Лучший способ выполнения контроля версий для MS Excel

Какие системы управления версиями вы использовали с MS Excel (2003/2007)? Что бы вы порекомендовали и почему? Какие ограничения вы обнаружили в своей системе управления версиями?

Чтобы представить это в перспективе, вот несколько вариантов использования:

  • контроль версий для модулей VBA
  • более одного человека работает над электронной таблицей Excel, и они могут вносить изменения в тот же рабочий лист, который они хотят объединить и интегрировать. Этот рабочий лист может содержать формулы, данные, диаграммы и т.д.
  • пользователи не слишком технические, и чем меньше систем управления версиями, тем лучше
  • Ограничение пространства - это соображение. В идеале сохраняются только инкрементные изменения, а не вся электронная таблица Excel.

Ответ 1

Я только что установил таблицу, которая использует Bazaar, с ручным контролем/выводом через TortiseBZR. Учитывая, что эта тема помогла мне с частью сохранения, я хотел разместить здесь свое решение.

Решение для меня заключалось в создании электронной таблицы, которая экспортирует все модули при сохранении, а также удаляет и повторно импортирует модули на открытом. Да, это может быть потенциально опасно для преобразования существующих электронных таблиц.

Это позволяет мне редактировать макросы в модулях с помощью Emacs (да, emacs) или изначально в Excel и фиксировать мой репозиторий BZR после серьезных изменений. Поскольку все модули являются текстовыми файлами, стандартные команды diff-style в BZR работают для моих источников, кроме самого файла 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!

Ответ 2

TortoiseSVN - удивительно хороший клиент Windows для системы контроля версий Subversion. Одна из функций, которую я только что обнаружил, заключается в том, что, когда вы нажимаете, чтобы получить разницу между версиями файла Excel, она откроет обе версии в Excel и выделит (красным) ячейки, которые были изменены. Это делается с помощью магии vbs script, описанной здесь.

Вы можете найти это полезным, даже если НЕ использовать TortoiseSVN.

Ответ 3

Это зависит от того, говоришь ли вы о данных или о коде, содержащемся в электронной таблице. Хотя я сильно не люблю Microsoft Visual Sourcesafe и обычно не рекомендую его, он легко интегрируется как с Access, так и с Excel и обеспечивает управление версиями модулей.

[Фактически интеграция с Access, включает запросы, отчеты и модули как отдельные объекты, которые могут быть версиями]

Ссылка MSDN здесь.

Ответ 4

Я не знаю инструмента, который делает это хорошо, но я видел множество домашних решений. Общим потоком этих данных является минимизация двоичных данных при управлении версиями и максимизация текстовых данных для использования мощности традиционных систем scc. Для этого:

  • Относитесь к книге как к любому другому приложению. Отдельная логика, конфигурация и данные.
  • Отдельный код из книги.
  • Построить пользовательский интерфейс программно.
  • Напишите сборку script, чтобы восстановить книгу.

Ответ 5

Позвольте мне подвести итог тому, что вы хотели бы контролировать версиями и почему:

  • Что:

    • Код (VBA)
    • Таблицы (формулы)
    • Таблицы (значения)
    • Диаграммы
    • ...
  • Почему:

    • Журнал аудита
    • Сотрудничество
    • Сравнение версий ( "diffing" )
    • Слияние

Как сообщают другие, существует несколько решений поверх существующих систем управления версиями, таких как:

  • Git
  • Mercurial
  • Subversion
  • Bazaar

