Subir archivos por vba a la nube con dropbox
Impreso de: Foro de Access y VBA
Categoría: Access y VBA
Nombre del foro: Access y VBA
Descripción del foro: Foro de programacion en Access (Con código y sin código)
URL: http://www.mvp-access.com/foro/forum_posts.asp?TID=84478
Fecha de impresión: 22/Abril/2021 a las 13:41
Tema: Subir archivos por vba a la nube con dropbox
Publicado por: rokoko
Asunto: Subir archivos por vba a la nube con dropbox
Fecha de publicación: 04/Mayo/2019 a las 13:57
Buenas!!
Hace un tiempo abri un hilo sobre este tema pero no llegue a ningun lado, parece que no habia gente que utilizase este metodo, cosa que me parece muy practica y segura, subir archivos a dropbox sin tenerlo instalado en el pc.
El objetivo seria este, subir archivos(copias seguridad de tablas) a dropbox silenciosamente al cerrar la aplicacion. Pongo dropbox porque es del que he encontrado informacion, pero podria ser drive o mega.....
El escenario es este, de hay que quiera hacerlo asi en parte. Son ordenadores que estan capados, no se les puede instalar nada. Todos los usuarios tienen su cuenta en el dominio, aunque se pudiese instalar dropbox(que no se puede) habria que crear la cuenta dropbox en todos los usuarios......
He encontrado esta info con APIs de dropbox. Parece que si se puede hacer lo que quiero.
https://veroniquefrizzell.com/using-vba-with-dropbox-api/
https://www.dropbox.com/developers-v1/core/docs#files_put
https://www.dropbox.com/developers
En el primer enlace hay un ejemplo de VBA pero que no llego a comprender bien o esta poco desarrolado....
A ver si alguien le saca jugo a esto, que creo es bien practico..
Saludos
|
Respuestas:
Publicado por: guarracuco
Fecha de publicación: 06/Mayo/2019 a las 14:51
El primer enlace utiliza el recurso para listar los usuarios que tienen acceso a las carpetas compartidas.
En esa misma lista de recursos o endpoints, ubica alguna que haga referencia a put o upload files. Hay
dos maneras de conectarse con las APIs: conexion directa o utilizando
aplicaciones de terceros o OAuth2 que es un tanto complicado. El ejemplo muestra la directa: token.
OAuth2:
Aplicaciones
de terceros es cuando un desarrollador crea una aplicacion para que
cualquier otro usuario del mismo servicio pueda utilizarlo. Es decir, tu
aplicacion es un intermediario entre el usuario y el servicio (Dropbox,
Square, Mailchimp y un largo etc). Cuando un usuario lo va a utilizar,
es direccionado a la pagina oficial (como lo viene haciendo desde hace
mas de una decada Paypal) para conectarse y autorizar que esa aplicacion
tendra acceso a ciertas secciones de tu cuenta. Si el acceso
es permitido, se genera un token temporal con el cual el usuario hace
peticiones al servicio: dame esta lista, actualiza este registro, etc. No
lo probe pero no hay duda de que desde VBA lo puedes hacer. Yo vengo
haciendolo con Square y otros metodos de pago, MailChimp, WordPress,
Twilio.
Actualiza los siguientes valores: 1) myurl = UBICA EL ENDPOINT PARA ENVIAR ARCHIVOS 2) argumentString 3) your-access-token
y por supuesto, primero crea tu aplicacion en tu cuenta de DropBox.
|
Publicado por: rokoko
Fecha de publicación: 07/Mayo/2019 a las 17:38
Algun pequeño avance he hecho, o eso creo. He encontrado este codigo en esta pagina https://www.dropboxforum.com/t5/Discuss-Developer-API/How-can-i-upload-file-to-my-Dropbox-account-with-vba/m-p/306546" rel="nofollow - https://www.dropboxforum.com/t5/Discuss-Developer-API/How-can-i-upload-file-to-my-Dropbox-account-with-vba/m-p/306546
Llamo a la funcio asi Dim varArchivo As String varArchivo = "Z:\Copia\Acces copia seguridad nube\Koala.jpg" DB_PutFile varArchivo
Public Sub DB_PutFile(FileName As String)
Dim varToken As String varToken = "EL TOKEN PROPORCIONADO POR DROPBOX en su aplicacion"
Dim req As MSXML2.ServerXMLHTTP60 Dim strFile As String Dim Pos1 As Integer Dim Pos2 As Integer Set req = New MSXML2.ServerXMLHTTP60 Dim arg As String strFile = ReadBinary(FileName) arg = "{""path"":""/" & FileName & """,""mode"":{"".tag"":""overwrite""},""autorename"":false,""mute"":true}" req.Open "POST", "https://content.dropboxapi.com/2/files/upload", False req.setRequestHeader "Authorization", varToken 'Hay que poner el token de la aplicacion de dropbox en la variable req.setRequestHeader "Content-Type", "application/octet-stream" req.setRequestHeader "Content-length", Len(Result) req.setRequestHeader "Dropbox-API-Arg", arg req.setRequestHeader "User-Agent", "api-explorer-client" req.send strFile
If req.Status = 200 Then MsgBox req.responseText Else MsgBox req.Status & ": " & req.statusText End If
End Sub
Al principio me daba un error, que parecia de referencias, al final he dado con la que es, Microsoft XML, v6.0 en access 2013.
El error que me suelta ahora es no se a definido sub o function en la linea en rojo ReadBinary, no tengo claro que es ReadBinary???............He quitado el ReadBinary poniendolo asi strFile = FileName y ahora me suelta un error ya como de conexion con dropbox
Standard API errorsCode | Description |
---|
400 | Bad input parameter. Error message should indicate which one and why.
|
Aqui mas info sobre la API https://www.dropbox.com/developers-v1/core/docs" rel="nofollow - https://www.dropbox.com/developers-v1/core/docs https://www.dropbox.com/developers-v1/core/docs#files_put" rel="nofollow - https://www.dropbox.com/developers-v1/core/docs#files_put https://www.dropbox.com/developers/documentation/http/documentation#files-upload" rel="nofollow - https://www.dropbox.com/developers/documentation/http/documentation#files-upload
Edito: Ahora veo que puede ser ReadBinary, una funcion que no se cual es para asar el directorio del archivo a Binario?????
La funcion no esta en la pagina web de donde he sacado el codigo
|
Publicado por: pitxiku
Fecha de publicación: 07/Mayo/2019 a las 18:27
ReadBinary puede ser una función personalizada para leer el archivo en binario. Puedes probar con la instrucción Open o con el objeto Stream de ADO:
- https://stackoverflow.com/questions/660312/how-can-i-read-a-binary-file-using-vba - https://docs.microsoft.com/es-es/office/vba/language/reference/user-interface-help/open-statement - https://www.w3schools.com/asp/ado_ref_stream.asp
Por otro lado, una duda: si estás en un dominio, ¿el departamento de IT no hace copias de seguridad del servidor?
|
Publicado por: rokoko
Fecha de publicación: 07/Mayo/2019 a las 18:42
pitxiku escribió:
Por otro lado, una duda: si estás en un dominio, ¿el departamento de IT no hace copias de seguridad del servidor? |
Si, si que hacen. Pero suele ser un horror de gestion para que te den el archivo. Mi idea era ir haciendo copias poniendo la fecha en el nombre del archivo para tener una serie de copias. Yo me imagino que los de IT iran pisando la copia que se haga..... y por otro lado tengo ganas de hacerlo funcionar para alguna otra aplicacion y curiosidad...
He encontrado este codigo que creo que lo pasa a binaryo, es correcto???
Function FileReadBinary(sFileName As String) As Variant Dim iFileNum As Integer, lFileLen As Long Dim vThisBlock As Variant, lThisBlock As Long, vFileData As Variant On Error GoTo ErrFailed If Len(Dir$(sFileName)) > 0 And Len(sFileName) > 0 Then iFileNum = FreeFile Open sFileName For Binary Access Read As #iFileNum lFileLen = LOF(iFileNum) Do lThisBlock = lThisBlock + 1 Get #iFileNum, , vThisBlock If IsEmpty(vThisBlock) = False Then If lThisBlock = 1 Then ReDim vFileData(1 To 1) Else ReDim Preserve vFileData(1 To lThisBlock) End If vFileData(lThisBlock) = vThisBlock End If Loop While EOF(iFileNum) = False Close iFileNum FileReadBinary = vFileData End If
Exit Function ErrFailed: Close iFileNum Debug.Print Err.Description
Lo he probado(sin saber que lo hace bien) y ahora solo me suelta el error 400 de dropbox........
|
Publicado por: pitxiku
Fecha de publicación: 07/Mayo/2019 a las 18:52
Revisa la cadena de argumentos, a ver si tienes algo raro. Por ejemplo, yo veo:
- ""path"":""/" & FileName & """: Estás usando la ruta y nombre del archivo en tu disco local, pero en la ayuda del API indican que ahí debe ir la ruta y nombre en Dropbox. Además, ellos usan la barra normal (/) para separar las carpetas, y en Windows se usa la invertida (\).
- ""mode"": No indicas un valor para este parámetro, aunque en la ayuda indican que hay un valor por defecto. Tal vez no sea necesario indicarlo, pero por si acaso...
- {"".tag"":""overwrite""}: encierras este parámetro entre llaves, y todo el conjunto entre otras llaves. En la ayuda del API sólo está la llave "principal".
|
Publicado por: rokoko
Fecha de publicación: 07/Mayo/2019 a las 19:58
Tiene su miga esto, no hay forma . Me sigue soltando el error 400 de dropbox. He probado todo lo que me as dicho. Lo que si es claro que tenia mal era path, estaba utilizando el del disco local.Ahora de momento lo tengo asi
para llamarla si Dim varArchivo As String varArchivo = "Z:\Acces copia seguridad nube\Koala.jpg" DB_PutFile varArchivo
Public Sub DB_PutFile(FileName As String)
Dim varToken As String varToken = "xxxxxxxxxxxxxxxxxxxxxxxxxx"
Dim varDirectorioDropbox As String varDirectorioDropbox = "Aplicaciones/CopiaAccess/Koala.jpg"
Dim req As MSXML2.ServerXMLHTTP60 Dim strFile As String Dim Pos1 As Integer Dim Pos2 As Integer Set req = New MSXML2.ServerXMLHTTP60 Dim arg As String strFile = FileReadBinary(FileName) 'MsgBox strFile arg = "{""path"":""/" & varDirectorioDropbox & """,""mode"":add,{"".tag"":""overwrite""},""autorename"":false,""mute"":true}" req.Open "POST", "https://content.dropboxapi.com/2/files/upload", False req.setRequestHeader "Authorization", varToken 'Hay que poner el token de la aplicacion de dropbox en la variable req.setRequestHeader "Content-Type", "application/octet-stream" req.setRequestHeader "Content-length", Len(Result) req.setRequestHeader "Dropbox-API-Arg", arg req.setRequestHeader "User-Agent", "api-explorer-client" req.send strFile
If req.Status = 200 Then
'Debug.Print req.responseText MsgBox req.responseText Else MsgBox req.Status & ": " & req.statusText 'Debug.Print req.responseText 'MsgBox req.responseText End If
|
Publicado por: guarracuco
Fecha de publicación: 07/Mayo/2019 a las 21:57
Tienes un detalle que corregir en una de las lineas del Header: req.setRequestHeader "Authorization", "Bearer " & varToken
Aunque la respuesta 400 no es la adecuada para este error, debes corregir este primero. Estas a 2 toques de lograrlo.
|
Publicado por: rokoko
Fecha de publicación: 07/Mayo/2019 a las 22:23
Asi esta con la correccion de guarruco, pero efectivamente sigue el error 400 bad request
A que puede deberse ese error????
Public Sub DB_PutFile(FileName As String)
Dim varToken As String varToken = "xxxxxxxxxxxxxxxxxxxxxx"
Dim varDirectorioDropbox As String varDirectorioDropbox = "Aplicaciones/CopiaAccess/Koala.jpg"
Dim req As MSXML2.ServerXMLHTTP60 Dim strFile As String Dim Pos1 As Integer Dim Pos2 As Integer Set req = New MSXML2.ServerXMLHTTP60 Dim arg As String strFile = FileReadBinary(FileName) 'strFile = FileName MsgBox strFile arg = "{""path"":""/" & varDirectorioDropbox & """,""mode"":add,{"".tag"":""overwrite""},""autorename"":false,""mute"":true}" req.Open "POST", "https://content.dropboxapi.com/2/files/upload", False req.setRequestHeader "Authorization", "Bearer " & varToken 'Hay que poner el token de la aplicacion de dropbox en la variable req.setRequestHeader "Content-Type", "application/octet-stream" req.setRequestHeader "Content-length", Len(Result) req.setRequestHeader "Dropbox-API-Arg", arg req.setRequestHeader "User-Agent", "api-explorer-client" req.send strFile
If req.Status = 200 Then MsgBox req.responseText Else MsgBox req.Status & ": " & req.statusText End If End Sub
|
Publicado por: guarracuco
Fecha de publicación: 07/Mayo/2019 a las 22:29
Busca en el panel de control de Dropbox credenciales de prueba (Sandbox Credentials) y me las envias por privado. Ignoro si esa API tiene credenciales de prueba.
Imprime la respuesta del servidor y publicalo para ver el mensaje que devuelve la API.
|
Publicado por: rokoko
Fecha de publicación: 07/Mayo/2019 a las 22:51
guarracuco escribió:
Busca en el panel de control de Dropbox credenciales de prueba (Sandbox Credentials) y me las envias por privado. Ignoro si esa API tiene credenciales de prueba.
Imprime la respuesta del servidor y publicalo para ver el mensaje que devuelve la API.
|
A ver, lo de las credenciales de prueba no lo veo por ningun lado(uso version gratuita de dropbox) no se si sera por esto.... y en la ventana inmediato me sale esto
La variable utiliza un tipo de Automatización no admitido en Visual Basic Error in call to API function "files/upload": HTTP header "Dropbox-API-Arg": could not decode input as JSON
Muchas gracias
|
Publicado por: guarracuco
Fecha de publicación: 07/Mayo/2019 a las 23:55
Option Compare Database Dim access_token As String Dim req As Object Dim vardir As String Dim varfile As String
Private Sub Command0_Click() Dim arg As String result = FRB(vardir) varfile = "\/TU_DIRECTORIO_EN_DRPBOX\/NOMBRE_Y_EXTENSION_FINAL_DEL_ARCHIVO_EN_DROPBOX" arg = "{""path"":""" & varfile & """,""mode"":""add"",""autorename"":false,""mute"":true}" Set req = CreateObject("WINHTTP.WinHTTPRequest.5.1") req.Open "POST", "https://content.dropboxapi.com/2/files/upload", False req.setRequestHeader "Authorization", "Bearer " & access_token 'Hay que poner el token de la aplicacion de dropbox en la variable req.setRequestHeader "Content-Type", "application/octet-stream"
req.setRequestHeader "Dropbox-API-Arg", arg req.setRequestHeader "User-Agent", "api-explorer-client" req.send (result) If req.status = 200 Then Debug.Print req.responseText Else Debug.Print req.responseText End If End Sub
Private Sub Form_Load() access_token = "TU-TOKEN"
'ruta del archivo a enviar. Debes enmascarar las barras inclinadas para que sea formato JSON valido vardir = "C:\\Users\\Carlos\\Documents\\MisOcx\\alter.txt" End Sub
Function FRB(ByVal sRuta As String) As Byte() Dim b() As Byte Open sRuta For Binary As #1 ReDim b(FileLen(sRuta) - 1) '''''****ESTE -1 ES LA SOLUCIÓN PARA QUE NO CORROMPA LOS ARCHIVOS******RESTARLE UN BYTE Get #1, , b Close #1 FRB = b
End Function
Reemplaza tu token, nombre de carpeta remota y ruta del archivo a subir.
|
Publicado por: rokoko
Fecha de publicación: 08/Mayo/2019 a las 00:26
guarracuco escribió:
Option Compare Database Dim access_token As String Dim req As Object Dim vardir As String |
Madre mia, que arte teneis algunos en este mundillo. Yo creo que ni metiendo todas las horas del mundo lo hago funcionar...complicado esto de las apis......
Mañana lo miro mas despacio y pregunto alguna duda..
Muchas muchas gracias
Saludos
|
Publicado por: guarracuco
Fecha de publicación: 08/Mayo/2019 a las 00:42
Un placer. Hay que realizar un ajuste en la ruta/nombre remoto, de lo contrario, crea dentro del directorio, uno nuevo.
varfile = "\/NOMBRE_Y_EXTENSION_FINAL_DEL_ARCHIVO_EN_DROPBOX" La diferencia es remover el nomre del directorio, ya que el token esta asociado al mismo. Recuerda enmascarar las barras inclinadas.
y para sobreescribir: arg = "{""path"":""" & varfile & """,""mode"":""overwrite"",""autorename"":false,""mute"":true}"
Ayudando se aprende. Esta API es nueva para mi. Todas son muy parecidas.
|
Publicado por: rokoko
Fecha de publicación: 08/Mayo/2019 a las 16:58
Hola
Alguna duda me queda.. Este parametro que es, algun tiempo de respuesta?? If req.status = 200 Then
Y por otro lado y probando pensando que no funcionaria, he creado un cuadro de dialogo para selecionar un archivo a subir y logicamente la ruta que crea es con una sola barra y no la doble barra para JSON, pero el archivo sube bien!!! Funciona con barra simple y doble(JSON).
|
Publicado por: emiliove
Fecha de publicación: 08/Mayo/2019 a las 17:14
Hola Rokoko
El 200 es que la petición que estas haciendo fue correcta, y te va a devolver la respuesta.
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms767625%28v%3Dvs.85%29" rel="nofollow - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms767625(v%3Dvs.85)
Saludos.
|
Publicado por: rokoko
Fecha de publicación: 08/Mayo/2019 a las 21:19
Hola
Probando con algunos archivos de uno 25mb me a dado el error en esta linea req.send (result)
-Se supero el tiempo de espera para esta operacion error -21470122894(80072ee2)
Se puede solucionar esto, modificar el limite de tiempo o alguna otra solucion??
Saludos
|
Publicado por: pitxiku
Fecha de publicación: 09/Mayo/2019 a las 19:27
Puede que en vez de usar el método upload, tengas que usar una sesión para subir archivos grandes:
- https://www.dropbox.com/developers/documentation/http/documentation#files-upload_session-start
|
Publicado por: rokoko
Fecha de publicación: 09/Mayo/2019 a las 20:05
pitxiku escribió:
Puede que en vez de usar el método upload, tengas que usar una sesión para subir archivos grandes:
- https://www.dropbox.com/developers/documentation/http/documentation#files-upload_session-start |
Justo ahora estaba probando y he conseguido subir un archivo de 144mbm en principio mas que suficiente para lo que quiero. He puesto esta linea.
Set req = CreateObject("WINHTTP.WinHTTPRequest.5.1") req.SetTimeouts 30000, 1000000, 1000000, 1000000 req.Open "POST", "https://content.dropboxapi.com/2/files/upload", False
ResolveTimeout,ConnectTimeout,SendTimeout,ReceiveTimeout
Son tiempos en milisegundos, lo que no he encontrado es que limites se pueden poner.. Y esa linea tiene que ir antes de Open
|
Publicado por: pitxiku
Fecha de publicación: 09/Mayo/2019 a las 22:43
Entiendo que los tiempos que has puesto son más que suficientes (son casi 3 horas).
Menos el tiempo del envío del archivo(send), para los demás con un par de segundos debe sobrar.
Si el archivo no pasa de 150 mb no pasa nada. Pero si pasa, entiendo que sí debes usar una sesión.
|
Publicado por: guarracuco
Fecha de publicación: 10/Mayo/2019 a las 01:24
Quizas sea suficiente el cambiar el parametro false por true. Esto indica que la solicitud se haga en modo asincrono de manera que no se detiene la ejecucion de codigo vba. Podrias colocar un reloj indicando que el proceso se esta ejecutando.
Hay un evento que te indica que el proceso finalizo. Utilizalo para detener el reloj.
|
Publicado por: rokoko
Fecha de publicación: 10/Mayo/2019 a las 08:13
guarracuco escribió:
Quizas sea suficiente el cambiar el parametro false por true. Esto indica que la solicitud se haga en modo asincrono de manera que no se detiene la ejecucion de codigo vba. Podrias colocar un reloj indicando que el proceso se esta ejecutando.
Hay un evento que te indica que el proceso finalizo. Utilizalo para detener el reloj.
|
He cambiado el parametro false a true en esta linea req.Open "POST", "https://content.dropboxapi.com/2/files/upload", True pero me suelta el error "El dato necesario para completar esta operacion no esta disponible ahora"
pitxiku escribió:
Entiendo que los tiempos que has puesto son más que suficientes (son casi 3 horas).
Menos el tiempo del envío del archivo(send), para los demás con un par de segundos debe sobrar.
Si el archivo no pasa de 150 mb no pasa nada. Pero si pasa, entiendo que sí debes usar una sesión. |
Pues si no pongo en todos parametro (3 ultimos) un tiempo generoso me dice que se ha agotado el tiempo.
Mañana lo probare ya en realidad en el trabajo, y ya os contare. Deberia de ir bien, ademas los archivos a subir no son muy grandes, mas bien pequeños
Saludos
|
Publicado por: guarracuco
Fecha de publicación: 10/Mayo/2019 a las 14:36
CUando se utiliza en modo asincrono, hay que agregar luego de la linea send: obj.waitForResponse
|
Publicado por: rokoko
Fecha de publicación: 12/Mayo/2019 a las 10:32
Hola
Lo he probado en el trabajo en 3 bases de datos y funciona perfectamente, la verdad que es una gozada hacer copias de seguridad asi. O para subir a Dropbox lo que quieras. Con este codigo estas limitado en teoria a 150 mb, pero modificandolo se podria subir archivos mas grandes.
Como resumen
https://www.dropbox.com/developers-v1/core/docs
https://www.dropbox.com/developers
https://dropbox.github.io/dropbox-api-v2-explorer/#files_upload
https://www.dropbox.com/developers/documentation/http/documentation
http://www.jose.it-berater.org/winhttp/settimeouts_method.htm
Y un ejemplo con varias opciones https://www.dropbox.com/s/dda5vkcbw2hal2m/ArchivosNube.rar?dl=0
Son 3 parametros los que hay que pasar, el token de dropbox, la ruta dropbox con archivo y extension, y ruta del archivo a subir con archivo y extension.
Se puede cerra, muchas gracias a todos.
|
Publicado por: rokoko
Fecha de publicación: 18/Mayo/2019 a las 17:47
Cerrar el hilo por favor
Saludos
|
|