Excel download file from url

Until now I was only writing about HTTP methods, but did not really describe the final trick to download the file from URL. In today’s article I want to present You and compare two methods of downloading files from URL – URLDownloadToFile function and saving byte array to file method.

How to download file from URL URLDownloadToFile

I don’t want to copy definitions from other websites or rewrite them with other words. I want You to present it my way, how I understand this and how I deal with that.

URLDownloadToFile function

This was the first method I have ever learn to download file from URL. Most likely because that is its function name.

Firstly You need to declare this function pointing out which and where this comes from.

Private 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

So how to read that correctly?

  • You declared function called URLDownloadToFile from urlmon.dll library file.
  • This file is somewhere in C:WindowsSystem32 system folder.
  • You referred to URLDownloadToFileA from this library.
  • Your function has 5 variables – 3 Long type and 2 String type.
  • URLDownloadToFile returns Long type value.

How I use this?

The best example is the code. Let me show You also below.

xstatus = URLDownloadToFile(0, myURL, filepath, 0, 0)
  • This functions returns Long value, so xstatus variable must be declared as Long type.
  • myURL has to be String type variable, link to website.
  • filepath has to be also String, which represents new path for download (path to folder + name of file with extension).

This is enough information You need to use this function. If You feel it is not, please go to other pages like this.

Saving byte array to file method

This method requires to create Http object like XMLHttp or WinHttp as first, open the URL and send request to the server like it was in article.

'for example
Dim xmlhttp As New MSXML2.XMLHTTP60

xmlhttp.Open "GET", myURL, False
xmlhttp.send

Secondly, create FreeFile as Long type, byte array and put new file path into String.
Then put inside byte array .responseBody property of http object. This step gets the file from object and puts inside the array.

Dim h As Long
Dim PictureToSave() As Byte
Dim FileName As String

h = FreeFile
FileName = "filepath"
PictureToSave() = xmlhttp.responseBody

The last thing You have to do is create that FreeFile in given file path and put inside that byte array.

Open FileName For Binary As #h
Put #h, 1, PictureToSave()
Close #h

Little bit complicated at the beginning, but not that hard in the end.

Summary

That’s it! Those were 2 methods to download file from URL, which I was and I am using in my macros. Which one is yours? If You have other ways to download file via VBA please feel free to write about this in comment section 🙂

I’m very advanced in VBA, Excel, also easily linking VBA with other Office applications (e.g. PowerPoint) and external applications (e.g. SAP). I take part also in RPA processes (WebQuery, DataCache, IBM Access Client Solutions) where I can also use my SQL basic skillset. I’m trying now to widen my knowledge into TypeScript/JavaScript direction.
View all posts by Tomasz Płociński

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

Содержание

  1. Как скачать файл из интернета по ссылке
  2. Excel-VBA Solutions
  3. Pages
  4. Download a file from url using VBA
  5. Download Files with VBA URLDownloadToFile
  6. The VBA Tutorials Blog
  7. The Built-in Windows Library Function
  8. Downloading Our First File using VBA
  9. Downloading Multiple Files
  10. Designing with Uniqueness in Mind
  11. Timeout Code to Track Problems
  12. Scraping for File Locations
  13. Ethical Questions
  14. Conclusion

Как скачать файл из интернета по ссылке

Вся суть статьи уже в заголовке. Возникает порой необходимость скачивания файлов из интернета только на основании ссылки. Например, это какие-то постоянно меняющиеся данные или автоматически генерируемая другим кодом ссылка. Или еще более усугубленный вариант — строк 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 799 скачиваний)

Статья помогла? Поделись ссылкой с друзьями!

Источник

Excel-VBA Solutions

Want to become an expert in VBA? So this is the right place for you. This blog mainly focus on teaching how to apply Visual Basic for Microsoft Excel. So improve the functionality of your excel workbooks with the aid of this blog. Also ask any questions you have regarding MS Excel and applying VBA. We are happy to assist you.

Pages

Download a file from url using VBA

Sometimes our Excel VBA applications need to interact with websites. Downloading a file through a URL is a typical example. In this lesson you can learn how to do that using XMLHttpRequest and ADODB.Stream object. XMLHttp is used to request the data from the web server. Once we receive the data from the server, the ADODB.Stream object is used to write that data to a file. You can use this method to download file types such as image files, csv files etc.

So let’s start writing our macro to download a file using the Uniform Resource Locator (URL). Let’s name our Sub procedure as “DownloadFileFromURL”

First we need to declare a few variables.

Next assign the URL of the file to the FileUrl variables

For an example if your file URL is https://www.excelvbasolutions.com/images/chart.jpg then you can assign it to the variable as follows.

