Excel - VBA

VBA로 ZIP과 UnZip

EGTools 2023. 8. 27. 23:53
728x90

Excel 파일인 xlsx, xlsm, xlam, xlsb 등은 모두 기본적으로 Zip파일 형식으로 저장된 파일입니다.

그래서 확장자를 zip으로 바꾸면 파일 내부 구조를 볼 수 있습니다.

물론 읽기 암호를 설정한 경우에는 ZIP파일에 암호를 걸어 둔 것처럼 안을 볼 수 없습니다.

 

이 파일을 압축해제하면 몇 가지 유용한 처리를 할 수 있습니다.

이 때 사용하기 위한 UnZip과 Zip 소스코드 입니다.

 

UnZip 소스이고, 이 함수는 압축이 해제된 폴더 Path를 반환합니다.

Function Unzip(ZipName As Variant) As String
    Dim UnZipFolder As Variant, BasePath As String
    Dim FSO As Object: Set FSO = CreateObject("Scripting.FileSystemObject")

    If Dir(ZipName) = vbNullString Then GoTo ERROR_RUN

    BasePath = FSO.GetParentFolderName(ZipName)
    UnZipFolder = BasePath & "\" & FSO.GetBaseName(ZipName) '& "_x"
    UnZipFolder = Replace(UnZipFolder, "\\", "\")

    If Right(UnZipFolder, 1) = "\" Then UnZipFolder = Left(UnZipFolder, Len(UnZipFolder) - 1)
    If FSO.FolderExists(UnZipFolder) Then
        FSO.DeleteFolder UnZipFolder, True
        Do While FSO.FolderExists(UnZipFolder)
            Application.Wait (Now + TimeValue("00:00:01"))
        Loop
    End If
    
    MkDir UnZipFolder
    Dim oApp As Object: Set oApp = CreateObject("Shell.Application")
    
    oApp.Namespace(CStr(UnZipFolder)).CopyHere oApp.Namespace(CStr(ZipName)).Items

    Unzip = UnZipFolder

EXIT_RUN:
    Set FSO = Nothing
    Set oApp = Nothing
    
    Exit Function
    
ERROR_RUN:
    Unzip = "ERROR: File not found "
    GoTo EXIT_RUN
    
End Function

 

그리고 특정 폴더를 Zip파일로 압축하는 Zip_Folder이고, 이 함수는 압축 파일의 Path를 반환합니다.

Function Zip_Folder(FolderName As Variant) As String
    Dim FileNameZip
    Dim oApp As Object

    On Error GoTo ERROREND
    FileNameZip = FolderName & ".zip"

    Set oApp = CreateObject("Shell.Application")

    If Len(Dir(FileNameZip)) > 0 Then Kill FileNameZip
    Open FileNameZip For Output As #1
    Print #1, Chr$(80) & Chr$(75) & Chr$(5) & Chr$(6) & String(18, 0)
    Close #1
    
    If Right(FolderName, 1) <> "\" Then FolderName = FolderName & "\"

    oApp.Namespace(CStr(FileNameZip)).CopyHere oApp.Namespace(CStr(FolderName)).Items

    On Error Resume Next
    Do Until oApp.Namespace(CStr(FileNameZip)).Items.Count = oApp.Namespace(CStr(FolderName)).Items.Count
        Application.Wait (Now + TimeValue("0:00:01"))
    Loop

    Zip_Folder = CStr(FileNameZip)
    Set oApp = Nothing
    Exit Function
    
ERROREND:
    Zip_Folder = "ERROR:" & Err.Description
    Set oApp = Nothing
    
End Function

 

파일 내부에 위치한 정보를 조작하여 아래와 같은 작업을 할 수 있습니다.

- 삽입된 그림을 추출하기

- 보호된 Workbook의 보호를 해제하기

- 보호된 WorkSheet의 보호를 해제하기

- 보호된 VBA Project의 보호를 해제하기

  (이건 좀 복잡한 Compound Binary File의 처리가 필요하고, 해제라기 보다는 알 수 있는 암호로 대체...)

 

 

728x90