Excel - VBA

VBA Module Source Backup Tool

EGTools 2024. 6. 8. 13:10
728x90

VBA Project를 많이 진행하면  각각의 프로젝트별로 또 각 버전별로 소스코드를 백업하는 게 일입니다.

그래서 소스코드 백업을 자동화 해 봅니다.

 

먼저 필요한 개체용 변수 및 상수를 지정합니다.

 

만약 VBA 편집기에서 외부 참조로 "Microsoft Visual Basic for Application Extensibility 5.3"를 지정한 경우

아래 Private Const 로 지정된 라인들은 필요하지 않습니다.

Private XL As Object
Private WB As Object
Private ProjectVersion As String

Private Const vbext_pp_locked As Integer = 1
Private Const vbext_ct_StdModule As Integer = 1
Private Const vbext_ct_ClassModule As Integer = 2
Private Const vbext_ct_MSForm As Integer = 3
Private Const vbext_ct_Document As Integer = 100

 

 

먼저 백업할 프로젝트를 지정하도록 합니다.

이미 열려 있는 프로젝트일수도 있고, 닫혀 있는 매크로 파일일 수 도 있어서 구분하여 처리합니다.

암호가 없거나, VBA 에디터 화면에서 암호가 입력되어 Open 된 상태가 되어야 정상 진행이 됩니다.

Private Function SelectProject()
    Dim sPath As String, sFullName As String, bThisProject As Boolean
    Dim oPRJ As Object
    
    Set XL = Application
    
    Select Case MsgBox("현재 Workbook을 진행할까요?" & vbNewLine & "파일을 선택하려면 '아니오/No'를 선택하세요.", vbYesNoCancel + vbDefaultButton1 + vbInformation)
    Case vbYes
        Set WB = ActiveWorkbook
        Set oPRJ = WB.VBProject
        bThisProject = True

        If oPRJ.Protection = vbext_pp_locked Then
            MsgBox "이 파일은 VBA Project가 보호되어 있으므로 진행할 수 없습니다." _
                   & vbNewLine & "먼저 VBA Project의 암호를 해제하고 진행하세요." _
                   & vbNewLine & WB.fullName
        End If
    Case vbNo
        sFullName = XL.GetOpenFilename(Title:="매크로파일", fileFilter:="Excel Macro File(*.xlsm;*.xlam;*.xlsb;*.xls),*.xlsm;*.xlam;*.xlsb;*.xls")
        If sFullName = "False" Or sFullName = "" Then Exit Function
    
        Set WB = XL.Workbooks.Open(fileName:=sFullName)
    Case vbCancel
        SelectProject = False
        Exit Function
    End Select
    
    Set oPRJ = WB.VBProject
    If oPRJ.Protection = vbext_pp_locked Then
        MsgBox "VBA Project가 보호되어 있으므로 진행할 수 없습니다." _
               & vbNewLine & "먼저 VBA Project의 암호를 해제하고 진행하세요." _
               & vbNewLine & WB.fullName
        If Not bThisProject Then
            WB.Close False
            Set WB = Nothing
            Set XL = Nothing
        End If
    End If
    
    Set oPRJ = Nothing
    
End Function

 

프로젝트가 지정이 되면, 각각의 모듈 Type을 확인하여 내보내기 할 이름을 지정합니다.

Private Sub BackUpModulesAndSheets()
    Dim oPRJ As Object, oMod As Object, oCOD As Object
    Dim sPath As String, sFileName As String
    Dim sExt As String, vLines As Variant, sContents As String
    Dim bAlert As Boolean, bScreen As Boolean

    Set oPRJ = WB.VBProject
    sPath = WB.Path & XL.PathSeparator & "Sources"
    If Dir(sPath, vbDirectory) = "" Then MkDir sPath
    sExt = oPRJ.Description
    If InStr(sExt, "(") = 0 Then sExt = oPRJ.Name
    sExt = Split(sExt, "(")(UBound(Split(sExt, "(")))
    ProjectVersion = Trim(Replace(Replace(sExt, ")", ""), ".", "_"))
    
    sPath = sPath & XL.PathSeparator & Replace(ProjectVersion, ".", "")
    If Dir(sPath, vbDirectory) = "" Then MkDir sPath
    
    For Each oMod In oPRJ.VBComponents
        If Dir(sPath, vbDirectory) = "" Then MkDir sPath
        Select Case oMod.Type
        Case vbext_ct_ClassModule:  sExt = ".cls"
        Case vbext_ct_Document:     sExt = ".cls"
        Case vbext_ct_MSForm:       sExt = ".frm"
        Case vbext_ct_StdModule:    sExt = ".bas"
        Case Else: MsgBox "Unknown Module Type": Exit Sub
        End Select
        If oMod.CodeModule.CountOfLines > 1 Then oMod.Export sPath & XL.PathSeparator & oMod.Name & sExt
    Next oMod
    
    WB.Worksheets.Copy
    bAlert = XL.DisplayAlerts
    XL.DisplayAlerts = False
    ActiveWorkbook.SaveAs sPath & XL.PathSeparator & "Sheets.xlsx", , , , , , , xlLocalSessionChanges
    ActiveWorkbook.Close
    XL.DisplayAlerts = bAlert
    WB.Activate
    
    Set oCOD = Nothing
    Set oMod = Nothing
    Set oPRJ = Nothing
End Sub

 

최종적으로 리본메뉴에서 사용할 Callback 함수를 작성합니다.

Sub BackupVBA(ctrl As IRibbonControl)
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    SelectProject
    If WB Is Nothing Then Exit Sub
    BackUpModulesAndSheets
    
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
    MsgBox "VBA Module을 백업했습니다."
End Sub

 

 

리본메뉴는 아래와 같이 CustomUI를 작성하여 추가기능에서 사용할 수 있도록 합니다.

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon startFromScratch="false">
<tabs>
  <tab id="tabVBA" label="EGVBATools">
    <group id="grProject">
      <button id="PRJ01" label="Backup Project" imageMso="B" size="large" onAction="BackupVBA" supertip="VBA Module을 백업합니다" />
    </group>
</tab>
</tabs>
</ribbon>
</customUI>

 

 

VBA소스 파일

VBAProjectBackup.bas
0.00MB

 

 

같은 소스로 추가기능으로 만든 파일

EGVBATools.xlam
0.02MB

 

728x90