I am trying to load csv file and download it to my hard disk from a link of GitHub. Here's my try
#If Win64 Then
Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As LongLong, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As LongLong, ByVal lpfnCB As LongLong) As LongLong
#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
Function DownloadFile(Url As String, SavePathName As String) As Boolean
DownloadFile = URLDownloadToFile(0, Replace(Url, "\", "/"), SavePathName, 0, 0) = 0
End Function
Sub Demo()
Dim strUrl As String, strSavePath As String, strFile As String
strUrl = "https://github.com/pcm-dpc/COVID-19/blob/master/dati-regioni/dpc-covid19-ita-regioni-20200224.csv" 'SharePoint Path For The File
strSavePath = ThisWorkbook.Path & "\"
strFile = "FileName" & Format(Date, "dd.mm.yyyy") & ".csv"
If DownloadFile(strUrl, strSavePath & strFile) Then
MsgBox "File Saved To: " & vbNewLine & strSavePath
Else
MsgBox "Unable To Download File:" & vbNewLine & strFile & vbNewLine & "Check URL String And That Document Is Shared", vbCritical
End If
End Sub
I used the code before to download some files and it worked well but as for this link the downloaded file is as HTML page not csv file. How can I download it as CSV file?
Try hitting the raw content option on that page. The link you are hitting has HTML markup, the other is just the CSV content.
Option Explicit
Public Sub GetCSV()
Dim response As String
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-regioni/dpc-covid19-ita-regioni-20200224.csv", False
.Send
response = .responseText
End With
If Trim$(response) = "" Then Exit Sub
Open "YOURPATHHERE\SOMEFILE.csv" For Output As #1
Print #1, response
Close #1
End Sub
this is more simple.
cange website address.
Sub test()
Dim Whttp As WinHttp.WinHttpRequest
Dim strFile As String, str As String
Dim Url As String
Set Whttp = New WinHttp.WinHttpRequest
Url = "https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-regioni/dpc-covid19-ita-regioni-20200224.csv" 'SharePoint Path For The File
strSavePath = ThisWorkbook.Path & "\"
strFile = strSavePath & "FileName" & Format(Date, "dd.mm.yyyy") & ".csv"
With Whttp
.Open "Get", Url
.send
str = .responseText
End With
TransToCSV strFile, str
End Sub
Sub TransToCSV(myfile As String, strTxt As String)
Dim objStream As Object
Set objStream = CreateObject("ADODB.Stream")
With objStream
.Charset = "utf-8"
.Open
.WriteText strTxt
.SaveToFile myfile, 2
.Close
End With
Set objStream = Nothing
End Sub
Related
The hyperlink below appears in a cell in an Excel Sheet. It opens and displays a file if clicked on (permissions given to anyone with the link)
How can I download a linked file to a local folder using Excel vba?
URLDownloadToFile on Google Drive
The folder C:\Test has to exist for this example to work.
For more info on URLDownloadToFile try to search SO or Google.
The Code
Option Explicit
#If VBA7 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 LongPtr
#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
Function downloadFile( _
ByVal FileURL As String, _
ByVal FilePath As String) _
As Boolean
Const ProcName As String = "downloadFile"
On Error GoTo clearError
URLDownloadToFile 0, FileURL, FilePath, 0, 0
downloadFile = True
ProcExit:
Exit Function
clearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
Sub downloadGoogleDrive()
Const UrlLeft As String = "http://drive.google.com/u/0/uc?id="
Const UrlRight As String = "&export=download"
Const FileID As String = "17bw2KgzD1ifcA7rdXdxiN9bN70g8jnMO"
Const FilePath As String _
= "C:\Test\Type1 and Type 2 errors - Atyati Temp.jpg"
Dim Url As String: Url = UrlLeft & FileID & UrlRight
Dim wasDownloaded As Boolean
wasDownloaded = downloadFile(Url, FilePath)
If wasDownloaded Then
MsgBox "Success"
Else
MsgBox "Fail"
End If
End Sub
Download File from Google Drive with original file name
Sub DownloadGoogleDriveWithFilename()
Dim myOriginalURL As String
Dim myURL As String
Dim FileID As String
Dim xmlhttp As Object
Dim FolderPath As String
Dim FilePath As String
Dim name0 As Variant
Dim oStream As Object
Dim wasDownloaded As Boolean
Application.ScreenUpdating = False
''URL from share link or Google sheet URL or Google doc URL
myOriginalURL = "https://drive.google.com/file/d/1MnaC9-adPeEjkv7AEARchoYLLSWELBsy/view?usp=sharing"
FileID = Split(myOriginalURL, "/d/")(1) ''split after "/d/"
FileID = Split(FileID, "/")(0) ''split before "/"
Const UrlLeft As String = "http://drive.google.com/u/0/uc?id="
Const UrlRight As String = "&export=download"
myURL = UrlLeft & FileID & UrlRight
Debug.Print myURL
Set xmlhttp = CreateObject("winhttp.winhttprequest.5.1")
xmlhttp.Open "GET", myURL, False ', "username", "password"
xmlhttp.Send
name0 = xmlhttp.getResponseHeader("Content-Disposition")
If name0 = "" Then
MsgBox "file name not found"
Exit Sub
End If
Debug.Print name0
name0 = Split(name0, "=""")(1) ''split after "=""
name0 = Split(name0, """;")(0) ''split before "";"
' name0 = Replace(name0, """", "") ' Remove double quotes
Debug.Print name0
FolderPath = ThisWorkbook.path
FilePath = FolderPath & "\" & name0
''This part is equvualent to URLDownloadToFile(0, myURL, FolderPath & "\" & name0, 0, 0)
''just without having to write Windows API code for 32 bit and 64 bit.
If xmlhttp.Status = 200 Then
Set oStream = CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1
oStream.Write xmlhttp.responseBody
oStream.SaveToFile FilePath, 2 ' 1 = no overwrite, 2 = overwrite
oStream.Close
End If
Application.ScreenUpdating = True
If FileExists(FilePath) Then
wasDownloaded = True
''open folder path location to look at the downloded file
Call Shell("explorer.exe" & " " & FolderPath, vbNormalFocus)
Else
wasDownloaded = False
MsgBox "failed"
End If
End Sub
Function FileExists(FilePath As String) As Boolean
Dim TestStr As String
TestStr = ""
On Error Resume Next
TestStr = Dir(FilePath)
On Error GoTo 0
If TestStr = "" Then
FileExists = False
Else
FileExists = True
End If
End Function
I have code that loops through a list of hyperlinks in Excel and batch downloads these links as PDFs.
Sometimes they save to my desktop, documents, or another file path.
I would like them saved to a designated folder on my desktop named "PDFs."
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
Function DownloadFile(URL As String, LocalFilename As String) As Boolean
Dim lngRetVal As Long
lngRetVal = URLDownloadToFile(0, URL, LocalFilename, 0, 0)
If lngRetVal = 0 Then DownloadFile = True
End Function
Sub DownloadPDFs()
Dim StartRowNum As Long
Dim EndRowNum As Long
Dim pdfname As String
Dim RecordNum As String
Dim URLprefix As String
LastRowPDF = Sheet1.Cells(Rows.Count, "B").End(xlUp).Row
For i = 2 To LastRowPDF
Application.ScreenUpdating = False
URLprefix = Sheet1.Cells(i, 2)
RecordNum = Sheet1.Cells(i, 3)
pdfname = RecordNum & ".pdf"
URL = URLprefix
DownloadFile URLprefix, pdfname
Application.ScreenUpdating = True
Next i
End Sub
How do I save to a specific folder path?
This is the method I use and it works well, especially if you may need to use the file on multiple computers where the user profile may change, for example sending to others to execute the print operation or printing from another desktop. This method does not set a static path specific to your PC, but rather a path according to the PC it is being run on. A more flexible solution.
'Set Filename
pdfname = Environ("UserProfile") & "\Desktop\PDFs\" & RecordNum & ".pdf"
I need to download a CSV file from a website using VBA in Excel. The server also needed to authenticate me since it was data from a survey service.
I found a lot of examples using Internet Explorer controlled with VBA for this. However, it was mostly slow solutions and most were also convoluted.
Update:
After a while I found a nifty solution using Microsoft.XMLHTTP object in Excel. I thought to share the solution below for future reference.
This solution is based from this website:
http://social.msdn.microsoft.com/Forums/en-US/bd0ee306-7bb5-4ce4-8341-edd9475f84ad/excel-2007-use-vba-to-download-save-csv-from-url
It is slightly modified to overwrite existing file and to pass along login credentials.
Sub DownloadFile()
Dim myURL As String
myURL = "https://YourWebSite.com/?your_query_parameters"
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:\file.csv", 2 ' 1 = no overwrite, 2 = overwrite
oStream.Close
End If
End Sub
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
Source
I found the above when looking for downloading from FTP with username and address in URL. Users supply information and then make the calls.
This was helpful because our organization has Kaspersky AV which blocks active FTP.exe, but not web connections. We were unable to develop in house with ftp.exe and this was our solution. Hope this helps other looking for info!
A modified version of above to make it more dynamic.
Public Function DownloadFileB(ByVal URL As String, ByVal DownloadPath As String, ByRef Username As String, ByRef Password, Optional Overwrite As Boolean = True) As Boolean
On Error GoTo Failed
Dim WinHttpReq As Object: Set WinHttpReq = CreateObject("Microsoft.XMLHTTP")
WinHttpReq.Open "GET", URL, False, Username, Password
WinHttpReq.send
If WinHttpReq.Status = 200 Then
Dim oStream As Object: Set oStream = CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1
oStream.Write WinHttpReq.responseBody
oStream.SaveToFile DownloadPath, Abs(CInt(Overwrite)) + 1
oStream.Close
DownloadFileB = Len(Dir(DownloadPath)) > 0
Exit Function
End If
Failed:
DownloadFileB = False
End Function
I was struggling for hours on this until I figured out it can be done in one line of powershell:
invoke-webrequest -Uri "http://myserver/Reports/Pages/ReportViewer.aspx?%2fClients%2ftest&rs:Format=PDF&rs:ClearSession=true&CaseCode=12345678" -OutFile "C:\Temp\test.pdf" -UseDefaultCredentials
I looked into doing it purely in VBA but it runs to several pages, so I just call my powershell script from VBA every time I want to download a file.
Simple.
Public Sub Test_DownloadFile()
Dim URLStr As String, DLPath As String, UName As String, PWD As String, DontOverWrite As Boolean
URLStr = "http.."
DLPath = Environ("USERPROFILE") & "\Downloads\TEST.PDF"
UName = ""
PWD = ""
DontOverWrite = False
Call DownloadFile(URLStr, DLPath, UName, PWD, DontOverWrite)
End Sub
Public Sub DownloadFile(ByVal URLStr As String, ByVal DLPath As String, Optional ByVal UName As String, Optional ByVal PWD As String, Optional DontOverWrite As Boolean)
On Error GoTo Failed
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("Microsoft.XMLHTTP")
WinHttpReq.Open "GET", URLStr, False, UName, PWD
WinHttpReq.send
If WinHttpReq.status = 200 Then
Set oStream = CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1
oStream.Write WinHttpReq.responseBody
Dim OWrite As Integer
If DontOverWrite = True Then
OWrite = 1
Else
OWrite = 2
End If
oStream.SaveToFile DLPath, OWrite
oStream.Close
Debug.Print "Downloaded " & URLStr & " To " & DLPath
Exit Sub
End If
Failed:
Debug.Print "Failed to DL " & URLStr
End Sub
A modified version of above solution to make it more dynamic.
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
Public Function DownloadFileA(ByVal URL As String, ByVal DownloadPath As String) As Boolean
On Error GoTo Failed
DownloadFileA = False
'As directory must exist, this is a check
If CreateObject("Scripting.FileSystemObject").FolderExists(CreateObject("Scripting.FileSystemObject").GetParentFolderName(DownloadPath)) = False Then Exit Function
Dim returnValue As Long
returnValue = URLDownloadToFile(0, URL, DownloadPath, 0, 0)
'If return value is 0 and the file exist, then it is considered as downloaded correctly
DownloadFileA = (returnValue = 0) And (Len(Dir(DownloadPath)) > 0)
Exit Function
Failed:
End Function
How do I pull the default name of a PDF from a website instead of blah.pdf in following code?
Option Explicit
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
Sub z()
Dim strSource As String
Dim strDest As String
strSource = "http://www.cran.r-project.org/doc/manuals/R-intro.pdf"
strDest = "c:\temp\blah.pdf"
URLDownloadToFile 0, strSource, strDest, 0, 0
End Sub
Using your original method of downloading the file is fine, but how are you actually determining the path and filename? Do you have a list? Do you need to get it from the website? With regards to retrieving the instrument number, first set references (VBE > Tools > References) to Microsoft XML, vx.0 and Microsoft HTML Object Library, then change the specified URL accordingly, and then try...
Option Explicit
Sub GetInstrumentNumber()
'Set a reference (VBE > Tools > References) to the following libraries:
' 1) Microsoft XML, v6.0 (or whatever version you have)
' 2) Microsoft HTML Object Library
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim sURL As String
Dim sInstrument As String
sURL = "http://www.cran.r-project.org/..." 'change the URL adddress accordingly
With XMLReq
.Open "GET", sURL, False
.send
Do While .readyState <> 4
DoEvents
Loop
End With
If XMLReq.Status <> 200 Then
MsgBox "Error " & XMLReq.Status & ": " & XMLReq.statusText
Exit Sub
End If
HTMLDoc.body.innerHTML = XMLReq.responseText
sInstrument = HTMLDoc.getElementById("6063270").getElementsByTagName("tr")(0).Cells(0).innerText
sInstrument = Trim(Split(sInstrument, ":")(1))
MsgBox "Instrument number: " & sInstrument, vbInformation
Set XMLReq = Nothing
Set HTMLDoc = Nothing
End Sub
I am trying to download a file with save as through the frame notification bar of internet explorer.
However after doing a lot of searches, I have only found solutions to click save on the frame notification bar.
So far I have been trying to save as the file on the sample site:
http://www.tvsubtitles.net/subtitle-114117.html
with the following code:
' Add referenses
' Microsoft Internet Controls
' Microsoft HTML Object Library
' UIAutomationClient (copy file from C:\Windows\System32\UIAutomationCore.dll to Documents Folder)
#If VBA7 Then
Private Declare PtrSafe Function FindWindowEx _
Lib "user32" _
Alias "FindWindowExA" ( _
ByVal hWnd1 As LongPtr, _
ByVal hWnd2 As LongPtr, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) _
As LongPtr
#Else
Private Declare Function FindWindowEx _
Lib "user32" _
Alias "FindWindowExA" ( _
ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) _
As Long
#End If
Sub downloadfilefromeie()
Dim subpage As InternetExplorer
Dim objpage As HTMLDocument
Dim o As CUIAutomation
Dim h As LongPtr
Dim fnb As LongPtr
Dim e As IUIAutomationElement
Dim iCnd As IUIAutomationCondition
Dim Button As IUIAutomationElement
Dim InvokePattern As IUIAutomationInvokePattern
Dim strBuff As String
Dim ButCap As String
Set objshell = CreateObject("Shell.Application")
Set objallwindows = objshell.Windows
Set subpage = New InternetExplorer
For Each ow In objallwindows
'MsgBox ow
If (InStr(1, ow, "Internet Explorer", vbTextCompare)) Then
'MsgBox ow.Hwnd & " " & ow & " " & ow.locationURL
If (InStr(1, ow.locationURL, "tvsub", vbTextCompare)) Then
Set subpage = ow
End If
End If
Next
Set objpage = New HTMLDocument
If subpage Is Nothing Then
Else
Set objpage = subpage.Document
'Debug.Print objpage
'objpage.getElementById("content").Click
Set dl = objpage.getElementsbyclassname("subtable")
Set dltable = dl(0).FirstChild.ChildNodes
Set dlrow = dltable(10).getElementsByTagName("a")(2)
dlrow.Click
While objpage.ReadyState <> "complete"
DoEvents
Wend
End If
Application.Wait (Now() + TimeValue("0:00:05"))
Set o = New CUIAutomation
h = subpage.Hwnd
fnb = FindWindowEx(h, 0, "Frame Notification Bar", vbNullString)
If fnb = 0 Then Exit Sub
'Debug.Print "type of fnb is " & TypeName(fnb)
Set e = o.ElementFromHandle(ByVal fnb)
'Debug.Print "type of e is " & TypeName(e)
Set iCnd = o.CreatePropertyCondition(UIA_NamePropertyId, "Save")
Set Button = e.FindFirst(TreeScope_Subtree, iCnd)
'Debug.Print "type of Button is " & TypeName(Button)
Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId)
'Debug.Print "type of InvokePattern is " & TypeName(InvokePattern)
InvokePattern.Invoke
End Sub
I have tried changing "Save" to "Save as" but it doesn't work. My guess is that I need to somehow be able to click on the arrow on the split button first before accessing to the save as button but I have had no success in doing it.
Gladly appreciate it if someone can offer a solution.
I tried simply to download a file by the link http://www.tvsubtitles.net/download-114117.html, which can be found on the webpage http://www.tvsubtitles.net/subtitle-114117.html, and it worked for me, here is the code:
Sub Test_download_tvsubtitles_net()
DownloadFile "http://www.tvsubtitles.net/download-114117.html", ThisWorkbook.Path & "\download-114117.zip"
End Sub
Sub DownloadFile(sUrl, sPath)
Dim aBody
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", sUrl, False
.Send
aBody = .responseBody
End With
With CreateObject("ADODB.Stream")
.Type = 1 ' adTypeBinary
.Open
.Write aBody
.SaveToFile sPath, 2 ' adSaveCreateOverWrite
.Close
End With
End Sub