Если ваша проблема связана только с кодом VBA в ваших книгах, то предлагаемый выше подход Demosthenex предлагает или VbaGit (https://github.com/brucemcpherson/VbaGit) работает очень хорошо работают и относительно просты в реализации. Преимущества заключаются в том, что вы можете положиться на проверенные системы контроля версий и выбрать один в соответствии с вашими потребностями (посмотрите https://help.github.com/articles/what-are-the-differences-between-svn-and-git/ для краткое сравнение между Git и Subversion).

Если вы не только беспокоитесь о коде, но и о данных в ваших листах ( "жестко закодированные" значения и результаты формулы), вы можете использовать для этого аналогичную стратегию: Сериализировать содержимое ваших листов в некоторый текстовый формат (через Range.) И использовать существующую систему управления версиями. Здесь очень хорошее сообщение в блоге об этом: https://wiki.ucl.ac.uk/display/~ucftpw2/2013/10/18/Using+git+for+version+control+of+spreadsheet+models+-+part+1+of+3

Однако сравнение электронных таблиц является нетривиальной алгоритмической задачей. Существует несколько инструментов, таких как Microsoft Spreadsheet Compare (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 для Excel просмотрите https://www.xltrail.com/blog/git-workflow-for-excel.

Ответ 6

Работа над работами @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

А затем в модуле Workbook:

Private Sub Workbook_Open()

    ImportCodeModules

End Sub

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

    SaveCodeModules

End Sub

Ответ 7

Принимая @Demosthenex, ответьте на шаг дальше, если вы хотите также отслеживать код в своих объектах Microsoft Excel и 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. Единственное отличие состоит в том, что при экспорте формы будут созданы два файла (вы получите файл .frm и .frx для каждого UserForm). Один из них содержит написанное вами программное обеспечение, а другой - двоичный файл, который (я уверен) определяет макет формы.

Объекты Microsoft Excel (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\"

Ответ 8

Одна вещь, которую вы можете сделать, это иметь следующий фрагмент в вашей книге:

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 "C:\Code\" & sName$ & ".vba"
            End If
        Next i
    End With
End Sub

Я нашел этот фрагмент в Интернете.

Впоследствии вы можете использовать Subversion для поддержания контроля версий. Например, используя интерфейс командной строки Subversion с командой "shell" в VBA. Это сделало бы это. Я даже подумываю сделать это сам:)

Ответ 9

Я использую git, и сегодня я портировал this (git -xlsx-textconv) на Python, поскольку мой проект основан на коде Python и взаимодействует с файлами Excel. Это работает как минимум для .xlsx, но я думаю, что он будет работать и для .xls. Вот ссылка github. Я написал две версии: по одной с каждой строкой в ​​своей строке и другую, где каждая ячейка находится на собственной строке (последняя была написана, потому что git diff не любит переносить длинные строки на по умолчанию, по крайней мере здесь, в Windows).

Это мой файл .gitconfig (это позволяет отличать script от моего проекта-репо):

[diff "xlsx"]
    binary = true
    textconv = python `git rev-parse --show-toplevel`/src/util/git-xlsx-textconv.py

если вы хотите, чтобы script был доступен для многих разных репозиториев, затем используйте что-то вроде этого:

[diff "xlsx"]
    binary = true
    textconv = python C:/Python27/Scripts/git-xlsx-textconv.py

my .gitattributes:

*.xlsx diff=xlsx

Ответ 10

Используйте любой из стандартных инструментов управления версиями, таких как SVN или CVS. Ограничения будут зависеть от цели. Помимо небольшого увеличения размера репозитория, я не сталкивался с какими-либо проблемами.

Ответ 11

Если вы смотрите на офисные помещения с обычными офисными нетехническими пользователями, чем Sharepoint, это жизнеспособная альтернатива. Вы можете настроить папки документов с включенным контролем версий и проверок и проверок. Делает это freindlier для обычных пользователей офиса.

Ответ 12

в ответ на ответ матового ответа - sharepoint будет работать как средство управления версиями только в том случае, если функция управления версиями включена в библиотеке документов. кроме того, имейте в виду, что любой код, который вызывает другие файлы по относительным путям, не будет работать. и, наконец, любые ссылки на внешние файлы будут разбиты, когда файл будет сохранен в sharepoint.

Ответ 14

Вам следует попробовать DiffEngineX. Его можно назвать программным, а также из командной строки с использованием аргументов командной строки. Он не только сравнивает ячейки таблиц Excel, но также макросы Visual Basic, встроенные в книги. Также сравниваются имена и комментарии, определенные в Excel, и многие из бесплатных программ пропущены. Его можно загрузить из

http://www.florencesoft.com/excel-differences-download.html

Я уверен, что ваша система управления версиями имеет опцию или поле, чтобы вы могли автоматически вызывать DiffEngineX с вашими оригинальными и измененными книгами Excel.

Ответ 15

После поиска возрастов и тестирования множества различных инструментов я нашел свой ответ на проблему с управлением версиями vba: fooobar.com/questions/42978/...

Это простой excel addin, для которого код можно найти здесь

После импорта нет повторяющихся модулей. Он автоматически экспортирует ваш код, как только вы сохраните книгу, без изменения существующих книг. Он поставляется вместе с форматиром кода vba.

Ответ 16

На самом деле существует только несколько решений для отслеживания и сравнения изменений в макрокоде - большинство из них уже были названы здесь. Я просматривал веб-страницы и наткнулся на этот новый инструмент, который стоит упомянуть:

Управление версиями XLTools для макросов VBA

  • контроль версий для листов Excel и модулей VBA
  • предварительный просмотр и изменение diff перед выполнением версии
  • отлично подходит для совместной работы нескольких пользователей в одном файле (трек, который изменил что/когда/комментарии)
  • сравнить версии и выделить изменения в строке по строке
  • подходит для пользователей, которые не являются технически подкованными или умело разбираются в Excel.
  • история версий хранится в Git -репозиторе на вашем собственном компьютере - любая версия может быть легко восстановлена.

Варианты кода VBA бок о бок, изменения визуализируются

Ответ 17

Существует также программа под названием Beyond Compare, которая имеет неплохое сравнение файлов Excel. Я нашел скриншот на китайском, который на короткое время показывает это:

Beyond Compare - comparing two excel files (Chinese)
Исходный источник изображения

Существует 30-дневная пробная версия на странице

Ответ 18

Возможно, вы попытались использовать Microsoft Excel XML в zip-контейнере (.xlsx и .xslm) для управления версиями и обнаружили, что vba хранится в vbaProject.bin(что бесполезно для контроля версий).

Решение прост.

  • Откройте файл excel с LibreOffice Calc
  • В LibreOffice Calc
    • Файл
    • Сохранить как
    • Сохранить как тип: ODF Spreadsheet (.ods)
  • Закрыть LibreOffice Calc
  • переименуйте расширение нового файла с .ods на .zip
  • создать папку для электронной таблицы в поддерживаемой области GIT
  • извлеките почтовый индекс в папку GIT
  • передать GIT

Если вы повторите это со следующей версией электронной таблицы, вам необходимо убедиться, что файлы папок точно совпадают с файлами в zip-контейнере (и не оставляйте удаленные файлы позади).

Ответ 19

Моя компания выполняет значительную работу по автоматизации решений Microsoft Office, поэтому я написал .DLL, который будет экспортировать источник решения каждый раз при сохранении шаблона. Он создает папку с именем Source в качестве дочернего элемента папки, в которой сохраняется шаблон, а под источником создается папка с тем же именем, что и проект VBA. В папке проекта он экспортирует весь исходный код для модулей, классов и пользовательских форм. Эта схема была выбрана так, чтобы упростить управление источником для больших коллекций шаблонов. DLL может разблокировать заблокированные проекты, чтобы получить доступ к проекту VBA, если у вас есть локальный файл конфигурации или глобальный файл конфигурации. Используя этот инструмент, разработчики могут работать с шаблонами в своем сердце и использовать свой любимый инструмент управления версиями для управления своей работой. Мы используем Git в первую очередь в нашей среде, и мы сохраняем полные двоичные файлы шаблонов, а также ресурсы VBA под контролем версий.

Ответ 20

Я хотел бы порекомендовать отличный инструмент с открытым исходным кодом под названием Rubberduck, в котором встроено управление версиями кода VBA. Попробуйте!

Ответ 21

Это зависит от того, какой уровень интеграции вы хотите, я использовал Subversion/TortoiseSVN, который кажется прекрасным для простого использования. Я также добавил в ключевые слова, но, похоже, существует риск повреждения файлов. В Subversion есть опция, позволяющая фиксировать фиксированную длину ключевых слов и насколько я понимаю, она будет работать, если фиксированная длина четная, но нечетная. В любом случае вы не получаете какой-либо полезной разновидности функциональности diff, я думаю, что есть коммерческие продукты, которые будут делать "diff". Я нашел что-то, что делало diff на основе преобразования материала в обычный текст и сравнения, но это было не очень приятно.

Ответ 22

Он должен работать с большинством VCS (в зависимости от других критериев вы можете выбрать SVN, CVS, Darcs, TFS и т.д.), однако на самом деле это будет полный файл (поскольку это двоичный формат), что означает, что "что изменилось" Вопрос не так-то просто ответить.

Вы можете по-прежнему полагаться на сообщения журнала, если люди их заполняют, но вы также можете попробовать новые форматы, основанные на XML, из Office 2007, чтобы получить дополнительную видимость (хотя все равно будет сложно обрабатывать тонны XML, плюс AFAIK файл XML застегнут на диске, поэтому вам понадобится фиксатор pre-commit, чтобы распаковать его, чтобы текстовый diff работал правильно).

Ответ 23

Я написал таблицу с контролируемым пересмотром, используя VBA. Это больше ориентировано на инженерные отчеты, в которых у вас много людей, работающих над Биллом материала или расписанием, а затем в какой-то момент времени вы хотите создать копию моментального снимка, которая показывает добавление, del и обновления из предыдущего rev.

Примечание. Это рабочая книга с поддержкой макросов, которую необходимо выполнить для входа с моего сайта (вы можете использовать OpenID)

Весь код разблокирован.

Rev Controlled Spreadsheet