Excel скачать файл по ссылке

Хитрости »

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 ссылкам

Загрузка файлов по URL

Загрузка файлов по 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's user avatar

shA.t

16.4k5 gold badges53 silver badges111 bronze badges

asked May 23, 2013 at 1:35

user2370064's user avatar

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 the user32 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 the Microsoft Internet Controls (Interop.SHDocVw) and the Microsoft 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

Community's user avatar

answered Jan 10, 2016 at 22:16

minus one's user avatar

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

Santosh's user avatar

SantoshSantosh

12.1k4 gold badges41 silver badges72 bronze badges

5

ares_dolbi12 Дата: Суббота, 13.03.2021, 19:30 |
Сообщение № 3

Группа: Пользователи

Ранг: Прохожий

Сообщений: 2


Репутация:

0

±

Замечаний:
0% ±


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ᴇʜ's user avatar

Pᴇʜ

56k9 gold badges49 silver badges73 bronze badges

asked Jul 26, 2013 at 9:13

Ole Henrik Skogstrøm's user avatar

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's user avatar

Rafiki

5945 silver badges19 bronze badges

answered Jul 26, 2013 at 9:13

Ole Henrik Skogstrøm's user avatar

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's user avatar

airstrike

2,2211 gold badge24 silver badges26 bronze badges

answered Apr 25, 2014 at 17:48

Cole Busby's user avatar

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

AndrewK's user avatar

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

Geoff Griswald's user avatar

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

FreeSoftwareServers's user avatar

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

AndrewK's user avatar

1

Like this post? Please share to your friends:
  • Excel скачать торрент рутрекер
  • Excel склонение в родительный падеж
  • Excel скачать торрент на английском
  • Excel склеить ячейки с данными
  • Excel скачать торрент кряк