[excel] MS Excel 버전 관리를 수행하는 가장 좋은 방법

MS Excel (2003/2007)에서 어떤 버전 제어 시스템을 사용 했습니까? 무엇을 추천하고 왜 하시겠습니까? 최고 등급의 버전 관리 시스템에서 어떤 제한을 찾았습니까?

이를 관점에서 살펴보면 다음과 같은 두 가지 사용 사례가 있습니다.

  1. VBA 모듈의 버전 제어
  2. 둘 이상의 사람이 Excel 스프레드 시트에서 작업하고 있으며 병합 및 통합하려는 동일한 워크 시트를 변경하고있을 수 있습니다. 이 워크 시트에는 수식, 데이터, 차트 등이있을 수 있습니다.
  3. 사용자가 너무 기술적이지 않고 더 적은 버전 제어 시스템이 더 잘 사용됨
  4. 공간 제약이 고려됩니다. 이상적으로 전체 Excel 스프레드 시트가 아닌 증분 변경 사항 만 저장됩니다.


답변

방금 TortiseBZR을 통한 수동 체크인 / 아웃과 함께 Bazaar를 사용하는 스프레드 시트를 설정했습니다. 주제가 저장 부분에 도움이되었다는 것을 감안할 때 여기에 솔루션을 게시하고 싶었습니다.

나를위한 해결책은 저장시 모든 모듈을 내보내고 열린 모듈을 제거하고 다시 가져 오는 스프레드 시트를 만드는 것이 었습니다. 예, 기존 스프레드 시트를 변환 할 때 잠재적으로 위험 할 수 있습니다.

이를 통해 Emacs (예, emacs) 를 통해 또는 Excel에서 기본적으로 모듈의 매크로를 편집하고 주요 변경 후 BZR 저장소를 커밋 할 수 있습니다. 모든 모듈은 텍스트 파일이므로 BZR의 표준 diff 스타일 명령은 Excel 파일 자체를 제외하고 내 소스에서 작동합니다.

BZR 저장소의 디렉토리 인 X : \ Data \ MySheet를 설정했습니다. 리포지토리에는 MySheet.xls와 각 모듈에 대한 하나의 .vba 파일이 있습니다 (예 : Module1Macros). 내 스프레드 시트에서 “VersionControl”이라는 내보내기 / 가져 오기주기에서 제외 된 하나의 모듈을 추가했습니다. 내보내고 다시 가져올 각 모듈은 “매크로”로 끝나야합니다.

“VersionControl”모듈의 내용 :

Sub SaveCodeModules()

'This code Exports all VBA modules
Dim i%, sName$

With ThisWorkbook.VBProject
    For i% = 1 To .VBComponents.Count
        If .VBComponents(i%).CodeModule.CountOfLines > 0 Then
            sName$ = .VBComponents(i%).CodeModule.Name
            .VBComponents(i%).Export "X:\Tools\MyExcelMacros\" & sName$ & ".vba"
        End If
    Next i
End With

End Sub

Sub ImportCodeModules()

With ThisWorkbook.VBProject
    For i% = 1 To .VBComponents.Count

        ModuleName = .VBComponents(i%).CodeModule.Name

        If ModuleName <> "VersionControl" Then
            If Right(ModuleName, 6) = "Macros" Then
                .VBComponents.Remove .VBComponents(ModuleName)
                .VBComponents.Import "X:\Data\MySheet\" & ModuleName & ".vba"
           End If
        End If
    Next i
End With

End Sub

다음으로, 이러한 매크로를 실행하기 위해 열기 / 저장을위한 이벤트 후크를 설정해야합니다. 코드 뷰어에서 “ThisWorkbook”을 마우스 오른쪽 단추로 클릭하고 “코드보기”를 선택하십시오. 코드 창의 맨 위에있는 선택 상자를 아래로 당겨 “(일반)”보기에서 “워크 북”보기로 변경해야 할 수 있습니다.

“워크 북”보기의 내용 :

Private Sub Workbook_Open()

ImportCodeModules

End Sub

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

SaveCodeModules

End Sub

앞으로 몇 주 동안이 워크 플로에 정착 할 것이며 문제가있을 경우 게시 할 것입니다.

VBComponent 코드를 공유해 주셔서 감사합니다!


답변

TortoiseSVN 은 Subversion 버전 제어 시스템을위한 놀랍도록 훌륭한 Windows 클라이언트입니다. 방금 발견 한 기능 중 하나는 Excel 파일 버전간에 차이점을 얻으려면 클릭하면 Excel에서 두 버전을 열고 변경된 셀을 강조 표시합니다 (빨간색). 여기 에 설명 된 vbs 스크립트의 마법을 통해 수행 됩니다 .

TortoiseSVN을 사용하지 않더라도이 기능이 유용 할 수 있습니다.


답변

버전 관리를 원하는 이유와 이유를 요약하겠습니다.

  1. 뭐:

    • 코드 (VBA)
    • 스프레드 시트 (수식)
    • 스프레드 시트 (값)
    • 차트
  2. 왜:

    • 감사 로그
    • 협동
    • 버전 비교 ( “diffing”)
    • 합병

