본문 바로가기

VBA

인터넷에서 파일 다운받기

오늘은 엑셀을 사용하여 인터넷에서 파일을 다운받는 것에 대해 알아보겠습니다.

왜 굳이 엑셀을 이용하여 인터넷파일을 다운받아야 하는가 의문이 들수도 있겠지만 살다보면 필요할 날이 올겁니다. ^^

이것도 역시 윈도우 API를 이용한 것입니다. API를 이용하는 것은 그냥 닥치고 붙여넣기 입니다. API를 제대로 활용한다는 것은 워낙 넓고 깊은 세계라 필요한 부분만 활용하는 것이 최선인것 같습니다.

원문 : http://www.cpearson.com/Excel/DownloadFile.aspx

오늘 자료도 역시 cpearson.com에서 가져왔습니다. 개인적으로 정말 훌륭한 프로그래머라고 생각되네요. 어떤 프로그램이든 매우 깔끔하고 명확합니다.

일단 기본명령어 구문입니다.

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

위의 사용자 정의함수를 써서 인터넷에 있는 파일을 다운 받습니다. 각줄의 끝에 "_" 연결하는 의미인것 알고 계시죠? 한줄의 명령어이지만 저렇게 받는 변수마다 줄을 뛰어놓아서 알아보기 쉽게 해놨습니다.

각 변수들에 대한 설명입니다.
UrlFileName은 다운할 파일의 URL풀네임입니다. 본문에 나온 예를 들면 http://www.cpearson.com/Zips/FindAll.zip 처럼 쓸수 있습니다.
DestinationFileName 은 다운할 파일이 저장되는 경로와 저장할 파일명입니다. C:\Test\FindAll.zip 처럼 쓸수 있겠죠.
Overwrite 는 여러가지 경우에 대한 처리를 지정해줍니다. OverwriteKill (=0) 으로 하면 그냥 이미 해당 파일이 있어도 덮어씌워버립니다. OverwriteRecycle (=1) 이면 이미 있는 파일을 휴지통으로 보내버리고 새로운 파일을 다운받습니다. DoNotOverwrite (=2)는 이미 파일이 있으면 파일을 다운받지 않고 프로세스를 끝내버립니다. PromptUser (=3)는 이미 파일이 있을때 사용자에게 물어보게 됩니다. 예스를 선택하면 기존파일을 휴지통으로 보내고 새로운 파일을 다운받습니다. ErrorText 는 에러가 발생할 경우 원인을 알려주게 됩니다.

이제 소스 코드입니다. 프로그램이 좀 긴편입니다. 인터넷에서 파일을 다운받는 경우 여러가지 경우의 수가 발생하고 그에 대한 처리가 각각 지정되다보니 전체적인 라인이 많이 늘어나 있습니다. 천천히 자세히 살피시고 사용할때는 그냥 쭉 복사해서 사용하시기 바랍니다.

선언문
Option Explicit
Option Compare Text

'''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' modDownloadFile
' By Chip Pearson, chip@cpearson.com, www.cpearson.com/Excel/DownloadFile.aspx
' Date: 23-April-2003
' This module contains the DownloadFile function and supporting players to
' download a file from a URL to a local file name.
'
' Example Usage:
'
'        Dim URL As String
'        Dim LocalFileName As String
'        Dim B As Boolean
'        Dim ErrorText As String
'
'        URL = "http://www.cpearson.com/Zips/FindAll.zip"
'        LocalFileName = "C:\Test\FindAll.zip"
'        B = DownloadFile(UrlFileName:=URL, _
'                        DestinationFileName:=LocalFileName, _
'                        Overwrite:=OverwriteRecycle, _
'                        ErrorText:=ErrorText)
'        If B = True Then
'            Debug.Print "Download successful"
'        Else
'            Debug.Print "Download unsuccessful: " & ErrorText
'        End If
'
' The Overwrite parameter of DownloadFile indicates how to handle the
' case when LocalFileName already exists. It is one of the following
' values:
'        OverwriteKill      use Kill to delete the existing file.
'        OverwriteRecycle   send the existing file to the Recycle Bin.
'        DoNotOverwrite     do not overwrite and terminate the procedure.
'        PromptUser         prompt the user asking whether to overwrite file.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


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

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Windows API functions, constants,and types.
' Used for RecycleFile.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

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

'''''''''''''''''''''''''''
' Download API function.
''''''''''''''''''''''''''''''''''''''

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


메인 프로시져

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' DownloadFile
' This downloads a file from a URL to a local filename.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

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 = 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
' Or
        .fFlags = FOF_ALLOWUNDO + FOF_NOCONFIRMATION
    End With

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

'VBA' 카테고리의 다른 글

폴더 선택을 위한 구문  (0) 2011.03.01
Static 변수를 자료맵핑에 활용  (0) 2010.06.16
엑셀에서 소리내기  (0) 2010.06.11
엑셀로 드래곤 커브 만들기  (0) 2009.11.13
스도쿠 100개 풀기  (0) 2009.08.14