Best way to do Version Control for MS Excel [closed]
What version control systems have you used with MS Excel (2003/2007)? What would you recommend and Why? What limitations have you found with your top rated version control system?
To put this in perspective, here are a couple of use cases:
- version control for VBA modules
- more than one person is working on a Excel spreadsheet and they may be making changes to the same worksheet, which they want to merge and integrate. This worksheet may have formulae, data, charts etc
- the users are not too technical and the fewer version control systems used the better
- Space constraint is a consideration. Ideally only incremental changes are saved rather than the entire Excel spreadsheet.
Solution 1:
I've just setup a spreadsheet that uses Bazaar, with manual checkin/out via TortiseBZR. Given that the topic helped me with the save portion, I wanted to post my solution here.
The solution for me was to create a spreadsheet that exports all modules on save, and removes and re-imports the modules on open. Yes, this could be potentially dangerous for converting existing spreadsheets.
This allows me to edit the macros in the modules via Emacs (yes, emacs) or natively in Excel, and commit my BZR repository after major changes. Because all the modules are text files, the standard diff-style commands in BZR work for my sources except the Excel file itself.
I've setup a directory for my BZR repository, X:\Data\MySheet. In the repo are MySheet.xls and one .vba file for each of my modules (ie: Module1Macros). In my spreadsheet I've added one module that is exempt from the export/import cycle called "VersionControl". Each module to be exported and re-imported must end in "Macros".
Contents of the "VersionControl" module:
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
Next, we have to setup event hooks for open / save to run these macros. In the code viewer, right click on "ThisWorkbook" and select "View Code". You may have to pull down the select box at the top of the code window to change from "(General)" view to "Workbook" view.
Contents of "Workbook" view:
Private Sub Workbook_Open()
ImportCodeModules
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
SaveCodeModules
End Sub
I'll be settling into this workflow over the next few weeks, and I'll post if I have any problems.
Thanks for sharing the VBComponent code!
Solution 2:
TortoiseSVN is an astonishingly good Windows client for the Subversion version control system. One feature which I just discovered that it has is that when you click to get a diff between versions of an Excel file, it will open both versions in Excel and highlight (in red) the cells that were changed. This is done through the magic of a vbs script, described here.
You may find this useful even if NOT using TortoiseSVN.
Solution 3:
Let me summarise what you would like to version control and why:
-
What:
- Code (VBA)
- Spreadsheets (Formulae)
- Spreadsheets (Values)
- Charts
- ...
-
Why:
- Audit log
- Collaboration
- Version comparison ("diffing")
- Merging
As others have posted here, there are a couple of solutions on top of existing version control systems such as:
- Git
- Mercurial
- Subversion
- Bazaar
If your only concern is the VBA code in your workbooks, then the approach Demosthenex above proposes or VbaGit (https://github.com/brucemcpherson/VbaGit) work very well working and are relatively simple to implement. The advantages are that you can rely on well proven version control systems and chose one according to your needs (have a look at https://help.github.com/articles/what-are-the-differences-between-svn-and-git/ for a brief comparison between Git and Subversion).
If you not only worry about code but also about the data in your sheets ("hardcoded" values and formula results), you can use a similar strategy for that: Serialise the contents of your sheets into some text format (via Range.Value) and use an existing version control system. Here's a very good blog post about this: https://wiki.ucl.ac.uk/display/~ucftpw2/2013/10/18/Using+git+for+version+control+of+spreadsheet+models+-+part+1+of+3
However, spreadsheet comparison is a non-trivial algorithmic problem. There are a few tools around, such as Microsoft's Spreadsheet Compare (https://support.office.com/en-us/article/Overview-of-Spreadsheet-Compare-13fafa61-62aa-451b-8674-242ce5f2c986), Exceldiff (http://exceldiff.arstdesign.com/) and DiffEngineX (https://www.florencesoft.com/compare-excel-workbooks-differences.html). But it's another challenge to integrate these comparison with a version control system like Git.
Finally, you have to settle on a workflow that suits your needs. For a simple, tailored Git for Excel workflow, have a look at https://www.xltrail.com/blog/git-workflow-for-excel.
Solution 4:
It depends whether you are talking about data, or the code contained within a spreadsheet. While I have a strong dislike of Microsoft's Visual Sourcesafe and normally would not recommended it, it does integrate easily with both Access and Excel, and provides source control of modules.
[In fact the integration with Access, includes queries, reports and modules as individual objects that can be versioned]
The MSDN link is here.
Solution 5:
I'm not aware of a tool that does this well but I've seen a variety of homegrown solutions. The common thread of these is to minimise the binary data under version control and maximise textual data to leverage the power of conventional scc systems. To do this:
- Treat the workbook like any other application. Seperate logic, config and data.
- Separate code from the workbook.
- Build the UI programmatically.
- Write a build script to reconstruct the workbook.