지난 글에서는 아스키 파일(텍스트 파일)을 시트에 불러오는 함수(LoadTextFile)를 작성했습니다. 이 함수에는 대상 파일명과 불러오고자 하는 시트, 인코딩 등의 정보를 입력하였을 때 작동하는 함수입니다.
오늘은 실제로 사용자가 활용할 수 있도록 Sub 프로시저를 작성하려고 합니다.
실제 Sub 프로시저를 작성하기 전에 함수를 2개 더 작성하려고 합니다. 바로 새로운 워크시트를 만들기 위해 워크시트의 이름을 지정해주는 함수와 불러올 파일명에서 경로와 확장자를 삭제하는 함수입니다.
첫번째 함수가 필요한 이유는.. 엑셀에서 워크시트를 삽입하도록 하면, 자동으로 Sheet1, Sheet2, ... 와 같이 시트명을 붙여줍니다만, 여러 개의 파일을 불러올 때, 이런 이름이 붙어있으면 어떤 파일을 불러왔는지 알 수가 없습니다. 따라서, 시트명을 기왕이면 불러온 파일명으로 지정해주면 해당 시트가 어떤 파일을 불러왔는지 쉽게 알 수 있기 때문이지요.
물론, 이런 함수 없이, 파일을 다 로딩한 후, Cells(1,1)에 파일명을 삽입해주는 방법도 있습니다만, 여러개의 시트가 있을 때, 특정 파일로 접근하려면 일일이 시트를 클릭해봐야하니 그만큼 사용자 입장에서는 불편하기 때문이지요.
새로운 시트를 삽입할 때, 시트명은 아래와 같이 만들어줍니다.
----------------------------------
Function NewSheetName(iName As String, iShIndex As Long, Optional iCount As Long = -1) As String
'새로운 시트명의 기본이름과 새로 작성하려는 시트의 인덱스, 그리고 혹시 중복되는 시트명이 있다면 시트명 뒤에 숫자로 구분할 수 있도록 시작값을 지정합니다. 만일, 시트명을 "ABC"라고 하고, 새로운 시트가 해당 워크북의 5번째 시트이며, 중복되었을 때, 1부터 시작하겠다고 한다면, NewSheetName("ABC", 5, 1)과 같이 입력합니다.
Dim i As Long, j As Long
If iName = "" Then
tiName = "Sheet"
Else
tiName = iName
End If
If iCount < 0 Then
j = 0
tName = tiName
Else
j = iCount
tName = tiName & j
End If
For i = 1 To ActiveWorkbook.Sheets.Count
If tName = ActiveWorkbook.Sheets(i).Name And iShIndex <> i Then
j = j + 1
tName = tiName & j
i = 0
End If
Next
If Len(tName) > 31 Then
NewSheetName = NewSheetName(Left(tiName, Len(tiName) - 1), iShIndex, iCount)
Else
NewSheetName = tName
End If
End Function
On Error GoTo ErrorHandler
Dim tStr As String, tSplit
tSplit = Split(iStr, "\")
tStr = tSplit(UBound(tSplit))
If InStr(tStr, ".") > 0 Then
tSplit = Split(tStr, ".")
GetShortFileName = Left(tStr, Len(tStr) - Len(tSplit(UBound(tSplit))) - 1)
Else
GetShortFileName = tStr
End If
ErrorHandler:
------------------------------------------------------
다음으로는 실제 사용자가 쓰게되는 Sub 프로시저를 작성하도록 하겠습니다. 필요한 함수를 미리 다 만들어두었기 때문에 Sub 프로시저는 그다지 길지 않습니다.
================================
On Error GoTo ErrorHandler
Dim tFN(), tStr As String, tWB1 As Workbook, tWB2 As Workbook, tSh As Worksheet, tSh2 As Worksheet
Set tSh = tWB1.Sheets(ActiveWorkbook.Sheets.Count)
For i = LBound(tFN) To UBound(tFN)
tFName = tFN(i)
tFExt = LCase(tFSO.GetExtensionName(tFName))
Select Case tFExt
Case "xls", "xlt", "xla", "xlm", "xlw", "xlb", "xlsx", "xlsm", "xlsb", "xltx", "xltm", "xlam"
Set tWB2 = Workbooks.Open(tFName)
For j = 1 To tWB2.Sheets.Count
Set tSh2 = tWB2.Sheets(j)
If Not (tSh2.UsedRange.Rows.Count = 1 And tSh2.UsedRange.Columns.Count = 1 And tSh2.UsedRange.Cells(1, 1).Value = Empty) Then
Set tSh = tWB1.Worksheets.Add(After:=tSh)
tSh2.UsedRange.Copy tSh.Cells(1, 1)
tSh.Name = NewSheetName(tSh2.Name & "_" & GetShortFileName(tWB2.Name), tSh.Index)
tSh.Tab.Color = RGB(102, 255, 102)
End If
Next
tWB2.Close SaveChanges:=False
If n = 1 Then
Next
ErrorHandler:
Erase tFN
End Sub
================================
서로 구분자가 다른 데이터파일을 열 때에는 엑셀에서 지원하는 구분자를 모두 클릭해놓으면 됩니다. 예를 들어, 일부 파일은 구분자가 '탭'이고 일부 파일은 '쉼표'라고 한다면, 첫 아스키파일이 열릴 때 구분자를 탭과 쉼표를 모두 클릭해두면 됩니다. 다만, 구분자를 여러개 지정했을 때, 불필요하게 데이터가 분할되는 수도 있기 때문에 가급적 구분자가 동일한 파일들을 일괄적으로 열어주는 게 좋습니다.
저의 경우엔, 일련의 데이터들은 모두 동일한 형식으로 된 파일로 받기 때문에 불편함없이 쓸 수 있지만, 서로 형식이 다른 형식의 파일을 한꺼번에 열게 되면, 워크시트에서 또다시 수작업을 해야하는 수가 있으니 굳이 이러한 매크로를 사용할 필요가 없을 수도 있겠습니다. 혹은 개인별로 자주쓰는 파일 유형을 구분해서 워크시트들을 모아주는 기능을 만들 수도 있겠구요. 이러한 부분은 각 사용자들이 더 개발하시면 좋을 듯 합니다.
여기까지, 엑셀 또는 아스키 파일을 한꺼번에 여는 매크로였습니다. 다음엔 동일한 구조의 파일이 열린 상태에서 특정 영역만 추출하는 매크로를 작성해보도록 하겠습니다.
댓글 없음:
댓글 쓰기
의견이나 질문이 있으신 분은 언제든지 댓글을 달아주세요~