어제 다음과 같은 프로그램을 짰더랬습니다.
https://gigglehd.com/gg/soft/379801
근데 자고 나서 일어나서 생각해 보니, 이 프로그램으로 원하는 파일을 찾는 건 좀 불편할 거란 생각이 들더군요. 그래서 좀 뜯어고치다가, 어째 잘 되지가 않아서 아예 갈아엎고 새로 원하는 대로 만들어 버렸습니다. 새 프로그램은 전처리 파일을 만들 필요 없이, 프로그램 내에서 디렉터리를 지정하면 자체적으로 DWG 파일을 찾게끔 바꾸었습니다.
새로 짠 프로그램은 다음과 같습니다.
Option Explicit '전역 변수 설정. Public dwgList As Collection Sub main() '필요 변수 등 설정. Dim dwgName As Variant Dim i As Long: i = 0 Dim readOnly As Boolean: readOnly = True Dim fileSystem As Object Dim hostFolder As String Dim outputFile As String Dim findingText As String Dim textList As Collection Set dwgList = New Collection '프로그램 시작 초기화 '프로그램 작동 설정. hostFolder = "T:\" outputFile = "T:\DWGfindResult.txt" findingText = "ASDF" ' 직접실행 창에 작업 시작을 알린다. Debug.Print "작업 1단계 개시." ' 각 디렉터리와 그 서브 디렉터리를 재귀적으로 순회한다. Set fileSystem = CreateObject("scripting.filesystemobject") doFolder fileSystem.getfolder(hostFolder) ' 직접실행 창에 작업 2단계 시작을 알린다. Debug.Print "" Debug.Print "작업 2단계 개시." ' 순회가 끝나면 경로 컬렉션의 모든 DWG 파일을 하나씩 열기 시작한다. For Each dwgName In dwgList Set textList = New Collection '초기화 - 버그 방지! ' 진행상황 파악을 위해 직접실행 창에 전체 DWG 파일 갯수와 _ ' 현재 열고 있는 DWG 파일 순서를 분수로 출력한다. i = i + 1 Debug.Print i & " / " & dwgList.Count On Error Resume Next '오류 발생시 넘어감 AutoCAD.Documents.Open dwgName, readOnly ' DWG 파일의 모든 텍스트 중 원하는 것이 있는지 찾는다. ' 원하는 텍스트가 포함된 텍스트 데이터를 텍스트 컬렉션에 추가한다. Set textList = dwgTextFind(findingText) ' 만약 텍스트 컬렉션의 카운트가 1 이상이면 현재 열린 파일명과 텍스트 컬렉션의 _ ' 모든 내용을 직접실행 창에 출력하고, 동시에 지정된 텍스트 파일에 추가한다. If textList.Count Then resultOutput outputFile, dwgName, textList End If ' 열린 DWG 파일을 닫는다. AutoCAD.Documents.Close ' 모든 DWG 파일에 이 작업을 반복한다. Next End Sub Sub doFolder(folder) '각 디렉터리와 서브 디렉터리를 재귀적으로 순회하기 위한 서브루틴. On Error Resume Next '오류 발생시 다음 폴더로 넘어감. Dim subFolder As Variant For Each subFolder In folder.subfolders doFolder subFolder Next ' 순회 과정에서 DWG 파일이 발견되면 경로 컬렉션에 경로를 추가한다. Dim file As Variant For Each file In folder.Files If LCase(file.Name) Like "*.dwg" Then dwgList.Add file.Path Debug.Print file.Path '화면에 출력 End If Next End Sub Function dwgTextFind(findingText) As Collection 'DWG 파일 내의 모든 텍스트에서 원하는 부분이 있는지 찾아, _ '조건이 맞는 모든 텍스트를 모은 컬렉션을 반환한다. Dim mSpaceObj As AcadObject Dim item As Variant Dim text As String Dim result As New Collection '한번에 선언 및 생성 - 초기화 For Each item In ThisDrawing.ModelSpace On Error Resume Next '텍스트 스트링이 없으면 그냥 지나감 text = "" '초기화 Set mSpaceObj = item text = mSpaceObj.TextString If InStr(LCase(text), LCase(findingText)) Then '대소문자 구분하지 않음! result.Add text End If Next Set dwgTextFind = result End Function Sub resultOutput(outputFile, dwgName, textList) '출력할 텍스트 파일명과 출력할 내용들을 받아서 _ '현재 열린 파일명과 검색된 스트링을 화면과 텍스트 파일에 출력하는 서브루틴. Dim fileNum As Integer Dim item As Variant fileNum = FreeFile() Open outputFile For Append As #fileNum '텍스트 파일을 추가 모드로 연다. Debug.Print dwgName Write #fileNum, dwgName For Each item In textList Debug.Print Chr(9) & item Print #fileNum, Chr(9); item Next Debug.Print "" '마지막에 빈 줄 추가 Write #fileNum, Close #fileNum End Sub
네. 이 프로그램은 잘 작동합니다. 적어도 제가 테스트한 한도 내에서는 말이죠.
하지만 왠지 제 실력 때문인지 뭔가 자꾸 부족하다는 생각이 드는군요. 굳이 dwgList
를 전역으로 쓸 필요가 있었을까? 오류 처리는 어떻게 하는 것이 더 좋을까? main
프로시저는 정말 저게 최선인가? 더 모듈화할 수 있지 않았을까? 이런 생각이 자꾸 드네요.
그래서 질문드립니다. 이 프로그램에서 부족한 부분은 무엇이고, 어떤 식으로 수정하는 것이 좋을까요? 여러분의 고견을 기다리겠습니다.