Next step is to create a XMLHttp object to request the data from the server.

Call the open method followed by the send method.

Then check the status. If it equals 200 (OK), we can move to the next step.

Now we need to create an ADODB.Stream object to write the data(received) to a file.

Stream in programming means flow of data. In programming data is what flows between processors and input or output devices. Check this link to see all the Properties, Methods and Events of Stream object.

But we need to use only a few of them here.

In the SaveToFile method I have entered 2 as SaveOptions. So the program will overwrite the file with the data from the stream if the file already exists. If you don’t want to overwrite the existing file then replace it with 1.

Below is the full code which you can use to download a file through a URL.

Dim FileUrl As String
Dim objXmlHttpReq As Object
Dim objStream As Object

FileUrl = «URL of your file»

‘example
‘FileUrl = «https://www.excelvbasolutions.com/images/chart.jpg»

Set objXmlHttpReq = CreateObject(«Microsoft.XMLHTTP»)
objXmlHttpReq.Open «GET», FileUrl, False, «username», «password»
objXmlHttpReq.send

If objXmlHttpReq.Status = 200 Then
Set objStream = CreateObject(«ADODB.Stream»)
objStream.Open
objStream.Type = 1
objStream.Write objXmlHttpReq.responseBody
objStream.SaveToFile ThisWorkbook.Path & «» & «file.jpg», 2
objStream.Close
End If

In the above example I showed how to download a .jpg file. But you can use this method to download other file types as well. Remember to change the file extension depending on the type of the file you download. For example if you are downloading a CSV file then the SaveToFile method should be changed as follows.

Источник

Download Files with VBA URLDownloadToFile

The VBA Tutorials Blog

Automation is all the rage these days. Automation can thrash labor markets while simultaneously exploding productivity and profits. It will also make human jobs less boring (assuming we still have jobs). In this tutorial, we will learn how to use VBA to programmatically download files based on URLs. We might already know these URLs, or we may have to scrape them from the web and parse them. This is automation of a rather dull task, so implementing it hopefully has a positive impact on your work.

This tutorial is a little more involved than our recent tutorials. It contains multiple steps and pieces of code that are outside the general scope of a “downloading files with VBA” tutorial. Where it makes sense to explain, we’ll explain, but there are times when we’ll simply gloss over the technical parts and just use the code without much explanation. This guide lays out the practical requirements for downloading files from the internet using VBA. Once you finish the tutorial, you’ll be able to easily download URL files yourself.

With that said, let’s get started.

The Built-in Windows Library Function

There are a number ways to download files using VBA, including using an XMLHTTP request to stream the binary data or text associated with your file, and then using the SaveToFile method to finish saving the downloaded file. This is probably the most common way to download files, but we’re not going to do it this way.

In this tutorial, we’re going to download files using a Windows function called URLDownloadToFile . The URLDownloadToFile function is part of the Windows library urlmon. Before we can use it, we need to declare the function and connect to it from VBA. We can do that by placing this line of code at the top of a VBA module:

Make powerful macros with our free VBA Developer Kit

It’s easy to copy and paste a macro like this, but it’s harder make one on your own. To help you make macros like this, we built a free VBA Developer Kit and wrote the Big Book of Excel VBA Macros full of hundreds of pre-built macros to help you master file I/O, arrays, strings and more — grab your free copy below.

I know this is a rather long function declaration. Libraries are basically sets of prewritten code, usually optimized by the library developer (Microsoft, for this library). All the code needed to access a URL, download the stream of bits and bytes, then structure them back into a file on the hard drive is conveniently wrapped into this single function. All we have to do is throw this declaration at the top to begin using it.

We can see the return type is Long , which means the function will return a whole number. This makes checking whether the download started much easier. We’ll get to that soon, but for now, the most important parts are the szURL and szFileName parameters. These arguments represent the URL source and the name of the file after we’ve downloaded it. The other arguments can almost always be set to 0 .

Downloading Our First File using VBA

Let’s say you find a picture you like and you want to download it. You could right-click then “Save Image as…”, or you could use VBA. Admittedly, using VBA would be inane for a single picture, but if you have hundreds of pictures to download, this task would be a perfect automation target. This tutorial focuses on downloading images, but the function is just as useful for downloading other file types.

Anyway, we’re going to start with just one picture: a cityscape picture from Hong Kong’s Wikipedia page as of November 2018. In the HTML, every picture on every webpage is represented as a link to the picture’s very own URL, and that’s the URL we need to pass to the URLDownloadToFile function. You do not want to pass the URL of the webpage where the picture is embedded.

