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

엑셀 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

 

반응형

댓글