다른 사람들이 여기에 게시 한 것처럼 다음과 같은 기존 버전 제어 시스템 위에 몇 가지 솔루션이 있습니다.

  • 힘내
  • 수은제
  • 파괴
  • 바자

통합 문서의 VBA 코드가 유일한 관심사 인 경우 위의 Demosthenex 제안 또는 VbaGit ( https://github.com/brucemcpherson/VbaGit ) 방식은 매우 잘 작동하며 구현하기가 비교적 간단합니다. 장점은 입증 된 버전 제어 시스템에 의존하고 필요에 따라 하나를 선택할 수 있다는 것입니다 ( https://help.github.com/articles/what-are-the-differences-between-svn-and 참조) Git과 Subversion을 간단히 비교하려면 -git / ).

코드뿐만 아니라 시트의 데이터 ( “하드 코딩 된”값 및 수식 결과)에 대해 걱정할 경우 비슷한 전략을 사용할 수 있습니다. 시트의 내용을 일부 텍스트 형식 (범위. 값을 통해)으로 직렬화 기존 버전 관리 시스템을 사용하십시오. https://wiki.ucl.ac.uk/display/~ucftpw2/2013/10/18/Using+git+for+version+control+of+spreadsheet+models+-+part에 대한 아주 좋은 블로그 게시물이 있습니다. +1의 +3

그러나 스프레드 시트 비교는 사소한 알고리즘 문제입니다. Microsoft의 스프레드 시트 비교 ( https://support.office.com/en-us/article/Overview-of-Spreadsheet-Compare-13fafa61-62aa-451b-8674-242ce5f2c986 ), Exceldiff 와 같은 몇 가지 도구가 있습니다. http://exceldiff.arstdesign.com/ ) 및 DiffEngineX ( https://www.florencesoft.com/compare-excel-workbooks-differences.html ). 그러나 이러한 비교를 Git과 같은 버전 제어 시스템과 통합하는 것은 또 다른 과제입니다.

마지막으로 필요에 맞는 워크 플로우를 설정해야합니다. 간단하고 맞춤화 된 Git for Excel 워크 플로는 https://www.xltrail.com/blog/git-workflow-for-excel참조하십시오 .


답변

데이터에 대해 이야기하고 있는지 또는 스프레드 시트에 포함 된 코드에 따라 다릅니다. Microsoft의 Visual Sourcesafe를 강력하게 싫어하지만 일반적으로 권장하지는 않지만 Access 및 Excel과 쉽게 통합되며 모듈의 소스 제어를 제공합니다.

[실제로 Access와의 통합에는 쿼리, 보고서 및 모듈이 버전을 지정할 수있는 개별 개체로 포함됨]

MSDN 링크는 여기에 있습니다 .


답변

나는 이것을 잘하는 도구를 알지 못하지만 다양한 국내 솔루션을 보았습니다. 이들의 공통적 인 스레드는 버전 제어에서 이진 데이터를 최소화하고 텍스트 데이터를 최대화하여 기존 scc 시스템의 성능을 활용하는 것입니다. 이것을하기 위해:

  • 통합 문서를 다른 응용 프로그램처럼 취급하십시오. 논리, 구성 및 데이터를 분리하십시오.
  • 통합 문서와 코드를 분리하십시오.
  • 프로그래밍 방식으로 UI를 빌드하십시오.
  • 통합 문서를 재구성하는 빌드 스크립트를 작성하십시오.

답변

@Demosthenex 작업, @Tmdean 및 @Jon Crowell에 대한 귀중한 의견! (+1)

통합 문서 위치 옆의 git \ dir에 모듈 파일을 저장합니다. 원하는대로 변경하십시오.

통합 문서 코드 변경 내용은 추적하지 않습니다. 따라서 동기화하는 것은 사용자의 책임입니다.

Sub SaveCodeModules()

'This code Exports all VBA modules
Dim i As Integer, name As String

With ThisWorkbook.VBProject
    For i = .VBComponents.count To 1 Step -1
        If .VBComponents(i).Type <> vbext_ct_Document Then
            If .VBComponents(i).CodeModule.CountOfLines > 0 Then
                name = .VBComponents(i).CodeModule.name
                .VBComponents(i).Export Application.ThisWorkbook.Path & _
                                            "\git\" & name & ".vba"
            End If
        End If
    Next i
End With

End Sub

Sub ImportCodeModules()
Dim i As Integer
Dim ModuleName As String

With ThisWorkbook.VBProject
    For i = .VBComponents.count To 1 Step -1

        ModuleName = .VBComponents(i).CodeModule.name

        If ModuleName <> "VersionControl" Then
            If .VBComponents(i).Type <> vbext_ct_Document Then
                .VBComponents.Remove .VBComponents(ModuleName)
                .VBComponents.Import Application.ThisWorkbook.Path & _
                                         "\git\" & ModuleName & ".vba"
            End If
        End If
    Next i
End With

End Sub

그런 다음 통합 문서 모듈에서 :

Private Sub Workbook_Open()

    ImportCodeModules

End Sub

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

    SaveCodeModules

End Sub


답변

@Demosthenex의 답변을 한 단계 더 발전 시키면 Microsoft Excel Objects 및 UserForms의 코드를 추적하려면 약간 까다로워 야합니다.

먼저 SaveCodeModules()내보내려는 다른 유형의 코드를 설명하기 위해 기능을 변경했습니다 .

Sub SaveCodeModules(dir As String)

'This code Exports all VBA modules
Dim moduleName As String
Dim vbaType As Integer

With ThisWorkbook.VBProject
    For i = 1 To .VBComponents.count
        If .VBComponents(i).CodeModule.CountOfLines > 0 Then
            moduleName = .VBComponents(i).CodeModule.Name
            vbaType = .VBComponents(i).Type

            If vbaType = 1 Then
                .VBComponents(i).Export dir & moduleName & ".vba"
            ElseIf vbaType = 3 Then
                .VBComponents(i).Export dir & moduleName & ".frm"
            ElseIf vbaType = 100 Then
                .VBComponents(i).Export dir & moduleName & ".cls"
            End If

        End If
    Next i
End With

End Sub

VBA 코드와 마찬가지로 UserForms를 내보내고 가져올 수 있습니다. 유일한 차이점은 양식을 내보낼 때 두 개의 파일이 생성된다는 것입니다 ( 각 UserForm에 .frm대한 .frx파일 과 파일이 제공됨). 이 중 하나는 작성한 소프트웨어를 보유하고 다른 하나는 양식의 레이아웃을 정의하는 바이너리 파일입니다.

마이크로 소프트 엑셀 (MEOs)는 (의미 개체 Sheet1, Sheet2, ThisWorkbook등)을로 내보낼 수 있습니다 .cls파일. 그러나이 코드를 통합 문서로 다시 가져 오려면 VBA 모듈과 같은 방식으로 가져 오려고하면 해당 시트가 통합 문서에 이미 있으면 오류가 발생합니다.

이 문제를 해결하기 위해 .cls 파일을 Excel로 가져 오려고하지 않고 .cls파일을 Excel로 대신 문자열로 읽은 다음이 문자열을 빈 MEO에 붙여 넣습니다. 내 ImportCodeModules는 다음과 같습니다.

Sub ImportCodeModules(dir As String)

Dim modList(0 To 0) As String
Dim vbaType As Integer

' delete all forms, modules, and code in MEOs
With ThisWorkbook.VBProject
    For Each comp In .VBComponents

        moduleName = comp.CodeModule.Name

        vbaType = .VBComponents(moduleName).Type

        If moduleName <> "DevTools" Then
            If vbaType = 1 Or _
                vbaType = 3 Then

                .VBComponents.Remove .VBComponents(moduleName)

            ElseIf vbaType = 100 Then

                ' we can't simply delete these objects, so instead we empty them
                .VBComponents(moduleName).CodeModule.DeleteLines 1, .VBComponents(moduleName).CodeModule.CountOfLines

            End If
        End If
    Next comp
End With

' make a list of files in the target directory
Set FSO = CreateObject("Scripting.FileSystemObject")
Set dirContents = FSO.getfolder(dir) ' figure out what is in the directory we're importing

' import modules, forms, and MEO code back into workbook
With ThisWorkbook.VBProject
    For Each moduleName In dirContents.Files

        ' I don't want to import the module this script is in
        If moduleName.Name <> "DevTools.vba" Then

            ' if the current code is a module or form
            If Right(moduleName.Name, 4) = ".vba" Or _
                Right(moduleName.Name, 4) = ".frm" Then

                ' just import it normally
                .VBComponents.Import dir & moduleName.Name

            ' if the current code is a microsoft excel object
            ElseIf Right(moduleName.Name, 4) = ".cls" Then
                Dim count As Integer
                Dim fullmoduleString As String
                Open moduleName.Path For Input As #1

                count = 0              ' count which line we're on
                fullmoduleString = ""  ' build the string we want to put into the MEO
                Do Until EOF(1)        ' loop through all the lines in the file

                    Line Input #1, moduleString  ' the current line is moduleString
                    If count > 8 Then            ' skip the junk at the top of the file

                        ' append the current line `to the string we'll insert into the MEO
                        fullmoduleString = fullmoduleString & moduleString & vbNewLine

                    End If
                    count = count + 1
                Loop

                ' insert the lines into the MEO
                .VBComponents(Replace(moduleName.Name, ".cls", "")).CodeModule.InsertLines .VBComponents(Replace(moduleName.Name, ".cls", "")).CodeModule.CountOfLines + 1, fullmoduleString

                Close #1

            End If
        End If

    Next moduleName
End With

End Sub

dir두 함수 에 대한 입력으로 인해 혼동되는 경우 코드 리포지토리입니다! 따라서 다음과 같이 이러한 함수를 호출합니다.

SaveCodeModules "C:\...\YourDirectory\Project\source\"
ImportCodeModules "C:\...\YourDirectory\Project\source\"