Under the architecture section on the Hong Kong Wikipedia page, there is a nice panorama of Hong Kong at night. We can access its URL by right-clicking and then clicking “Copy Image Location” or “Copy Image Address.” The words may change depending on your browser, but you get the idea.


Copy the URL of the image by clicking the «Copy Image Location» option.

You should have the following image path on your clipboard:

. If you paste this path directly into a web browser’s URL box, you’ll get the image on its own page.

To download the picture with VBA, we can run a short subroutine, like this:

If you have a folder named C:DownloadedPics , there will now be a file entitled HK Skyline.jpg in that folder. Simple as that. Notice how we concatenated our download path ( dlpath ) and our file name. Because we do that, it’s important to have a trailing backslash at the end of your download path.

If a folder with the path you specify doesn’t exist, your download will fail. You won’t get any error messages, but your file won’t be downloaded anywhere.

If the download folder doesn’t exist, don’t worry. You can make the folder using VBA before calling the URLDownloadToFile function. This approach is particularly useful if you frequently automate repetitive tasks. For example, you can timestamp the folder name when you run the program so you can go back through the folders later and know when you ran the macro.

Downloading Multiple Files

If you’re going to download multiple files, you likely already have a list of URLs. Lists are nice, because you can stick them in an array then iterate through your array with a For Loop. You just need to program a way to change the downloaded location’s filepath each time, otherwise you’ll overwrite the previous download with each new file. It’s also a smart idea to check for delays when downloading multiple files. We’ll explain why momentarily.

Designing with Uniqueness in Mind

If the list of files you want to download is small enough, you could manually label each URL and use the label as the filename. For example, you could have 2 columns in Excel: the first column will contain the file name and the second column will contain the URL you want to download, like this:


A list of cities (labels) and a URL with a photo of the respective city

Now we can iterate through this list, downloading each picture and assigning it a unique name.

Since we know we only want to download jpg pictures in this example, we hard-coded the .jpg extension in our URLDownloadToFile function. Once downloaded, we should have a folder with files looking something like this:


The destination folder with six downloaded pictures of cities

Timeout Code to Track Problems

If you download several hundred files per run, you will want to track which files are missing. An easy way to implement a timeout is to check the URLDownloadToFile return value and wait a couple seconds if it is not the desired result. If it hangs for more than the specified time, move to the next URL and mark that file’s download as failed.

A return value of zero ( 0 ) means the download has started successfully. Barring some connection interruption or memory failure downloading a gigantic file, it should finish. Thus, a simple yet effective way to track download problems is to check whether the result of the function is zero. If it isn’t, try it one more time before moving on. Other return values are out-of-memory or unreachable-source errors. If you want to be very meticulous, you could mark the type of failure in your program (hint: use an array).

For a more robust solution, you can use VBA to check whether or not the files exist before exiting your macro. If they don’t, you know the download failed or it’s still downloading.

In this example, we capture the returning long integer and check whether or not it’s a zero. If it’s not, we force the macro to try it again. If it fails a second time, we just give up and move on. We don’t implement a way to flag it as failed in this macro, but I recommend you store details about the failed download into an array before moving on.

Scraping for File Locations

If you want to grab every picture on a website, you can capture the URLs of the images via webscraping.

Since images will be tagged with img in the webpage’s HTML, you can use VBA’s GetElementsByTagName function to grab all the image URLs. You can easily adapt our VBA webscraping tutorial to grab the img tag. You will then need to access the src property of each Item, which will contain the URL of the image file. If the src property is not available for some reason, you might be able to use the href property. At least one of these two properties will be present for all images.

The modification from the webscraping tutorial would follow logic like this:

The example we used for webscraping used the Wikipedia page on country and dependency populations, which has a nice table of countries with ranks, populations, and little flags. To practice, try to scrape the table, extract the country name, scrape the associated flag’s image URL, download the flag picture file, and use the extracted country name to name the file. Paste your solution in the comments section!

If you aren’t so ambitious, you could use something like imgname = i & downloadPath , where i is the for-loop control variable. This method would match the flag with the country’s population rank, so there is some practicality to doing it this simpler way.

If you’re lucky, the photos on the website might have a title property, and you could use that for naming, too.

Ethical Questions

You can automate the download of hundreds or thousands of files rather easily using this method, especially when coupled with a webscraper that’s simply looking for a tag, like the img tag, to grab any and all files on a website.

There are three ethical issues here.

First, you’ll be requesting server time from someone or some company, and automating this process might put strain on their infrastructure. In the extrinsic case, you might get your IP banned from accessing the server as a punishment, but even if you don’t, there’s the ethical question of using up resources others are providing for free and fair use. For huge sites, like Google or Amazon, they probably won’t notice at all. But smaller companies, especially those running their own servers, might be affected.

