본문 바로가기
  • 반가워요 : )
엑셀

엑셀 vba 폴더 파일 관리 기본 문법 정리

by 교육의 기울기 2024. 11. 17.
반응형

 

엑셀에서는 새로운 엑셀파일을 열고, 데이터를 저장하고, 옮길수있다. 또한 데이터를 텍스트로도 저장할수있다. 여기서는 엑셀의 vba를 이용해서 파일을 열고, 제어하는 몇가지 기본사항에 대해서 설명하고자 한다. 여기서 배울 몇가지 필요한 명령어는 다음과 같다.

 

목차

     

    Dir로 파일유무 체크해보기

    아래의 코드는 Dir을 이용해서 파일의 유무를 체크하는 간단한 코드이다. Dir은 경로를 분석해서, 해당 경로의 폴더나, 파일을 문자열 형식으로 반환한다. 만약 파일이나 폴더가 없을경우 빈 문자열 ("")을 반환하게 된다.

     

    아래 코드는 Northwind.mdb라는 파일 경로를 Dir명령어를 이용해 파일명을 문자열로 반환시켰다. 그리고 반환된 파일명을 메세지 박스로 팝업시켰고, 찾는 파일이 없다면,  메세지를 팝업시킨다.

     

    Dir의 속성은 여러가지가 있는데 vbnormal이 디폴트 값으로, 파일이름을 가져오게된다. vbDirectory는 폴더명을 가져오게된다. 그 외의 것은 아래 링크를 참조하면 찾을수있다.

     

    Dir function (Visual Basic for Applications)

    Office VBA reference topic

    learn.microsoft.com


    Option Explicit
    
    Sub 파일유무체크()
    'Dir은 경로를 사용하고, 해당 경로의 폴더명이나, 파일명을 반환한다.
    '만약 해당 경로가 존재하지않으면 "" 빈값을 반환한다.
    '옵션은 다음과 같이 사용가능
    
    ' vbNormal(0) : 디폴트값, 파일이름
    ' vbReadOnly(1) : 읽기 전용파일
    ' vbHidden(2) : 숨김파일
    ' vbSystem(4) : 시스템 파일
    ' vbDirectory(16) : 폴더, 디렉토리
    
    
    Dim path As String  'Dir 로 파일을 찾으면 해당 결과가 문자열임
    Dim FileChk As String
    
    path = "C:\Users\ddfg\Desktop\Northwind.mdb"
    
    FileChk = VBA.FileSystem.Dir(path, vbNormal)
    '만약에 위의 경로에 있는 파일이 없다면, FileChk은 "빈값"을 받음
    
    If FileChk = VBA.Constants.vbNullString Then
        MsgBox "파일이 존재하지않습니다."
    Else
        MsgBox FileChk
    End If
    
    End Sub

    와일드 카드로 모든 파일 찾아보기

    이전 코드에서는, 특정 파일명을 찾았더라면, 이번코드는 와일드카드를 이용해서 여러가지 파일을 특정형식에 맞추어서 찾을수있다. (와일트카드 =" * ") 다음 예시를 보자.

    • WildPath1 = "C:\Users\ddfg\Desktop\*" ' 모든 파일을 찾는다.
    • WildPath2 = "C:\Users\ddfg\Desktop\????" ' 4글자 파일을 전부찾는다.

    위 예시에서 WildPath1 이라는 변수에 들어간 경로는, Desktop아래에있는 모든 파일을 말한다.

    WildPath2는 Desktop 아래에있는 네글자파일을 말한다.

     

    위예시를 머리속에 생각하고 아래 코드를 읽어보면, 해당 파일경로에 맞는 파일이 있는지 체크하는 코드라는것을 알수있다.  와일드 카드에대해서 더 자세히 알고싶다면 아래 링크를 참조해보자.

     

    Wildcard Characters used in String Comparisons

    Office VBA reference topic

    learn.microsoft.com


    Sub 파일유무체크_와일드카드()
    
    Dim WildPath1 As String
    Dim WildPath2 As String
    Dim FileChk As String
    
    WildPath1 = "C:\Users\ddfg\Desktop\*" ' 모든 파일을 찾는다.
    WildPath2 = "C:\Users\ddfg\Desktop\????" ' 4글자 파일을 전부찾는다.
    
    FileChk = VBA.FileSystem.Dir(WildPath2, 0)
    '만약에 위의 경로에 있는 파일이 없다면, FileChk은 "빈값"을 받음
    
    If FileChk = VBA.Constants.vbNullString Then
        MsgBox "파일이 존재하지않습니다."
    Else
        MsgBox FileChk
    End If
    
    End Sub

    Dir로 폴더유무 체크후, 없을시 Mkdir로 폴더만들기

    Dir에서  vbDirectory를 사용하면 폴더명을 가져오게된다. 위에서 코드들과 비슷하나, 여기서 차이점은 파일이 아니라, 폴더의 유무를 체크한다는것이고, 만약 폴더가 없으면, Mkdir이라는 명령어를 이용해서 폴더를 생성하게 된다. 

    Sub 폴더찾기()
    
    Dim FolderPath As String
    Dim PathChk As String
    Dim Answer As VbMsgBoxResult
    
    
    FolderPath = "C:\Users\ddfg\Desktop\domini"
    PathChk = VBA.FileSystem.Dir(FolderPath, vbDirectory)
    
    If PathChk = VBA.Constants.vbNullString Then
        Answer = MsgBox("폴더 경로가 존재하지않습니다. 경로를 생성하시겠습니까?", vbYesNo, "폴더생성")
            Select Case Answer
             Case vbYes
                VBA.FileSystem.MkDir (FolderPath)
             Case Else
                Exit Sub
            End Select
    End If
    
    MsgBox "폴더가 존재합니다."
    
    End Sub

     


    GetOpenFilename 을 이용해서 파일 경로를 가져오기.

    GetOpenFilename을 이용하면, 파일을 직접 선택할수있다. 그리고 선택한 경로를 변수에 저장한다. 아래코드는 엑셀 워크북경로를 하나 가져와서, 해당 파일을 열수있는 코드이다. 

    GetOpenFilename은 필수속성이 하나도 없기때문에, 실행하면 바로 실행이된다, 그외 옵션이되는 속성들은 몇가지 있는데, 거기서 자주 쓰는것은 Title, FileFilter이다.  Title은 아래에 있는 코드를 참조하면된다. 그리고 FileFilter는 아무속성도 선택하지 않으면, 기본적으로 모든파일을 선택하게된다. 

     

    FileFilter를 사용하는건 다음코드를 참조하자.

    filepath = Application.GetOpenFilename(FileFilter:="PDF 파일 (*.pdf),*.pdf")

    위에서  파일필터를 할때는 두가지 문자열을 사용하게된다. 처음에 PDF파일(*.pdf)라고 되어있는건 팝업되는 박스에서 볼수있는 부분이고, *.pdf는 실제로 필터링해줄 파일의 속성들을 말하는것이다. 

    실제로 박스를 열었을떄 pdf파일이 필터링된다.


    -. 엑셀파일열기 코드

     Sub 엑셀파일열기()
     
     'GetOpenFilename 어플리케이션을 이용해서 파일을 가져온다.
     
     
       Dim filepath As Variant
       Dim OpenBook As Workbook
    
        filepath = Application.GetOpenFilename(Title:="파일선택하기", FileFilter:="엑셀 파일 (*.xlsx),*.xlsx")
    
        If filepath <> False Then
            Set OpenBook = Application.Workbooks.Open(filepath)
            'OpenBook.Close False
        End If
     End Sub

    -. PDF파일을 열수있는 코드

     Sub PDF파일열기()
        Dim filepath As Variant
        filepath = Application.GetOpenFilename(FileFilter:="PDF 파일 (*.pdf),*.pdf", Title:="PDF 파일 선택하기")
        
        If filepath <> False Then
            ' PDF 파일 기본 프로그램으로 열기
            Shell "explorer.exe """ & filepath & """", vbNormalFocus
        Else
            MsgBox "PDF 파일을 선택하지 않았습니다."
        End If
    End Sub

    -. 이미지파일을 열수있는 코드

    Sub 이미지파일열기()
        Dim filepath As Variant
        filepath = Application.GetOpenFilename(FileFilter:="이미지 파일 (*.jpg;*.jpeg;*.png;*.bmp),*.jpg;*.jpeg;*.png;*.bmp", Title:="이미지 파일 선택하기")
        
        If filepath <> False Then
            ' 이미지 파일 기본 프로그램으로 열기
            Shell "explorer.exe """ & filepath & """", vbNormalFocus
        Else
            MsgBox "이미지 파일을 선택하지 않았습니다."
        End If
    End Sub

    -. 텍스트 파일을 열수있는 코드

    Sub 텍스트파일열기()
        Dim filepath As Variant
        Dim FileNum As Integer
        Dim FileContent As String
        
        filepath = Application.GetOpenFilename(FileFilter:="텍스트 파일 (*.txt),*.txt", Title:="텍스트 파일 선택하기")
        
        If filepath <> False Then
            FileNum = FreeFile
            Open filepath For Input As #FileNum
            FileContent = Input$(LOF(FileNum), FileNum)
            Close #FileNum
            
            MsgBox "파일 내용: " & vbCrLf & FileContent
        Else
            MsgBox "텍스트 파일을 선택하지 않았습니다."
        End If
    End Sub




    참고로 Filepath라는 변수는 variant로 할당하는데, 이는 다음과 같은 이유가있다.   

     파일 선택창이 열리고, open을 누르면 해당파일 경로가 변수에 할당된다. 반대로 close를 누르면 False가 할당된다. 여기서 False는 불리안인데, 만약 해당변수를 String으로 만들었다면, String데이터 타입으로 보게된다.
    때문에 이 변수를 선언할때 데이터 타입은 Variant로 해줘야한다. (variant데이터타입은 유동적이다)

    GetOpenFilename으로 여러 타입 파일을 한번에 열어 보기

    아래코드는 여러개의 엑셀파일을 선택했을때, 모두 열어주는 코드이다. 여러개를 선택하면, 선택된 파일들이 FileToOpen에 배열형태로 저장되기때문에, 반복문을 써서 배열의 순서대로 엑셀파일을 열어준다.


    Sub Select_Many_Files()
      
      '여러개의 엑셀파일 선택해서 열기.
      Dim FileToOpen As Variant
      Dim FileCnt As Byte
      Dim SelectedBook As Workbook
        'Pick the files to import - allow multiselect
        FileToOpen = Application.GetOpenFilename(Filefilter:="Excel Files (*.xlsx), *.xlsx", Title:="Select Workbook to Import", MultiSelect:=True)
            
       If IsArray(FileToOpen) Then
          For FileCnt = 1 To UBound(FileToOpen)
            Set SelectedBook = Workbooks.Open(Filename:=FileToOpen(FileCnt))
            'SelectedBook.Close
          Next FileCnt
        End If
    End Sub

     

    아래코드는 여러개의 파일을 한꺼번에 열수있는 코드이다. 또한 여러개의 파일타입을 처리할수있다. 여기에 쓰여지지않은 파일타입은 따로 추가를 해주어야 한다.


    Sub Select_Multiple_Files()
        Dim FileToOpen As Variant
        Dim FileCnt As Integer
        Dim FileExt As String
        
        ' 여러 파일 형식을 선택할 수 있도록 필터 설정
        FileToOpen = Application.GetOpenFilename( _
            FileFilter:="Excel Files (*.xlsx;*.xls),*.xlsx;*.xls," & _
                        "PDF Files (*.pdf),*.pdf," & _
                        "Image Files (*.jpg;*.jpeg;*.png;*.bmp),*.jpg;*.jpeg;*.png;*.bmp," & _
                        "Text Files (*.txt),*.txt," & _
                        "All Files (*.*),*.*", _
            Title:="Select Files to Open", MultiSelect:=True)
        
        ' 파일을 선택하지 않은 경우 종료
        If Not IsArray(FileToOpen) Then
            MsgBox "파일을 선택하지 않았습니다.", vbExclamation
            Exit Sub
        End If
        
        ' 선택한 파일들을 하나씩 처리
        For FileCnt = LBound(FileToOpen) To UBound(FileToOpen)
            FileExt = LCase(Mid(FileToOpen(FileCnt), InStrRev(FileToOpen(FileCnt), ".") + 1)) ' 파일 확장자
            
            Select Case FileExt
                Case "xlsx", "xls" ' 엑셀 파일
                    Dim wb As Workbook
                    Set wb = Workbooks.Open(Filename:=FileToOpen(FileCnt))
    
                    ' 필요에 따라 추가 작업 수행
                    ' wb.Close False ' 파일 닫기
                
                Case "pdf" ' PDF 파일
                    Shell "explorer.exe """ & FileToOpen(FileCnt) & """", vbNormalFocus
    
                    
                Case "jpg", "jpeg", "png", "bmp" ' 이미지 파일
                    Shell "explorer.exe """ & FileToOpen(FileCnt) & """", vbNormalFocus
    
                    
                Case "txt" ' 텍스트 파일
                    Dim FileNum As Integer
                    Dim FileContent As String
                    FileNum = FreeFile
                    Open FileToOpen(FileCnt) For Input As #FileNum
                    FileContent = Input$(LOF(FileNum), FileNum)
                    Close #FileNum
    
                    
                Case Else ' 그 외 파일
                    MsgBox "지원되지 않는 파일 형식: " & FileToOpen(FileCnt), vbExclamation
            End Select
        Next FileCnt
    End Sub

    FileDialog로 폴더탐색하기

    FileDialog와 GetOpenFilename은 VBA에서 파일 선택 대화상자를 표시할 때 사용되지만, 기능과 사용 방식에서 몇 가지 차이가 있다. 아래 표에서 그것을 요약해본다. 

    특징 FileDialog
    GetOpenFilename
    사용 방식 객체( FileDialog ) 기반 함수 기반
    파일/폴더 선택 파일과 폴더 모두 선택 가능 ( FolderPicker )
    파일만 선택 가능
    다중 선택 지원 지원 ( AllowMultiSelect = True )
    지원 ( MultiSelect:=True )
    반환값 SelectedItems 컬렉션 (목록)
    선택한 파일 경로(문자열/배열)
    사용자 정의 옵션 다양한 옵션 및 필터 제공
    제한된 필터 설정
    참조 라이브러리 Microsoft Office xx.x Object Library 필요 필요 없음
    UI 사용자 정의 가능 불가능

     

    FileDialog의 특징이라고하면, 해당 명령어는 폴더를 선택할수도있고, 파일을 선택할수있다는 것이다.

    해당 명령어는 필수속성을 한가지만 넣으면 되는데, 다음 네가지와 같다.

    • msoFileDialogFilePicker. 파일선택가능
    • msoFileDialogFolderPicker. 폴더선택가능
    • msoFileDialogOpen. 파일오픈가능
    • msoFileDialogSaveAs. 파일 저장가능

    또한, 해당 코드로 가져온 경로는 SelectedItems 라는 곳에 저장되게되는데, 아래의 코드를 보면 이해가 쉬울것이다.

    FileDialog로 가져온 경로를 SelectedItems에 저장하고, 이를 path에 대입하였다.


    Sub loopFolder()
    '폴더내의 파일 전부 확인하기
    
    Dim path As String
    Dim Filetolist As String
    
    
    With Application.FileDialog(msoFileDialogFolderPicker)
            .Title = "폴더를 선택하세요"
            .ButtonName = "선택"
            If .Show = 0 Then
                MsgBox "아무폴더도 선택되지않았습니다."
                Exit Sub
            Else
                path = .SelectedItems(1) & "\"
                MsgBox "특정폴더가 선택되었습니다." & path
            End If
    End With
    
    Filetolist = Dir(path & "*")
    ' 해당폴더에서 첫번째 파일을 불러온다.
    
    Do Until Filetolist = ""
    
    MsgBox Filetolist
    Filetolist = Dir
    
    Loop
    ' 그 다음에 차례대로 불러온다.dir만 사용하는 이유는 아래와 같다.
    'Dir returns the first file name that matches pathname.
    'To get any additional file names that match pathname,
    'call Dir again with no arguments.When no more file names match, '
    'Dir returns a zero-length string (""). After a zero-length string is returned,
    'you must specify pathname in subsequent calls, or an error occurs.
    
    End Sub

    그리고 다음코드는 여러가지 파일을 한꺼번에 선택하고, 그 파일을 하나하나 메세지박스로 띄워주는 코드이다.

    코드를 보면 SelectedItems를 count하는걸 볼수있는데, 이를 보면, 경로를 전부 여기에 저장한다는것을 알수있다.

    Sub UseFileDialogOpen()
     
        Dim lngCount As Long
     
        ' Open the file dialog
        With Application.FileDialog(msoFileDialogOpen)
            .AllowMultiSelect = True
            .Show
     
            ' Display paths of each file selected
            For lngCount = 1 To .SelectedItems.Count
                MsgBox .SelectedItems(lngCount)
            Next lngCount
     
        End With
     
    End Sub

    vba Open statement 

    Open statement는 VBA에서 파일을 열고 데이터를 읽거나 쓰는 데 사용하는 명령어입니다. 파일을 열 때는 해당 파일이 어떻게 사용될지를 지정하는 모드(예: 읽기 전용, 쓰기 전용 등)를 설정해야 합니다.

     

    Open pathname For mode [Access access] [lock] As [#]filenumber [Len=reclength]

    여기서 pathname은 반드시 지정해주어야합니다.그리고 mode는 읽기모드냐, 쓰기모드냐에 따라 달라집니다.  

    filenumber는 1~255까지 임의로 정해주시면됩니다. 아래 코드는 쓰기모드로 텍스트파일에 텍스트를 쓴 코드입니다.

     


    Sub writefile()
    '텍스트파일에 데이터 쓰기
    Dim Filename As String
    Filename = "C:\Users\ddfg\Desktop" & "\Project2.csv"
    Open Filename For Output As #1
        Print #1, Range("A1").Value
        Write #1, Range("A1").Value
        Print #1, "Print line1 "
        Write #1, "Print line2 "
        Print #1, 1
        Print #1, 2
    Close #1
    
    End Sub

     

    vba로 csv파일로 변환하기 (Workbook.Save as)

    엑셀파일을 다른형식으로 저장하고싶을때, Saveas를 사용하면 변환할수있다.

    아래코드는 기존에 있는 워크북의 시트데이터를 새로운 워크시트를 열어 복사하고, 다른이름으로 csv파일로 저장하는 코드이다. 


    Sub csvSaveas()
    'csv파일로 저장하기
    '엑셀 워크북을 다른 형식으로 저장하는 방법
    Dim NewWB As Workbook
    Dim Filenameset As String
    
    '파일 경로와, 파일의 이름을 사전에 설정
    Filenameset = Application.ThisWorkbook.path & "\TestFile.csv"
    
    '새로운 워크북을 오픈하고 현재 워크북의 시트를 복사붙여넣기
    Set NewWB = Workbooks.Add
    Sheet8.Copy Before:=NewWB.Sheets(1)
    
    '새로운 워크북의 첫번째시트 1~3행 삭제
    NewWB.Sheets(1).Rows("1:3").Delete
    NewWB.SaveAs Filename:=Filenameset, FileFormat:=Excel.xlCSV
    NewWB.Close
    
    MsgBox "csv파일이 현재 워크북의 경로에 저장되었습니다"
    End Sub

     

    위에서  파일을 저장할때, csv파일형식으로 저장하는데, 위데이터 형식은 아래 링크를 참고하면 나온다. csv파일은 xlCSV라고저장할수있다.

     

     

    XlFileFormat enumeration (Excel)

    Office VBA reference topic

    learn.microsoft.com

     

     

    참고로 위의 파일형식을 사용할때, csv파일 뿐만아니라, docx, ppt, 등을 넣어도 실행되며, 워드, 파워포인트로 열린다.

    자신의 필요여하게 따라서 위의 코드는 유용하게 사용될수있을듯하다.

     

    그외 참고사항

    위에서 사용한 코드중에 특이한것을 따져본다면 다음과 같은 것들이 있다.

     

    vba Constants

     

    Miscellaneous constants

    Office VBA reference topic

    learn.microsoft.com

    shell

     

    Shell function (Visual Basic for Applications)

    Office VBA reference topic

    learn.microsoft.com

     

    반응형

    댓글