I am attempting to pull data from a Dropbox account with Excel VBA.
I removed the URL to make the generic script easier to follow:
Sub DownloadFile()
Dim myURL As String
myURL = "Some URL HEre"
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("Microsoft.XMLHTTP")
WinHttpReq.Open "GET", myURL, False, "username", "password"
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 "C:\Users\Eric\Downloads\Miami.txt", 2 ' 1 = no overwrite, 2 = overwrite
oStream.Close
End If
End Sub
My original URL is the Dropbox URL, which includes the text file in the sub directories (..../..../somefile.txt). I do not know what to do for the username and password options, and left those untouched when I originally ran the file.
When I did run the code, I had success, however I had a mass amount of HTML code pulled and not the text file downloaded.
Related
I'm trying to download a xlsx file from a password protected website to use in PBI.
On PBI I already tried to use Power Query and the Web Connector. I also tried using Power Automate (online version with HTTP connector, since my desktop version doesn't run on background).
And finally I'm using VBA. But all of them returns a file with the website HTML code, instead of the data which should be in the xlsx.
The code from the last try with VBA (which I found here is bellow (with a generic website URL)):
Sub DownloadFile()
Dim evalURL As String
Dim streamObject As Object
Dim winHttpRequest As Object
Set winHttpRequest = CreateObject("Microsoft.XMLHTTP")
evalURL = "https://generic_website.com/Excel_file.xslx" '
winHttpRequest.Open "GET", evalURL, False, "username", "password"
winHttpRequest.send
If winHttpRequest.Status = 200 Then
Set streamObject = CreateObject("ADODB.Stream")
streamObject.Open
streamObject.Type = 1
streamObject.Write winHttpRequest.responseBody
streamObject.SaveToFile "C:\Users\MyUser\Downloads\Excel_file.xslx", 2 ' 1 = no overwrite, 2 = overwrite
streamObject.Close
End If
End Sub
If I log into the website and open the URL directly in a browser, it downloads the .xlsx file.
Is there any way to do that? I have no idea what's happening, since the same code worked to other people.
UPDATE:
I tried the VBA code bellow, and get the results you can see in the image here.
Sub Login()
Dim response As String
With CreateObject("Microsoft.XMLHTTP")
.Open "GET", "https://generic_website.com/Excel_file.xslx", False, "username", "password"
.send
response = .responseText
End With
MsgBox response
End Sub
I do not know if this works as I cant login, and dont know the file. hopefully it can point you in the right direction.
' VBA Editor->Tools->References
' find and select the following
' Microsoft WinHTTP Services,version 5.1
' Microsoft HTML Object Library
Sub GetFile()
Dim URL As String: URL = "your url"
Dim File As String: File = "your url/file.xslx"
Dim Email As String: Email = "your#address.com"
Dim Password As String: Password = "Your Password"
Dim Cookie As String
Dim Token As String
Dim Message As String
Dim HTML As HTMLDocument: Set HTML = New HTMLDocument
Dim HTTP As WinHttpRequest: Set HTTP = New WinHttpRequest
' you potentially need the csrf_token to post the login form.
' so we get the token, and any cookies sent
HTTP.Open "GET", URL, True
HTTP.Send
HTTP.WaitForResponse
HTML.body.innerHTML = HTTP.ResponseText
Cookie = HTTP.GetResponseHeader("Set-Cookie")
Token = HTML.getElementsByName("csrf_token")(0).Value
Message = "csrf_token=" & Token & "&email=" & URLEncode(Email) & "&senha=" & URLEncode(Password)
HTTP.Open "POST", URL, True
HTTP.SetRequestHeader "Content-type", "application/x-www-form-urlencoded"
HTTP.SetRequestHeader "Cookie", Cookie
HTTP.Send Message
HTTP.WaitForResponse
Cookie = HTTP.GetResponseHeader("Set-Cookie")
' i dont have credentials so dont know what happens after this point and cannot test any further
HTTP.Open "GET", File, True
HTTP.SetRequestHeader "Cookie", Cookie
HTTP.Send
HTTP.WaitForResponse
msgbox HTTP.responseText
' if the runtime error still occurs then not sure what to do
' however,
' if the above message box looks like HTML, it didnt work.
' if it doesn't, it MIGHT have worked, you just need to
' figure out how to save the data to a file
'Dim FileNumber As Integer: FileNumber = FreeFile()
'Open "C:\destination.xslx" For Binary Access Write As #FileNumber
'Put #FileNumber, 1, HTTP.ResponseBody
'Close #FileNumber
End Sub
'https://stackoverflow.com/a/218199/212869
Public Function URLEncode(StringVal As String) As String
Dim StringLen As Long: StringLen = Len(StringVal)
If StringLen > 0 Then
ReDim result(StringLen) As String
Dim i As Long, CharCode As Integer
Dim Char As String
For i = 1 To StringLen
Char = Mid$(StringVal, i, 1)
CharCode = Asc(Char)
Select Case CharCode
Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
result(i) = Char
Case 32
result(i) = "+"
Case 0 To 15
result(i) = "%0" & Hex(CharCode)
Case Else
result(i) = "%" & Hex(CharCode)
End Select
Next i
URLEncode = Join(result, "")
End If
End Function
I want to change a URL to make it into the API compatible form.
If I have the string: "https://MYSERVER.com/browse/BIT-1234?jql=projectXXXXXX"
I want to change it into: "https://MYSERVER.com/rest/api/latest/search?jql=projectXXXXXX"
I use an InputBox to get the URL and I want to change it to that form and put it back into the script as shown below. How do I this?
Dim response As String
With CreateObject("Microsoft.XMLHTTP")
myURL= Application.InputBox("Enter the URL")
//CHANGE THE URL SOMEHOW
.Open "GET", myURL(changed URL goes here), False, **USERNAME**, **PASSWORD**
.send
response = .responseText
End With
Dim response As String, arr
myURL= Application.InputBox("Enter the URL")
arr = Split(myUrl, "?")
If ubound(arr) = 1 Then
With CreateObject("Microsoft.XMLHTTP")
myUrl = "https://MYSERVER.com/rest/api/latest/search?" & arr(1)
.Open "GET", myURL, False, **USERNAME**, **PASSWORD**
.send
response = .responseText
End With
Else
Msgbox "URL has no querystring!"
End If
I'm facing a problem when trying to open a file from a URL using ADODB, and then using that as a string stream. Basically, the issue I'm facing is almost a duplicate of this question here:
convert ADODB binary stream to string vba
Except that I have to use an ADODB Stream to work with the content later on. Therefore, skipping ADODB completely is not an option, like in the answer in the other topic.
Right now, what I'm doing is making a HTTP GET Request, using a binary stream to save it as a file, then loading that very same file using a text stream. This works just fine, but there has to be a way to skip the saving-loading part and make it work directly.
Here is the code I have so far:
Dim myURL As String
myURL = "https://xyz.xyz/xyz.csv"
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("Microsoft.XMLHTTP")
WinHttpReq.Open "GET", myURL, False
WinHttpReq.Send
Dim objStream, strData
Dim leftcellstarttemp As Variant, rightcellstarttemp As Variant, leftcellendtemp As Variant, rightcellendtemp As Variant, r As Long, line As String, dtStr As String, mlValue As String, dtArr() As String
myURL = WinHttpReq.ResponseBody
If WinHttpReq.Status = 200 Then
Set oStream = CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1
oStream.Write WinHttpReq.ResponseBody
oStream.SaveToFile "C:\Temp\file1.csv", 2
oStream.Close
Set objStream = CreateObject("ADODB.Stream")
objStream.Charset = "utf-8"
objStream.Type = 2
objStream.Open
objStream.LoadFromFile "C:\Temp\file1.csv"
line = objStream.ReadText(-2)
End If
Do Until objStream.EOS
(and so on, and so forth...)
Can you help me on how I can get past this needless file saving-loading process?
Thanks!
I have the url which contains a zipped csv file, I need to download only .csv from the zip , the Codes below is downloading zip
Sub DownloadFile()
Dim myURL As String
myURL = "https://www1.nseindia.com/content/historical/EQUITIES/2020/FEB/cm07FEB2020bhav.csv.zip"
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("Microsoft.XMLHTTP")
WinHttpReq.Open "GET", myURL, False, "username", "password"
WinHttpReq.send
If WinHttpReq.Status = 200 Then
Set oStream = CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1
oStream.Write WinHttpReq.responseBody
oStream.SaveToFile "C:\Users\playt\Desktop\STACK\ruff.zip", 2 ' 1 = no overwrite, 2 = overwrite
oStream.Close
End If
End Sub
You cannot download a file from an archive, but you can adapt your code in the next way:
Insert this lines at the end of your existing code (just before End Sub):
Dim zipFileName As String, unZipFolderName As String
zipFileName = "C:\Users\playt\Desktop\STACK\ruff.zip"
unZipFolderName = left(zipFileName, InStrRev(zipFileName, "\") - 1)
UN_Zip zipFileName, unZipFolderName
The simplest sub able to unzip and delete the archive must look like that (it needs a reference to 'Microsoft Shell Controls And Automation'):
Private Sub UN_Zip(zipFileName As String, unZipFolderName As String)
Dim wShApp As New Shell
wShApp.Namespace(unZipFolderName).CopyHere wShApp.Namespace(zipFileName).Items
Kill zipFileName
End Sub
If too lazy for adding the reference, to make the code look more elegant, the sub can be adapted with only two lines:
Use Dim wShApp As Object instead of Dim wShApp As New Shell declaration and then add the next line:
Set ShApp = CreateObject("Shell.Application")
In this way, no reference is necessary, anymore...
I need to have a vba macro that downloads data from my Podio app to an excel sheet. Right now I am running a code I found on Podio community website, which I am pasting below:
Dim winHttpReq As Object
Dim access_token As String
Function ProjectsFromPodio()
Dim result As String
Dim postData As String
Dim myURL As String
Dim token_pos As Long
'Initialisierung
Set winHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
myURL = "https://api.podio.com/oauth/token"
postData = "grant_type=app&app_id=ABC&app_token=DEF&client_id=GHI&client_secret=JKL"
If winHttpReq.Open("POST", myURL, False) = S_OK Then
'MsgBox ("Open successfull")
End If
winHttpReq.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
winHttpReq.Send (postData)
result = winHttpReq.responseText
token_pos = InStr(result, "access_token")
access_token = Mid(result, token_pos + 15)
token_pos = InStr(access_token, Chr(34)) - 1
access_token = Mid(access_token, 1, token_pos)
OAuthAppAuthorization = result
'MsgBox (OAuthAppAuthorization)
Set winHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
myURL = "https://api.podio.com/item/app/XYZ"
winHttpReq.Open "GET", myURL, False
winHttpReq.SetRequestHeader "Authorization", "OAuth2 " & access_token
winHttpReq.Send
result = winHttpReq.responseText
'MsgBox (result)
End Function
This works nice, data is downloaded and I can use it. My question is how to download this data in CSV format, rather than JSON? Is it possible?
If it is not possible, how can I parse it to a sheet in a smart way?
Thanks for any help
You may send the POST request to /item/app/{app_id}/export/{exporter}which creates a batch for exporting the items.
Here you can export the items as xls and xlsx formats.
Your myURL must be like,
myURL = "https://api.podio.com/item/app/XYZ/export/xls"
You will get a batch_id as a result of this request.
Then make a GET call to /batch/{batch_id} to get the status of the batch. You can download the output xls file by making a GET request to /file/{file_id} using the podio_file_id from the batch response.
References
Podio - Export Items
Podio - Get Batch
Podio - Get File