The second ethical question revolves around hotlinking and revenue theft. Basically, if you already know the image URL and don’t need to visit the main webpage (such as if you found the image through Google’s Image Search and just grabbed the URL), you’ll be depriving the host of any advertising revenue. On one hand, you won’t be taking up server resources to load the main page, but you also won’t be rewarding the host with any advertising revenue or traffic in exchange for their information. This could harm their search engine rankings.

While this kind of automation probably doesn’t carry ethical questions of eliminating someone’s job, it does carry some ethical implications. You should think about such ethical considerations before automating any task.

The third ethical question, and the one that plagued me the most before posting this tutorial, is that someone with criminal intent could use the function for more sinister macros. For example, someone could write a macro to automatically download viruses or other nefarious file types to someone’s machine. I’m posting this tutorial because many people would benefit from being able to automatically download files using VBA. Don’t be a jerk and abuse the knowledge you’ve learned as a VBA developer.

Conclusion

In this tutorial, you learned how to use VBA to download files. We used images in our examples, but you can download any file type. The entire automation process can be quite long and may require a lot of research, but this tutorial will get you on your way. Automation can help reduce tedious work, but always remember to consider the ethical implications that arise from automating work, from job elimination to revenue theft.

I hope you found this helpful. When you’re ready to take your VBA to the next level, remember to subscribe using the form below.

Ready to do more with VBA?
We put together a giant PDF with over 300 pre-built macros and we want you to have it for free. Enter your email address below and we’ll send you a copy along with our VBA Developer Kit, loaded with VBA tips, tricks and shortcuts.

Before we go, I want to let you know we designed a suite of VBA Cheat Sheets to make it easier for you to write better macros. We included over 200 tips and 140 macro examples so they have everything you need to know to become a better VBA programmer.

This article was written by Cory Sarver, a contributing writer for The VBA Tutorials Blog. Visit him on LinkedIn and his personal page.

Источник

Хитрости »

2 Декабрь 2016              40445 просмотров


Как скачать файл из интернета по ссылке

Вся суть статьи уже в заголовке. Возникает порой необходимость скачивания файлов из интернета только на основании ссылки. Например, это какие-то постоянно меняющиеся данные или автоматически генерируемая другим кодом ссылка. Или еще более усугубленный вариант — строк 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

Если надо получить ТЕКСТ страницы, то можно использовать примерно такой код:  

  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

ThreeWave
Downloading A File From The Web

This page describes how to use VBA to download a file from the web.
ShortFadeBar

Your application may need to download a file from the web. This is an easy task to complete. The code
on this page uses the URLDownloadToFile Windows API function to perform the
actual download. The code that wraps up this API, a function called DownloadFile, handles
the circumstances when the local destination file already exists. The function prototype of DownloadFile
is as follows:

Public Function DownloadFile(UrlFileName As String, _
                            DestinationFileName As String, _
                            Overwrite As DownloadFileDisposition, _
                            ErrorText As String) As Boolean

The parameter UrlFileName is the full URL of the file to be downloaded, such as
http://www.cpearson.com/Zips/FindAll.zip. The
DestinationFileName
parameter is the name of the local file on your machine where the downloaded
file should be stored. This must be a fully qualified file name, not a folder name. The
Overwrite parameter specifies how to handle the case when
DestinationFileName already exists. If Overwrite is
OverwriteKill (= 0), the existing file is deleted with the Kill
function. If Overwrite is OverwriteRecycle (= 1), the local file
is sent to the Windows Recycle Bin. If Overwrite is DoNotOverwrite (= 2)
the local file will not be overwritten and the download operation will not be carried out. If Overwrite
is PromptUser (= 3) ,the user is prompted with a MsgBox asking whether to replace the existing file. If the user
chooses No, the download operation is cancelled. If the user chooses Yes, the existing file is sent to the
Windows Recycle Bin. The ErrorText parameter is a string that will be populated with the reason
the download failed. If the download was successful, ErrorText is set to an empty string.

The function returns True if the download was successful, or False if the download
failed. If the download failed, ErrorText will contain the reason.

SectionBreak

The complete code is shown below. The code includes the DownloadFile procedure and the
RecycleFileOrFolder procedure to send the existing file to the Recycle Bin, if necessary.

Option Explicit
Option Compare Text



Public Enum DownloadFileDisposition
    OverwriteKill = 0
    OverwriteRecycle = 1
    DoNotOverwrite = 2
    PromptUser = 3
End Enum


Private Declare Function SHFileOperation Lib "shell32.dll" Alias _
    "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

