sirve - La mejor manera de hacer control de versiones para MS Excel
sistema operativo dos caracteristicas (23)
Acabo de configurar una hoja de cálculo que usa Bazaar, con checkin / out manual a través de TortiseBZR. Dado que el tema me ayudó con la porción de salvar, quería publicar mi solución aquí.
La solución para mí fue crear una hoja de cálculo que exporte todos los módulos al guardar, y elimine y vuelva a importar los módulos en abierto. Sí, esto podría ser potencialmente peligroso para convertir hojas de cálculo existentes.
Esto me permite editar las macros en los módulos a través de Emacs (sí, emacs) o de forma nativa en Excel, y confirmar mi repositorio BZR después de cambios importantes. Debido a que todos los módulos son archivos de texto, los comandos estándar de estilo diff en BZR funcionan para mis fuentes, excepto el archivo Excel en sí.
He configurado un directorio para mi repositorio BZR, X: / Data / MySheet. En el repositorio se encuentran MySheet.xls y un archivo .vba para cada uno de mis módulos (es decir, Module1Macros). En mi hoja de cálculo, agregué un módulo que está exento del ciclo de exportación / importación llamado "VersionControl". Cada módulo que se exportará y reimportará debe terminar en "Macros".
Contenido del módulo "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
A continuación, tenemos que configurar ganchos de eventos para abrir / guardar para ejecutar estas macros. En el visor de código, haga clic derecho en "ThisWorkbook" y seleccione "Ver código". Puede tener que desplegar el cuadro de selección en la parte superior de la ventana de código para cambiar de la vista "(General)" a la vista "Libro de trabajo".
Contenido de la vista "Libro de trabajo":
Private Sub Workbook_Open()
ImportCodeModules
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
SaveCodeModules
End Sub
Me instalaré en este flujo de trabajo en las próximas semanas y publicaré si tengo algún problema.
¡Gracias por compartir el código de VBComponent!
¿Qué sistemas de control de versiones ha usado con MS Excel (2003/2007)? ¿Que recomendaria y porque? ¿Qué limitaciones ha encontrado con su sistema de control de versión mejor valorado?
Para poner esto en perspectiva, aquí hay un par de casos de uso:
- control de versión para módulos VBA
- más de una persona está trabajando en una hoja de cálculo de Excel y pueden estar haciendo cambios en la misma hoja de trabajo, que desean fusionar e integrar. Esta hoja de trabajo puede tener fórmulas, datos, gráficos, etc.
- los usuarios no son demasiado técnicos y cuantos menos sistemas de control de versiones usaron mejor
- La restricción de espacio es una consideración. Idealmente, solo se guardan los cambios incrementales en lugar de la hoja de cálculo de Excel completa.
Debería funcionar con la mayoría de VCS (dependiendo de otros criterios, puede elegir SVN, CVS, Darcs, TFS, etc.), pero en realidad será el archivo completo (porque es un formato binario), lo que significa que la pregunta "¿qué cambió? no tan fácil de responder.
Todavía puede confiar en los mensajes de registro si las personas los completan, pero también puede probar los nuevos formatos basados en XML de Office 2007 para obtener más visibilidad (aunque todavía sería difícil eliminar las toneladas de XML, además de AFAIK el archivo XML) está comprimido en el disco, por lo que necesitaría un gancho precompromiso para descomprimirlo para que la diferencia de texto funcione correctamente).
Deberías probar DiffEngineX. Puede llamarse programáticamente y también desde la línea de comandos tomando argumentos de línea de comando. No solo compara las celdas de hojas de cálculo de Excel, sino también las macros de Visual Basic incrustadas en los libros de trabajo. También compara nombres y comentarios definidos de Excel, que muchas herramientas de software gratuito se pierden. Se puede descargar de
http://www.florencesoft.com/excel-differences-download.html
Estoy seguro de que su sistema de control de versiones tiene una opción o cuadro para que pueda llamar automáticamente a DiffEngineX con sus libros de Excel originales y modificados.
Depende de si está hablando de datos o del código contenido en una hoja de cálculo. Si bien tengo una fuerte aversión a Visual Sourcesafe de Microsoft y normalmente no lo recomendaría, se integra fácilmente con Access y Excel, y proporciona control de fuente de los módulos.
[De hecho, la integración con Access incluye consultas, informes y módulos como objetos individuales que se pueden versionar]
El enlace de MSDN está here .
Depende del nivel de integración que desee, he usado Subversion / TortoiseSVN, que parece estar bien para un uso simple. También agregué palabras clave, pero parece haber un riesgo de corrupción de archivos. Existe una opción en Subversion para hacer que las sustituciones de palabras clave tengan una duración fija y, por lo que yo entiendo, funcionarán si la longitud fija es par, pero no impar. En cualquier caso, no obtiene ningún tipo de funcionalidad útil, creo que hay productos comerciales que harán ''diff''. Encontré algo que hizo diferencias basado en convertir cosas a texto plano y comparar eso, pero no fue muy agradable.
Después de buscar por años y probar muchas herramientas diferentes, he encontrado mi respuesta al problema de control de versión vba aquí: https://.com/a/25984759/2780179
Es un simple complemento de Excel para el cual se puede encontrar el código here
No hay módulos duplicados después de la importación. Exporta su código automáticamente, tan pronto como guarde su libro de trabajo, sin modificar ninguno de los libros existentes . Viene junto con un formateador de código vba.
En realidad, solo hay un puñado de soluciones para rastrear y comparar los cambios en el código de macro, la mayoría de ellos ya se mencionaron aquí. He estado navegando por la web y encontré esta nueva herramienta que vale la pena mencionar:
Control de versiones XLTools para macros de VBA
- control de versiones para hojas de Excel y módulos de VBA
- vista previa y cambios de diferencias antes de comprometer una versión
- ideal para el trabajo colaborativo de varios usuarios en el mismo archivo (rastrear quién cambió qué / cuándo / comentarios)
- comparar versiones y resaltar los cambios en el código línea por línea
- adecuado para usuarios que no son conocedores de la tecnología o conocedores de Excel para el caso
- el historial de versiones se almacena en Git-repository en su propia PC; cualquier versión puede recuperarse fácilmente
Versiones de código VBA una al lado de la otra, los cambios se visualizan
Es posible que haya intentado utilizar el XML de Excel de Microsoft en el contenedor zip (.xlsx y .xslm) para el control de versiones y haya encontrado que la vba se almacenó en vbaProject.bin (que es inútil para el control de versiones).
La solución es simple.
- Abra el archivo Excel con LibreOffice Calc
- En LibreOffice Calc
- Archivo
- Guardar como
- Guardar como tipo: Hoja de cálculo ODF (.ods)
- Cerrar LibreOffice Calc
- cambiar el nombre de la extensión del archivo nuevo de .ods a .zip
- crear una carpeta para la hoja de cálculo en un área mantenida por GIT
- extraer el zip en su carpeta GIT
- comprometerse con GIT
Cuando repita esto con la próxima versión de la hoja de cálculo, deberá asegurarse de que los archivos de la carpeta coincidan exactamente con los del contenedor zip (y no deje ningún archivo eliminado).
Escribí una hoja de cálculo controlada por revisión usando VBA. Está más orientado a informes de ingeniería donde tienes varias personas trabajando en una lista de materiales o programación y luego, en algún momento, quieres crear una revisión instantánea que muestre las adiciones, del y las actualizaciones de la versión anterior.
Nota: es un libro de trabajo macro habilitado al que debe iniciar sesión para descargarlo de mi sitio (puede usar OpenID)
Todo el código está desbloqueado.
He estado investigando esto también. Parece que el último Team Foundation Server 2010 puede tener un complemento de Excel.
Aquí hay una pista:
http://team-foundation-server.blogspot.com/2009/07/tf84037-there-was-problem-initializing.html
Me gustaría recomendar una gran herramienta de código abierto llamada Rubberduck que tiene el control de versión del código VBA incorporado. ¡Pruébalo!
Mi compañía hace una cantidad considerable de trabajo para automatizar las soluciones de Microsoft Office, así que escribí un .DLL que exportará el origen de una solución cada vez que se guarde una plantilla. Crea una carpeta llamada Source como elemento secundario de la carpeta donde se guarda la plantilla, y debajo de Source crea una carpeta con el mismo nombre que el Proyecto VBA. En la carpeta del proyecto, exporta todo el código fuente para módulos, clases y formularios de usuario. Esta disposición se eligió para facilitar la administración de la fuente de grandes colecciones de plantillas. La DLL puede desbloquear proyectos bloqueados para obtener acceso al proyecto VBA si tiene un archivo de configuración local o un archivo de configuración global disponible. Con esta herramienta en uso, los desarrolladores pueden trabajar en plantillas al máximo contenido y usar su herramienta de control de revisiones favorita para administrar su trabajo. Usamos Git principalmente en nuestro entorno y mantenemos los archivos binarios de la plantilla completa, así como los recursos de VBA bajo control de revisión.
No conozco una herramienta que lo haga bien, pero he visto una variedad de soluciones de cosecha propia. El hilo común de estos es minimizar los datos binarios bajo control de versión y maximizar los datos textuales para aprovechar la potencia de los sistemas scc convencionales. Para hacer esto:
- Trate el libro de trabajo como cualquier otra aplicación. Separa la lógica, la configuración y los datos.
- Separe el código del libro de trabajo.
- Construye la interfaz de usuario programáticamente.
- Escriba un script de compilación para reconstruir el libro de trabajo.
Permítame resumir lo que le gustaría controlar de la versión y por qué:
Qué:
- Código (VBA)
- Hojas de cálculo (fórmulas)
- Hojas de cálculo (valores)
- Gráficos
- ...
Por qué:
- Registro de auditoría
- Colaboración
- Comparación de versión ("diferente")
- Fusión
Como otros han publicado aquí, hay un par de soluciones sobre los sistemas de control de versiones existentes, tales como:
- Git
- Mercurial
- Subversión
- Bazar
Si su única preocupación es el código VBA en sus libros de trabajo, entonces el enfoque propuesto por Demosthenex más arriba o VbaGit ( https://github.com/brucemcpherson/VbaGit ) funcionan muy bien y son relativamente simples de implementar. Las ventajas son que puede confiar en sistemas de control de versiones bien probados y elegir uno según sus necesidades (consulte https://help.github.com/articles/what-are-the-differences-between-svn-and-git/ para una breve comparación entre Git y Subversion).
Si no solo se preocupa por el código sino también por los datos en sus hojas (valores "codificados" y resultados de fórmula), puede usar una estrategia similar para eso: serializar los contenidos de sus hojas en algún formato de texto (a través de Range.Value) y use un sistema de control de versiones existente. Aquí hay una muy buena publicación de blog sobre esto: https://wiki.ucl.ac.uk/display/~ucftpw2/2013/10/18/Using+git+for+version+control+of+spreadsheet+models+-+part+1+of+3
Sin embargo, la comparación de hoja de cálculo es un problema algorítmico no trivial. Existen algunas herramientas, como la comparación de hoja de cálculo de Microsoft ( https://support.office.com/en-us/article/Overview-of-Spreadsheet-Compare-13fafa61-62aa-451b-8674-242ce5f2c986 ), Exceldiff ( http://exceldiff.arstdesign.com/ ) y DiffEngineX ( https://www.florencesoft.com/compare-excel-workbooks-differences.html ). Pero es otro desafío integrar estas comparaciones con un sistema de control de versiones como Git.
Finalmente, debe establecer un flujo de trabajo que se adapte a sus necesidades. Para obtener un flujo de trabajo simple y adaptado de Git for Excel, consulte https://www.xltrail.com/blog/git-workflow-for-excel .
Si está buscando un entorno de oficina con usuarios no técnicos regulares de la oficina, Sharepoint es una alternativa viable. Puede configurar carpetas de documentos con control de versiones habilitado y checkins y checkouts. Lo hace más fácil para los usuarios habituales de la oficina.
También hay un programa llamado Beyond Compare que tiene un archivo de Excel bastante bueno. Encontré una captura de pantalla en chino que muestra brevemente esto:
Hay una prueba de 30 días en su page
Tomando la respuesta de @Demosthenex un paso más allá, si también desea realizar un seguimiento del código en sus Objetos de Microsoft Excel y UserForms tiene que ser un poco complicado.
Primero modifiqué mi función SaveCodeModules()
para dar cuenta de los diferentes tipos de código que planeo exportar:
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
Los UserForms se pueden exportar e importar como el código VBA. La única diferencia es que se crearán dos archivos cuando se exporte un formulario (obtendrá un .frm
y un archivo .frx
para cada UserForm). Uno de ellos contiene el software que ha escrito y el otro es un archivo binario que (estoy bastante seguro) define el diseño del formulario.
Los Objetos de Microsoft Excel (MEO) (es decir, Sheet1
, Sheet2
, ThisWorkbook
, etc.) se pueden exportar como un archivo .cls
. Sin embargo, cuando desee volver a introducir este código en su libro de trabajo, si intenta importarlo de la misma manera que lo haría con un módulo de VBA, obtendrá un error si esa hoja ya existe en el libro de trabajo.
Para evitar este problema, decidí no intentar importar el archivo .cls en Excel, pero para leer el archivo .cls
en Excel como una cadena en su lugar, luego pegar esta cadena en el MEO vacío. Aquí está mi 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
En caso de que esté confundido por la entrada del dir
a estas dos funciones, ¡ese es solo su repositorio de código! Entonces, llamarías a estas funciones como:
SaveCodeModules "C:/.../YourDirectory/Project/source/"
ImportCodeModules "C:/.../YourDirectory/Project/source/"
Trabajando sobre el trabajo de @Demosthenex, @Tmdean y @Jon Crowell comentarios invaluables! (+1 ellos)
Guardo archivos de módulo en git / dir al lado de la ubicación del libro. Cambia eso a tu gusto.
Esto NO rastreará los cambios al código del Libro de trabajo. Entonces depende de usted sincronizarlos.
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
Y luego en el módulo Libro de trabajo:
Private Sub Workbook_Open()
ImportCodeModules
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
SaveCodeModules
End Sub
Una cosa que podría hacer es tener el siguiente fragmento en su Libro de trabajo:
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
Encontré este fragmento en Internet.
Después, puede usar Subversion para mantener el control de la versión. Por ejemplo, al usar la interfaz de línea de comando de Subversion con el comando ''shell'' dentro de VBA. Eso lo haría. Incluso estoy pensando en hacer esto yo mismo :)
Utilice cualquiera de las herramientas de control de versiones estándar como SVN o CVS. Las limitaciones dependerán de cuál sea el objetivo. Además de un pequeño aumento en el tamaño del repositorio, no tuve problemas
Yo uso git , y hoy porté esto (git-xlsx-textconv) a Python, ya que mi proyecto se basa en el código de Python e interactúa con archivos de Excel. Esto funciona para al menos archivos .xlsx , pero creo que funcionará para .xls también. Here''s el enlace de Github. Escribí dos versiones, una con cada fila en su propia línea, y otra donde cada celda está en su propia línea (esta última se escribió porque a git diff no le gusta ajustar líneas largas de forma predeterminada, al menos aquí en Windows).
Este es mi archivo .gitconfig (esto permite que el script diferente resida en el repositorio de mi proyecto):
[diff "xlsx"]
binary = true
textconv = python `git rev-parse --show-toplevel`/src/util/git-xlsx-textconv.py
si desea que el script esté disponible para muchos repositorios diferentes, use algo como esto:
[diff "xlsx"]
binary = true
textconv = python C:/Python27/Scripts/git-xlsx-textconv.py
mi archivo .gitattributes :
*.xlsx diff=xlsx
en respuesta a la respuesta de mattlant, sharepoint funcionará bien como control de versión solo si la característica de control de versión está activada en la biblioteca de documentos. Además, tenga en cuenta que ningún código que llame a otros archivos por rutas relativas no funcionará. y, finalmente, cualquier enlace a archivos externos se romperá cuando se guarde un archivo en sharepoint.
TortoiseSVN es un cliente de Windows asombrosamente bueno para el sistema de control de versiones de Subversion. Una característica que acabo de descubrir que tiene es que cuando hace clic para obtener una diferencia entre las versiones de un archivo de Excel, abrirá ambas versiones en Excel y resaltará (en rojo) las celdas que se cambiaron. Esto se hace a través de la magia de un script vbs, que se describe here .
Puede encontrar esto útil aunque NO use TortoiseSVN.