Хитрости »
2 Декабрь 2016 40454 просмотров
Как скачать файл из интернета по ссылке
Вся суть статьи уже в заголовке. Возникает порой необходимость скачивания файлов из интернета только на основании ссылки. Например, это какие-то постоянно меняющиеся данные или автоматически генерируемая другим кодом ссылка. Или еще более усугубленный вариант — строк 100 со ссылками на файлы, которые надо скачать…Вот уж радости руками по каждой клацать
Поэтому выкладываю решение, которое в большинстве случае поможет при помощи Visual Basic for Applications скачать файл на основании ссылки URL:
'--------------------------------------------------------------------------------------- ' File : mDownloadFileFromURL ' Purpose: код позволяет скачивать файлы из интернета по указанной ссылке '--------------------------------------------------------------------------------------- Option Explicit 'объявление функции API - URLDownloadToFile ' работает на любых ПК под управлением ОС Windows ' на MAC код работать не будет #If Win64 Then 'для операционных систем с 64-разрядной архитектурой 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 #If VBA7 Then 'для любых операционных систем с офисом 2010 и выше Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _ (ByVal pCaller As LongPtr, ByVal szURL As String, ByVal szFileName As String, _ ByVal dwReserved As Long, ByVal lpfnCB As LongPtr) As LongPtr #Else 'для 32-разрядных операционных систем 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 #End If 'переменная для хранения пути к папке Dim sFilePath As String Function CallDownload(sFileURL As String, sFileName As String) ' sFileURL - ссылка URL для скачивания файла ' sFileName - имя файла с расширением, которое будет присвоено после скачивания Dim h If sFilePath = "" Then 'диалоговое окно выбора папки 'подробнее: http://www.excel-vba.ru/chto-umeet-excel/dialogovoe-okno-vybora-fajlovpapki/ With Application.FileDialog(msoFileDialogFolderPicker) If .Show = False Then Exit Function End If sFilePath = .SelectedItems(1) End With End If If Right(sFilePath, 1) <> "" Then sFilePath = sFilePath & "" 'проверяем есть ли файл с таким же именем в выбранной папке If Dir(sFilePath & sFileName, 16) = "" Then 'файла нет - скачиваем h = DownloadFileAPI(sFileURL, sFilePath & sFileName) Else 'файл есть - запрос на перезапись If MsgBox("Этот файл уже существует в папке: " & sFilePath & vbNewLine & "Перезаписать?", vbYesNo, "www.excel-vba.ru") = vbYes Then 'если существующий файл открыт - невозможно его перезаписать, показываем инф.окно 'отменяем загрузку If IsBookOpen(sFileName) Then MsgBox "Невозможно сохранить файл в указанную папку, т.к. она уже содержит файл '" & sFileName & "' и этот файл открыт." & _ vbNewLine & "Закройте открытый файл и повторите попытку.", vbCritical, "www.excel-vba.ru" Else h = DownloadFileAPI(sFileURL, sFilePath & sFileName) End If End If End If CallDownload = h End Function 'функция скачивания файла в выбранную папку Function DownloadFileAPI(sFileURL, ToPathName) ' sFileURL - ссылка URL для скачивания файла ' ToPathName - полный путь с именем файла для сохранения Dim h Dim sFilePath As String Dim sFileName As String 'вызов функции API для непосредственно скачивания h = (URLDownloadToFile(0, sFileURL, ToPathName, 0, 0) = 0) 'если h = False - файл не удалось скачать, показываем инф.окно If h = False Then MsgBox "Невозможно скачать файл." & vbNewLine & _ "Возможно, у Вас нет прав на создание файлов в выбранной директории." & vbNewLine & _ "Попробуйте выбрать другую папку для сохранения", vbInformation, "www.excel-vba.ru" Exit Function Else 'файл успешно скачан sFileName = Dir(ToPathName, 16) sFilePath = Replace(ToPathName, sFileName, "") If MsgBox("Файл сохранен в папку: " & sFilePath & _ vbNewLine & "Открыть файл сейчас?", vbYesNo, "www.excel-vba.ru") = vbYes Then If IsBookOpen(sFileName) Then MsgBox "Файл с именем '" & sFileName & "' уже открыт. Закройте открытый файл и повторите попытку.", vbCritical, "www.excel-vba.ru" Else Workbooks.Open ToPathName End If End If End If DownloadFileAPI = h End Function 'Функция проверки - открыта ли книга с заданным именем 'подробнее: ' http://www.excel-vba.ru/chto-umeet-excel/kak-proverit-otkryta-li-kniga/ Function IsBookOpen(wbName As String) As Boolean Dim wbBook As Workbook For Each wbBook In Workbooks If Windows(wbBook.Name).Visible Then If wbBook.Name = wbName Then IsBookOpen = True: Exit For End If Next wbBook End Function
Код необходимо скопировать и вставить в книгу в стандартный модуль. Макросы должны быть разрешены.
Основная функция, отвечающая за непосредственно скачивание — это функция API(Application Programming Interface) URLDownloadToFile. Она объявлена в самом верху кода. Там есть страшные директивы вроде #If Win64 Then. Это особые директивы, которые работают даже вне процедур. Поэтому не надо удивляться, что они вне всяких Sub и тем более не надо эти Sub-ы добавлять. При этом так же не надо удивляться, если какие-то из строк внутри этих директив будут подсвечены компилятором VBA красным шрифтом. На функциональность это не повлияет.
Вызов скачивания файла происходит обычным обращением к функции CallDownload. Например, есть ссылка для скачивания: http://www.excel-vba.ru/files/book.xls. И сохранить надо под именем «Книга1.xls». Вызываем функцию скачивания файла:
Sub DownloadFile() Call CallDownload("http://www.excel-vba.ru/files/book.xls", "Книга1.xls") 'вызываем скачивание файла End Sub
Функция сама запросит папку для сохранения файла и после скачивания предложит открыть этот файл. Если такой файл уже есть — будет предложено его перезаписать.
К статье приложен файл, в котором код чуть расширен — он позволяет скачивать файлы сразу из множества ячеек, проставляя при этом признак — скачан файл или нет. И если сразу весь список обработать не получилось и какие-то файлы остались не скачанные(например, имена совпадали, а заменять файлы не надо было), то в этом случае можно будет повторно запустить код и скачиваться будут лишь те, у которых статус не является «Скачан!».
Так же т.к. ячеек много, перед скачиванием файлов будет выбор — запрашивать ли открытие файлов после скачивания или нет. Если открывать не надо, следует ответить Нет. Тогда файлы просто будут скачаны в указанную папку. Однако, если в этой папке будут расположены файлы с идентичными именами — запрос на перезапись все же появится, при этом для каждого файла. Если подобный запрос так же мешает, то надо этот блок:
'проверяем есть ли файл с таким же именем в выбранной папке If Dir(sFilePath & sFileName, 16) = "" Then 'файла нет - скачиваем h = DownloadFileAPI(sFileURL, sFilePath & sFileName) Else 'файл есть - запрос на перезапись If MsgBox("Этот файл уже существует в папке: " & sFilePath & vbNewLine & "Перезаписать?", vbYesNo, "www.excel-vba.ru") = vbYes Then 'если существующий файл открыт - невозможно его перезаписать, показываем инф.окно 'отменяем загрузку If IsBookOpen(sFileName) Then MsgBox "Невозможно сохранить файл в указанную папку, т.к. она уже содержит файл '" & sFileName & "' и этот файл открыт." & _ vbNewLine & "Закройте открытый файл и повторите попытку.", vbCritical, "www.excel-vba.ru" Else h = DownloadFileAPI(sFileURL, sFilePath & sFileName) End If End If End If
заменить на всего одну строку:
h = DownloadFileAPI(sFileURL, sFilePath & sFileName)
Но при этом надо помнить — что при этом можно потерять какие-то важные файлы. Поэтому подобные вещи вы делаете на свой страх и риск.
Однако следует помнить одну вещь: не все сайты вот так запросто разрешают скачивать с них файлы, тем более пачками. Особенно это актуально для всякого рода форексов и иже с ними. Возможно, получится скачать один, два, три — десять файлов. Но всегда может случиться так, что сайт просто заблокирует ваш IP до конца дня, т.к. на сайте установлено ограничение на автоматизированное обращение извне. При этом для разных сайтов решение данной проблемы может быть различным и не всегда решаемым
Скачать файл
Tips_Macro_DownloadFileFromURL.xls (64,0 KiB, 3 837 скачиваний)
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
Часто требуется макросом скачать некий файл из интернета.
Обычно в этом помогает WinAPI-функция URLDownloadToFile, но есть также возможность загрузить файл без её использования:
Чем чревато использование функции URLDownloadToFile — по сути, ничем, кроме как необходимостью прописывать её в 2 вариантах, для обеспечения совместимости с 64-битной Windows
#If VBA7 Then ' Office 2010-2013 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 ' Office 2003-2007 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 DownLoadFileFromURL(ByVal URL$, ByVal LocalPath$, Optional ByVal DisableCache As Boolean = False) As Boolean On Error Resume Next If (LocalPath$ = "") Or (URL$ = "") Then Exit Function If Not LocalPath$ Like "**" Then LocalPath$ = Environ("TEMP") & "" & LocalPath$ Kill LocalPath$ If DisableCache Then Randomize: URL$ = URL$ & "?rnd=" & Left(Rnd(Now) * 1E+15, 10) DownLoadFileFromURL = URLDownloadToFile(0, URL$, LocalPath$, 0, 0) = 0 End Function
Я же предлагаю другое решение — функцию DownloadFile с использованием объектов Microsoft.XMLHTTP и ADODB.Stream:
Sub ПримерИспользования() СсылкаНаФайл$ = "http://excelvba.ru/sites/default/files/3.jpg" ПутьДляСохранения$ = "C:1.jpg" ' скачиваем файл из интернета DownloadFile СсылкаНаФайл$, ПутьДляСохранения$ ' открываем скачанный файл CreateObject("wscript.shell").Run """" & ПутьДляСохранения$ & """" End Sub
Function DownloadFile(ByVal URL$, ByVal LocalPath$) As Boolean ' Функция скачивает файл по ссылке URL$ ' и сохраняет его под именем LocalPath$ Dim XMLHTTP, ADOStream, FileName On Error Resume Next: Kill LocalPath$ Set XMLHTTP = CreateObject("Microsoft.XMLHTTP") XMLHTTP.Open "GET", Replace(URL$, "", "/"), "False" XMLHTTP.send If XMLHTTP.statustext = "OK" Then Set ADOStream = CreateObject("ADODB.Stream") ADOStream.Type = 1: ADOStream.Open ADOStream.Write XMLHTTP.responseBody ADOStream.SaveToFile LocalPath$, 2 ADOStream.Close: Set ADOStream = Nothing DownloadFile = True Else 'MsgBox "Не удаётся скачать файл " & XMLHTTP.statustext End If Set XMLHTTP = Nothing End Function
Загрузка файлов по URL ссылкам
Загрузка файлов по URL ссылкам – инструмент для импорта файлов с веб ресурсов по URL ссылкам, в выбранную папку на компьютере.
С возможностью их переименования при импорте.
Инструкция по использованию:
- Диапазон ссылок на файлы – ссылки на файлы. Должна содержать протокол (например,
http://
). - Выбор папки для файлов – путь к папки для сохранения файлов.
Пример использования инструмента загрузки файлов по URL ссылкам
URL файла – кнопка выбора диапазона ячеек с ссылками URL, на файлы для скачивания. Если в соседнем столбце с ссылками указать новые названия файлов, то при загрузке они будут переименованы. Если в соседнем столбце пусто, то название файлов останется без изменения.
Выбор папки для сохранения – кнопка выбора папки, в которую будут загружены файлы.
Если надо получить ТЕКСТ страницы, то можно использовать примерно такой код:
Sub test()
Set IE = CreateObject(«InternetExplorer.Application»): DoEvents
IE.Navigate «http://ExcelVBA.ru»
While IE.readyState <> 4: DoEvents: Wend ‘ ждем, пока загрузится страница
Set ieDoc = IE.Document
For i = 0 To IE.Document.all.Length — 1
MsgBox IE.Document.all.item(i).innerText, vbInformation, «Элемент № » & i
Next
IE.Quit
Set IE = Nothing
End Sub
Я в объектной модели DOM пока плохо разбираюсь, так что, возможно, есть более простой способ.
Но меня и такой вариант устраивает.
Смотрите, что скачивается, выбираете индексы нужных Вам элементов,
и модернизируете код, чтобы обрабатывался текст только из интересующих Вас частей веб-страницы.
Вот пример работы со страницей, содержащей фреймы:
(заполняется поле поиска, нажимается кнопка ОТПРАВИТЬ, обрабатывается результат из сформированной скриптом веб-страницы)
Function GetSubsribersCollection(Optional ByVal SearchString As String = «*») As Collection
On Error Resume Next
‘Set GetSubsribersCollection = New Collection
If Len(Trim(SearchString)) = 0 Then Exit Function ‘ пустая строка поиска недопустима
‘ pi.Show «Биллинг — запрос данных »
‘ «Подключение к серверу…»
Set IE = CreateObject(«InternetExplorer.Application»): DoEvents
NavStr = «https://…./template.cgi?tpl=base/index.tpl»
‘IE.Visible = -1
IE.Navigate NavStr
While IE.readyState <> 4: DoEvents: Wend
Set ieDoc = IE.Document
‘pi.StartNewAction 20, 70, «Обработка запроса…»
With ieDoc.frames.item(0).Document
.all(«search_limit»).selectedIndex = 2
.all(«search»).Value = SearchString
.forms(«frm_param»).submit
End With
While IE.Busy
DoEvents
Wend
Set t = ieDoc.frames.item(1).Document.activeElement.childNodes(1)
For i = 1 To t.Rows.Length — 2
‘If i Mod PI_step = 0 Then pi.CurAction 0, 0, , «Обрабатывается строка » & i
With t.Rows.item(i).Cells
‘ код
End With
Next i
IE.Quit
Set IE = Nothing
pi.Hide
End Function
I’ve been spending the last few hours trying to figure out how to save a file onto the computer using VBA. The code template below that I found on another forum seems promising, except when I go to the desktop to access it, the .csv file has what looks like the page’s source code instead of the actual file I want. This may be because when I go to the URL, it doesn’t automatically download the file; rather, I am asked to save the file to a certain location (since I don’t know the path name of the uploaded file on the site).
Is there any way to alter this code to accommodate this, or will I have to use a different code entirely?
Sub Test()
Dim FileNum As Long
Dim FileData() As Byte
Dim MyFile As String
Dim WHTTP As Object
On Error Resume Next
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5")
If Err.Number <> 0 Then
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")
End If
On Error GoTo 0
MyFile = "MY_URL_HERE"
WHTTP.Open "GET", MyFile, False
WHTTP.send
FileData = WHTTP.responseBody
Set WHTTP = Nothing
If Dir("C:UsersBLAHBLAHDesktop", vbDirectory) = Empty Then MkDir "C:UsersBLAHBLAHDesktop"
FileNum = FreeFile
Open "C:UsersBLAHBLAHDesktopmemberdatabase.csv" For Binary Access Write As #FileNum
Put #FileNum, 1, FileData
Close #FileNum
End Sub
Cross posts:
http://www.ozgrid.com/forum/showthread.php?t=178884
http://www.excelforum.com/excel-programming-vba-macros/925352-vba-go-to-website-and-download-file-from-save-prompt.html
shA.t
16.4k5 gold badges53 silver badges111 bronze badges
asked May 23, 2013 at 1:35
I found over the years more ways how to save/download data
using vba:
- The firs option witch I prefer and would recommend is to use the
URLDownloadToFile function
of theuser32 library
using the following solution - The second one which was also mentioned be yourself. The point here is to use the
Microsoft WinHTTP Services (Interop.WinHttp) COM library
. In order to achieve this you can also add the Interop.WinHttp reference to your project link. After that you are able to use simpler notation like here link - The third option I aware is to ask the browser to save it for us and then using the
Save_Over_Existing_Click_Yes
function was mentioned by Santosh. In this case we open an Internet Explorer using the COM interface and navigate to the proper site. So we have to add theMicrosoft Internet Controls
(Interop.SHDocVw
) and theMicrosoft HTML Object Library
(Microsoft.mshtml
) references to our project in order to gain intellisense feature of the editor.
I don’t like this download method because this is a work around by hacking. BUT if your IE session was already established authenticated etc. this gonna work nicely. The save function of the Internet Controls was dropped because of security concern. See for example: link
Newer the less you have to have the correct url to download what you want. If you pick the wrong one you will download something else
- So please try to make sure the the url you use is correct by enter it in a browser. If it opens the right .csv file than your source could work too.
- Also please try to send some more information: for example the url to the .csv file
answered Jan 10, 2016 at 22:16
minus oneminus one
6227 silver badges27 bronze badges
Try below code :
Copied from here (Not tested)
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
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
Declare Function SetForegroundWindow Lib "user32" Alias "SetForegroundWindow" (ByVal hwnd As Long) As Long
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Private Sub Save_Over_Existing_Click_Yes()
Dim hWnd As Long
Dim timeout As Date
Debug.Print "Save_Over_Existing_Click_Yes"
'Find the Download complete window, waiting a maximum of 30 seconds for it to appear. Timeout value is dependent on the
'size of the download, so make it longer for bigger files
timeout = Now + TimeValue("00:00:30")
Do
hWnd = FindWindow(vbNullString, "Save As")
DoEvents
Sleep 200
Loop Until hWnd Or Now > timeout
Debug.Print " Save As window "; Hex(hWnd)
If hWnd Then
'Find the child Close button
hWnd = FindWindowEx(hWnd, 0, "Button", "&Yes")
Debug.Print " Yes button "; Hex(hWnd)
End If
If hWnd Then
'Click the Close button
SetForegroundWindow (hWnd)
Sleep 600 'this sleep is required and 600 miiliseconds seems to be the minimum that works
SendMessage hWnd, BM_CLICK, 0, 0
End If
End Sub
answered May 23, 2013 at 2:57
SantoshSantosh
12.1k4 gold badges41 silver badges72 bronze badges
5
ares_dolbi12
Сообщение № 3
Группа: Пользователи Ранг: Прохожий Сообщений: 2
Замечаний: |
lebensvoll, Спасибо!
мб кому надо (для таких же нубов как я):
Есть excel файл 23 тыщ. ссылок для 4.3 тыщ. ФИО
1. Создал папки по списку ФИО в папке C:test
[vba]
Код
Sub MDir()
On Error Resume Next
For Each oCell In Range([A1], [A65536].End(xlUp))
If Not IsEmpty(oCell) Then MkDir «C:test» & oCell
Next
End Sub
[/vba]
2. Чуть подправил код, чтобы он сохранял файлы в соответствующие папки My WebPage
[vba]
Код
‘—————————————————————————————
‘ File : mDownloadFileFromURL
‘ Purpose: код позволяет скачивать файлы из интернета по указанной ссылке
‘—————————————————————————————
Option Explicit
‘объявление функции API — URLDownloadToFile
‘ работает на любых ПК под управлением ОС Windows
‘ на MAC код работать не будет
#If Win64 Then ‘для операционных систем с 64-разрядной архитектурой
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
#If VBA7 Then ‘для любых операционных систем с офисом 2010 и выше
Declare PtrSafe Function URLDownloadToFile Lib «urlmon» Alias «URLDownloadToFileA» _
(ByVal pCaller As LongPtr, ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As LongPtr) As LongPtr
#Else ‘для 32-разрядных операционных систем
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
#End If
‘переменная для хранения пути к папке
Function CallDownload(sFileURL As String, sFileName As String,sFilePath As String)
‘ sFileURL — ссылка URL для скачивания файла
‘ sFileName — имя файла с расширением, которое будет присвоено после скачивания
Dim h
If sFilePath = «» Then
‘диалоговое окно выбора папки
‘подробнее: http://www.excel-vba.ru/chto-umeet-excel/dialogovoe-okno-vybora-fajlovpapki/
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = False Then
Exit Function
End If
sFilePath = .SelectedItems(1)
End With
End If
If Right(sFilePath, 1) <> «» Then sFilePath = sFilePath & «»
‘проверяем есть ли файл с таким же именем в выбранной папке
If Dir(sFilePath & sFileName, 16) = «» Then
‘файла нет — скачиваем
h = DownloadFileAPI(sFileURL, sFilePath & sFileName)
Else
‘файл есть — запрос на перезапись
If MsgBox(«Этот файл уже существует в папке: » & sFilePath & vbNewLine & «Перезаписать?», vbYesNo, «www.excel-vba.ru») = vbYes Then
‘если существующий файл открыт — невозможно его перезаписать, показываем инф.окно
‘отменяем загрузку
If IsBookOpen(sFileName) Then
MsgBox «Невозможно сохранить файл в указанную папку, т.к. она уже содержит файл ‘» & sFileName & «‘ и этот файл открыт.» & _
vbNewLine & «Закройте открытый файл и повторите попытку.», vbCritical, «www.excel-vba.ru»
Else
h = DownloadFileAPI(sFileURL, sFilePath & sFileName)
End If
End If
End If
CallDownload = h
End Function
‘функция скачивания файла в выбранную папку
Function DownloadFileAPI(sFileURL, ToPathName)
‘ sFileURL — ссылка URL для скачивания файла
‘ ToPathName — полный путь с именем файла для сохранения
Dim h
Dim sFilePath As String
Dim sFileName As String
‘вызов функции API для непосредственно скачивания
h = (URLDownloadToFile(0, sFileURL, ToPathName, 0, 0) = 0)
‘если h = False — файл не удалось скачать, показываем инф.окно
If h = False Then
MsgBox «Невозможно скачать файл.» & vbNewLine & _
«Возможно, у Вас нет прав на создание файлов в выбранной директории.» & vbNewLine & _
«Попробуйте выбрать другую папку для сохранения», vbInformation, «www.excel-vba.ru»
Exit Function
Else ‘файл успешно скачан
sFileName = Dir(ToPathName, 16)
sFilePath = Replace(ToPathName, sFileName, «»)
End If
DownloadFileAPI = h
End Function
‘Функция проверки — открыта ли книга с заданным именем
‘подробнее:
‘ http://www.excel-vba.ru/chto-umeet-excel/kak-proverit-otkryta-li-kniga/
Function IsBookOpen(wbName As String) As Boolean
Dim wbBook As Workbook
For Each wbBook In Workbooks
If Windows(wbBook.Name).Visible Then
If wbBook.Name = wbName Then IsBookOpen = True: Exit For
End If
Next wbBook
End Function
[/vba]
3. Использовал фу-цию CallDownload (B1 ссылка, A1 ФИО, ‘D1&ПРАВСИМВ(B1;5)’ имя файла с расширением типа .jpeg или .pdf)
[vba]
Код
=CallDownload(B1;D1&ПРАВСИМВ(B1;5);»C:test»&A1&»»)
[/vba]
Сообщение отредактировал ares_dolbi12 — Воскресенье, 14.03.2021, 03:10
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.
Pᴇʜ
56k9 gold badges49 silver badges73 bronze badges
asked Jul 26, 2013 at 9:13
0
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
Rafiki
5945 silver badges19 bronze badges
answered Jul 26, 2013 at 9:13
6
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:SomePath" & 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!
airstrike
2,2211 gold badge24 silver badges26 bronze badges
answered Apr 25, 2014 at 17:48
2
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
answered Dec 26, 2019 at 23:41
1
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:Temptest.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.
answered Jan 26, 2021 at 14:10
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") & "DownloadsTEST.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
answered Nov 23, 2021 at 19:09
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
answered Dec 26, 2019 at 23:26
1