I’m trying to upload a file to Storage using Microsoft.XMLHTTP in VBA for MS Access with progress tracking. Uploading without progress tracking works fine, but I need to have progress tracking, especially for larger files.
I have a problem with this line:
xmlHttp.send fileData
err: The parameter is incorrect… I tried to divide the file into 5 portions and upload them, but I am doing something wrong. Here is the snippet:
Public Sub UploadToAzureBlob(filePath As String, fileName As String)
Dim adoStream As Object
Dim xmlHttp As Object
Dim responseStatus As Long
Dim sUrl As String
Dim fileSize As Long
Dim bytesSent As Long
Dim chunkSize As Long
Dim fileData() As Byte
Dim progressForm As Form
Dim numParts As Long
'On Error GoTo ErrHandler
filePath = filePath & fileName
fileName = "/" & URLEncodeJScript(fileName) ' For Azure in this format
sUrl = blobUrl & fileName & sasToken
Set adoStream = CreateObject("ADODB.Stream")
adoStream.Mode = 3
adoStream.Type = 1
adoStream.Open
adoStream.LoadFromFile filePath
fileSize = adoStream.Size
numParts = 5
chunkSize = fileSize \ numParts
If chunkSize = 0 Then chunkSize = fileSize
DoCmd.OpenForm "dlgPRGBAR"
Set progressForm = Forms!dlgPRGBAR
Set xmlHttp = CreateObject("Microsoft.XMLHTTP")
bytesSent = 0
Do While bytesSent < fileSize
If bytesSent + chunkSize > fileSize Then
chunkSize = fileSize - bytesSent
End If
adoStream.Position = bytesSent
ReDim fileData(0 To chunkSize - 1)
fileData = adoStream.Read(chunkSize)
Debug.Print "Chunk size: " & chunkSize & " Bytes sent: " & bytesSent
xmlHttp.Open "PUT", sUrl, False
xmlHttp.setRequestHeader "x-ms-blob-type", "BlockBlob"
xmlHttp.setRequestHeader "Content-Length", CStr(chunkSize)
Debug.Print "URL: " & sUrl
Debug.Print "Content-Length: " & CStr(chunkSize)
xmlHttp.send fileData
If xmlHttp.status <> 201 And xmlHttp.status <> 202 Then
Debug.Print "Error: " & xmlHttp.status & " - " & xmlHttp.StatusText
MsgBox "Error: " & xmlHttp.status & " - " & xmlHttp.StatusText, vbCritical
GoTo CleanUp
End If
bytesSent = bytesSent + chunkSize
Dim IntValue As Long
IntValue = (bytesSent \ chunkSize)
If IntValue >= 5 Then
IntValue = 5
End If
Set prg = Forms!dlgPRGBAR!CtlProgress.Object
Set Complete = Forms!dlgPRGBAR!lblComplete
prg.Max = numParts
prg.Value = IntValue
strComplete = Format((prg.Value / prg.Max) * 100, "##") & " % Complete"
Complete.Caption = strComplete
DoCmd.RepaintObject
Loop
adoStream.Close
DoCmd.Close acForm, "dlgPRGBAR"
responseStatus = xmlHttp.status
If responseStatus = 201 Then
MsgBox "File uploaded successfully!", vbInformation
Else
MsgBox "Error: " & responseStatus & " - " & xmlHttp.StatusText, vbCritical
End If
CleanUp:
On Error Resume Next
If Not adoStream Is Nothing Then adoStream.Close
Set adoStream = Nothing
Set xmlHttp = Nothing
Exit Sub
ErrHandler:
MsgBox "An error occurred: " & err.Description, vbCritical
Resume CleanUp
End Sub