Private Declare Function PathIsNetworkPath Lib "shlwapi.dll" _
    Alias "PathIsNetworkPathA" ( _
    ByVal pszPath As String) As Long

Private Declare Function GetSystemDirectory Lib "kernel32" _
    Alias "GetSystemDirectoryA" ( _
    ByVal lpBuffer As String, _
    ByVal nSize As Long) As Long

Private Declare Function SHEmptyRecycleBin _
    Lib "shell32" Alias "SHEmptyRecycleBinA" _
    (ByVal hwnd As Long, _
     ByVal pszRootPath As String, _
     ByVal dwFlags As Long) As Long

Private Const FO_DELETE = &H3
Private Const FOF_ALLOWUNDO = &H40
Private Const FOF_NOCONFIRMATION = &H10
Private Const MAX_PATH As Long = 260

Private Type SHFILEOPSTRUCT
    hwnd As Long
    wFunc As Long
    pFrom As String
    pTo As String
    fFlags As Integer
    fAnyOperationsAborted As Boolean
    hNameMappings As Long
    lpszProgressTitle As String
End Type


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

Private Declare Function DeleteUrlCacheEntry Lib "wininet.dll" Alias _
    "DeleteUrlCacheEntryA" (ByVal lpszUrlName As String) As Long


Public Function DownloadFile(UrlFileName As String, _
                            DestinationFileName As String, _
                            Overwrite As DownloadFileDisposition, _
                            ErrorText As String) As Boolean

Dim Disp As DownloadFileDisposition
Dim Res As VbMsgBoxResult
Dim B As Boolean
Dim S As String
Dim L As Long

ErrorText = vbNullString

If Dir(DestinationFileName, vbNormal) <> vbNullString Then
    Select Case Overwrite
        Case OverwriteKill
            On Error Resume Next
            Err.Clear
            Kill DestinationFileName
            If Err.Number <> 0 Then
                ErrorText = "Error Kill'ing file '" & DestinationFileName & "'." & vbCrLf & Err.Description
                DownloadFile = False
                Exit Function
            End If
    
        Case OverwriteRecycle
            On Error Resume Next
            Err.Clear
            B = RecycleFileOrFolder(DestinationFileName)
            If B = False Then
                ErrorText = "Error Recycle'ing file '" & DestinationFileName & "." & vbCrLf & Err.Description
                DownloadFile = False
                Exit Function
            End If
        
        Case DoNotOverwrite
            DownloadFile = False
            ErrorText = "File '" & DestinationFileName & "' exists and disposition is set to DoNotOverwrite."
            Exit Function
            
        'Case PromptUser
        Case Else
            S = "The destination file '" & DestinationFileName & "' already exists." & vbCrLf & _
                "Do you want to overwrite the existing file?"
            Res = MsgBox(S, vbYesNo, "Download File")
            If Res = vbNo Then
                ErrorText = "User selected not to overwrite existing file."
                DownloadFile = False
                Exit Function
            End If
            B = RecycleFileOrFolder(DestinationFileName)
            If B = False Then
                ErrorText = "Error Recycle'ing file '" & DestinationFileName & "." & vbCrLf & Err.Description
                DownloadFile = False
                Exit Function
            End If
    End Select
End If
L = DeleteUrlCacheEntry(UrlFileName)
L = URLDownloadToFile(0&, UrlFileName, DestinationFileName, 0&, 0&)
If L = 0 Then
    DownloadFile = True
Else
    ErrorText = "Buffer length invalid or not enough memory."
    DownloadFile = False
End If
    
End Function
                            
Private Function RecycleFileOrFolder(FileSpec As String) As Boolean

    Dim FileOperation As SHFILEOPSTRUCT
    Dim lReturn As Long

    If (Dir(FileSpec, vbNormal) = vbNullString) And _
        (Dir(FileSpec, vbDirectory) = vbNullString) Then
        RecycleFileOrFolder = True
        Exit Function
    End If

    With FileOperation
        .wFunc = FO_DELETE
        .pFrom = FileSpec
        .fFlags = FOF_ALLOWUNDO
		
        .fFlags = FOF_ALLOWUNDO + FOF_NOCONFIRMATION
    End With

    lReturn = SHFileOperation(FileOperation)
    If lReturn = 0 Then
        RecycleFileOrFolder = True
    Else
        RecycleFileOrFolder = False
    End If
End Function

ShortFadeBar

LastUpdate This page last updated: 23-April-2009.

Понравилась статья? Поделить с друзьями:
  • Excel exe process id
  • Excel does not contain
  • Excel exe office 2013
  • Excel documents in google docs
  • Excel exe bad image