Codice VBA per Download non sempre funzionante

di il
9 risposte

Codice VBA per Download non sempre funzionante

Ciao a tutti,
ho trovato online una procedura vba per il download di file, nel mio caso serve per aggiornare i dati di magazzino :

-------------------------------------------------------------------------------------
DoCmd.SetWarnings False
'chiudo il pannello principale dell'applicativo
DoCmd.Close acForm, "pannello"
'se esiste il file dati lo elimino
If dir(Application.CurrentProject.Path & "\dati.accdb") = "" Then
Else
Kill (Application.CurrentProject.Path & "\dati.accdb")
End If

Dim myURL As String
myURL = "http://www.miaareaweb.it/Dati/dati.accd"
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("Microsoft.XMLHTTP")
WinHttpReq.Open "GET", myURL, False
WinHttpReq.Send
myURL = WinHttpReq.ResponseBody
If WinHttpReq.Status = 200 Then
Set oStream = CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1
oStream.Write WinHttpReq.ResponseBody
oStream.SaveToFile (Application.CurrentProject.Path & "\dati.accdb")
oStream.Close
End If
MsgBox "Aggiornamento dati completato!", vbInformation, "Aggiorna Dati"
-------------------------------------------------------------------------------------
il file dati.accdb (5mb circa) contiene oltre i dati di magazzino una tabella che contiene data/ora dell'aggiornamento fatto e che viene mostrata sulla maschera pannello una volta avviata

ha funzionato perfettamente per un pò e da un pò di giorni a questa parte, in alcuni casi, pare che non scarichi piu, nonostante il download sia diretto nella dir dell'applicativo
Il sintomo è che il download è istantaneo ed il file in effetti non viene scaricato, viene scaricato correttamente se effettuo ad esempio una pulizia delle cache dei browser con ccleaner o similari

Ci sono metodi più affidabili o suggerimenti per il codice già in essere?
avevo pensato a ritardare il codice dopo la prima parte dove avviene la cancellazione di dati.accdb ma non credo dipenda da li...
Grazie mille
Nico

9 Risposte

  • Re: Codice VBA per Download non sempre funzionante

    Se vuoi puoi provare usando le API:
    
    Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
    (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, _
    ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
    
    Sub Example()
        DownloadFile$ = "someFile.ext" 'here the name with extension
        URL$ = "http://some.web.address/" & DownloadFile 'Here is the web address
        LocalFilename$ = "C:\Some\Path" & DownloadFile !OR! CurrentProject.Path & "\" & DownloadFile 'here the drive and download directory
        MsgBox "Download Status : " & URLDownloadToFile(0, URL, LocalFilename, 0, 0) = 0
    End Sub
  • Re: Codice VBA per Download non sempre funzionante

    Ciao Alex,
    grazie per la risposta...
    dove va impostata la declare ptrsafe function? nel modulo dell'oggetto o in un nuovo modulo?
    ovunque la incollo viene indicata sempre in rosso...


    grazie
  • Re: Codice VBA per Download non sempre funzionante

    Allora, l'errore era dovuto al fatto che la stringa ptrsafe fa riferimento a sistemi 64bit se non ho capito male leggendo in rete....
    ora il file lo scarica ma non riesco a gestire la questione che mi visualizzi un messaggio a fine download....
  • Re: Codice VBA per Download non sempre funzionante

    Allora, riepilogo per chi fosse interessato:

    'funziona per app realizzate con access 32bit, per app realizzati con access 64bit bisogna sostituire con Private Declare PtrSafe Function URLDownloadToFile Lib

    Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
    (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, _
    ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long

    la sub corretta al click o altro evento è:

    Private Sub miopulsante()
    Dim DownloadFile As String
    Dim url As String
    Dim LocalFilename As String

    DownloadFile = "nomefile.ext" 'here the name with extension
    url = "http://miopercorsoweb.it" & DownloadFile 'Here is the web address
    LocalFilename = CurrentProject.Path & "\" & DownloadFile 'here the drive and download directory
    If URLDownloadToFile(0, url, LocalFilename, 0, 0) = 0 Then
    MsgBox "Terminato!"
    Else
    End If
    End Sub

    Ho testato e funziona, se ho scritto boiate avvisatemi che correggo

    Nico
  • Re: Codice VBA per Download non sempre funzionante

    Se vogliamo fare i precisi e rendere il codice adattabile al 32bit o 64bit potresti sfruttare la compilazione condizionale cosi:
    
    #If VBA7 And Win64 Then
        Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" _
          Alias "URLDownloadToFileA" ( _
            ByVal pCaller As LongPtr, _
            ByVal szURL As String, _
            ByVal szFileName As String, _
            ByVal dwReserved As LongPtr, _
            ByVal lpfnCB As LongPtr _
          ) As Long
    #Else
        Private Declare Function URLDownloadToFile Lib "urlmon" _
          Alias "URLDownloadToFileA" ( _
            ByVal pCaller As Long, _
            ByVal szURL As String, _
            ByVal szFileName As String, _
            ByVal dwReserved As Long, _
            ByVal lpfnCB As Long _
          ) As Long
    #End If
    
    Per il resto direi che va bene... io ho un Modulo basAPI generale in cui metto le dichiarazioni che possono essere invocate da qualsiasi posizione dell'applicativo, quindi le.ho dichiarate PUBLIC.

    Se vuoi testare l'esito del download devi testare il valore restituito dalla chiamata che deve essere 0 se OK
    
    result = URLDownloadToFile(0, ...
    If result<>0 THEN MSGBOX "errore..."
    
  • Re: Codice VBA per Download non sempre funzionante

    L'applicativo gira su runtime 2007, dici che conviene comunque passare via codice la possibilità che il sistema "capisca" su che piattaforma gira o posso lasciarlo così standard a 32bit?
    per quanto riguarda il valore assunto da result, in quali casi potrebbe essere diverso da zero? file non trovato, caduta connessione o cosa?

    Grazie come sempre per il prezioso aiuto

    Nico
  • Re: Codice VBA per Download non sempre funzionante

    Con il runtime 2007 la Costante VBA7 non è ancora stata implementata sicché la dovresti fare da codice cosa che rende inutile il codice... Quindi lascia quello che hai fatto.
    Quando effettuerai l'upgrade a versioni più recenti ed in particolare ACCDB ricordati di questa variante che io implementerei.

    Il valore sarà <>0 in caso fallisca, e questo può accadere per molte cause.
    Non sono a conoscenza se il valore restituito possa essere oggetto di diagnostica, ovvero non so se possa restituire valori differenti a seconda della differente causa... questo tuttavia puoi provarlo con qualche test, tipo nome file sbagliato o sollevando il cavo.di rete... tieni traccia del valore in relazione alla causa.
  • Re: Codice VBA per Download non sempre funzionante

    @Alex ha scritto:


    Con il runtime 2007 la Costante VBA7 non è ancora stata implementata sicché la dovresti fare da codice cosa che rende inutile il codice... Quindi lascia quello che hai fatto.
    Quando effettuerai l'upgrade a versioni più recenti ed in particolare ACCDB ricordati di questa variante che io implementerei.

    Il valore sarà <>0 in caso fallisca, e questo può accadere per molte cause.
    Non sono a conoscenza se il valore restituito possa essere oggetto di diagnostica, ovvero non so se possa restituire valori differenti a seconda della differente causa... questo tuttavia puoi provarlo con qualche test, tipo nome file sbagliato o sollevando il cavo.di rete... tieni traccia del valore in relazione alla causa.
    Ho trovato i Valori restituiti dalla chiamata API quì:
    
    This function can return one of these values.
    Return code			Description
    
    S_OK				The download started successfully.
    E_OUTOFMEMORY			The buffer length is invalid, or there is insufficient memory to complete the operation.
    INET_E_DOWNLOAD_FAILURE		The specified resource or callback interface was invalid.
    e quì trovi l'esplicitazione del Valore di sistema:
    https://docs.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values
    e quì:
    
    Name 		Description 								Value
    S_OK 		Operation successful 							0x00000000
    E_OUTOFMEMORY 	Failed to allocate necessary memory					0x8007000E
    
    INET_E_DOWNLOAD_FAILURE The download has failed (the connection was interrupted).	0x800C0008 
  • Re: Codice VBA per Download non sempre funzionante

    Aggiungo in ogni caso un Link ad un codice meglio strutturato per il DOWNLOAD SINCRONO usando il componente "WinHTTP Service":
    https://stagesolutions.wordpress.com/2012/04/18/asynchronous-download-from-http-with-vba/
Devi accedere o registrarti per scrivere nel forum
9 risposte