Quels systèmes de contrôle de version avez-vous utilisés avec MS Excel (2003/2007)? Que recommanderiez-vous et pourquoi? Quelles limitations avez-vous trouvées avec votre système de contrôle de version le mieux coté?
Pour mettre cela en perspective, voici quelques cas d'utilisation:
Je viens de mettre en place une feuille de calcul utilisant Bazaar, avec archivage/départ manuel via TortiseBZR. Étant donné que le sujet m'a aidé avec la partie de sauvegarde, je voulais poster ma solution ici.
La solution pour moi était de créer un tableur qui exporte tous les modules lors de la sauvegarde, puis supprime et réimporte les modules en cours. Oui, cela pourrait être potentiellement dangereux pour la conversion de feuilles de calcul existantes.
Cela me permet d’éditer les macros dans les modules via Emacs (oui, emacs) ou nativement dans Excel et de valider mon référentiel BZR après des modifications majeures. Comme tous les modules sont des fichiers texte, les commandes standard de style diff de BZR fonctionnent pour mes sources, à l'exception du fichier Excel lui-même.
J'ai configuré un répertoire pour mon référentiel BZR, X:\Data\MySheet. MySheet.xls et un fichier .vba pour chacun de mes modules (c'est-à-dire: Module1Macros) figurent dans le référentiel. Dans ma feuille de calcul, j'ai ajouté un module exempt du cycle d'exportation/importation appelé "VersionControl". Chaque module à exporter et à réimporter doit se terminer par "Macros".
Contenu du module "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
Ensuite, nous devons configurer les crochets d’événement pour open/save afin d’exécuter ces macros. Dans la visionneuse de code, cliquez avec le bouton droit de la souris sur "ThisWorkbook" et sélectionnez "Afficher le code". Vous devrez peut-être dérouler la zone de sélection en haut de la fenêtre de code pour passer de la vue "(Général)" à la vue "Classeur".
Contenu de la vue "Cahier":
Private Sub Workbook_Open()
ImportCodeModules
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
SaveCodeModules
End Sub
Je vais m'installer dans ce flux de travail au cours des prochaines semaines, et je posterai si j'ai des problèmes.
Merci de partager le code VBComponent!
TortoiseSVN est un client Windows étonnamment bon pour le système de contrôle de version Subversion. Une caractéristique que je viens de découvrir, c'est que lorsque vous cliquez pour obtenir un diff entre les versions d'un fichier Excel, les deux versions sont ouvertes dans Excel et mettent en surbrillance (en rouge) les cellules modifiées. Cela se fait par la magie d'un script vbs, décrit ici .
Vous pouvez trouver cela utile même si vous n'utilisez PAS TortoiseSVN.
Cela dépend si vous parlez de données ou du code contenu dans une feuille de calcul. Bien que je n'aime pas vraiment Visual Sourcesafe de Microsoft et que je ne le recommande pas normalement, il s'intègre facilement à Access et à Excel et permet le contrôle de source des modules.
[En fait, l'intégration avec Access inclut les requêtes, les rapports et les modules sous forme d'objets individuels pouvant être versionnés]
Le lien MSDN est ici .
Permettez-moi de résumer ce que vous souhaitez contrôler par version et pourquoi:
Quoi:
Pourquoi:
Comme d'autres l'ont signalé ici, plusieurs solutions s'ajoutent aux systèmes de contrôle de version existants, tels que:
Si votre seul souci est le code VBA de vos classeurs, l'approche proposée par Demosthenex ou VbaGit ( https://github.com/brucemcpherson/VbaGit ) fonctionne très bien et est relativement simple à mettre en œuvre. Les avantages sont que vous pouvez compter sur des systèmes de contrôle de version éprouvés et en choisir un en fonction de vos besoins (consultez https://help.github.com/articles/what-are-the-differences-between-svn -and-git/ pour une brève comparaison entre Git et Subversion).
Si vous vous inquiétez non seulement du code mais aussi des données de vos feuilles (valeurs "codées en dur" et résultats de formules), vous pouvez utiliser une stratégie similaire pour cela: Sérialiser le contenu de vos feuilles dans un format de texte (via Range.Value) et utilisez un système de contrôle de version existant. Voici un très bon article de blog à ce sujet: https://wiki.ucl.ac.uk/display/~ucftpw2/2013/10/18/Using+git+for+version+control+of+spreadsheet+models+- + partie + 1 + de + 3
Cependant, la comparaison de feuilles de calcul est un problème algorithmique non trivial. Il existe quelques outils, tels que Spreadsheet Compare ( https://support.office.com/en-us/article/Overview-of-Spreadsheet-Compare-13fafa61-62aa-451b-8674-242ce5f2c986 ), Exceldiff ( http://exceldiff.arstdesign.com/ ) et DiffEngineX ( https://www.florencesoft.com/compare-Excel-workbooks-differences.html ). C’est un autre défi d’intégrer ces comparaisons à un système de contrôle de version comme Git.
Enfin, vous devez choisir un flux de travail qui répond à vos besoins. Pour un flux de production Git for Excel simple et personnalisé, consultez https://www.xltrail.com/blog/git-workflow-for-Excel .
Je ne suis pas au courant d'un outil qui fait cela bien mais j'ai vu une variété de solutions maison. Leur dénominateur commun est de minimiser les données binaires sous contrôle de version et de maximiser les données textuelles afin de tirer parti de la puissance des systèmes scc conventionnels. Pour faire ça:
Travailler sur @Demosthenex, @Tmdean et @Jon Crowell, de précieux commentaires! (+1 eux)
J'enregistre les fichiers de module dans git\dir à côté de l'emplacement du classeur. Changer cela à votre goût.
Ceci ne suivra PAS les modifications apportées au code du classeur. C'est donc à vous de les synchroniser.
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
Et ensuite dans le module Classeur:
Private Sub Workbook_Open()
ImportCodeModules
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
SaveCodeModules
End Sub
Pour aller plus loin dans la réponse de @Demosthenex, si vous souhaitez également garder une trace du code dans vos objets Microsoft Excel et UserForm, vous devez être un peu délicat.
D'abord, j'ai modifié ma fonction SaveCodeModules()
pour prendre en compte les différents types de code que je compte exporter:
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
Les UserForms peuvent être exportés et importés comme le code VBA. La seule différence est que deux fichiers seront créés lors de l'exportation d'un formulaire (vous obtiendrez un fichier .frm
et un fichier .frx
pour chaque formulaire UserForm). L’un d’eux contient le logiciel que vous avez écrit et l’autre est un fichier binaire qui (je suis à peu près sûr) définit la présentation du formulaire.
Les objets Microsoft Excel (MEO) (signifiant Sheet1
, Sheet2
, ThisWorkbook
etc.) peuvent être exportés sous la forme d'un fichier .cls
. Toutefois, lorsque vous souhaitez récupérer ce code dans votre classeur, si vous tentez de l'importer de la même manière qu'un module VBA, vous obtiendrez une erreur si cette feuille existe déjà dans le classeur.
Pour résoudre ce problème, j'ai décidé de ne pas essayer d'importer le fichier .cls dans Excel, mais plutôt de lire le fichier .cls
dans Excel sous forme de chaîne, puis de coller cette chaîne dans le MEO vide. Voici mes 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
Si l'entrée dir
vous confond avec ces deux fonctions, il s'agit simplement de votre référentiel de code! Donc, vous appelez ces fonctions comme:
SaveCodeModules "C:\...\YourDirectory\Project\source\"
ImportCodeModules "C:\...\YourDirectory\Project\source\"
J'utilise git, et aujourd'hui j'ai porté this (git-xlsx-textconv) vers Python, car mon projet est basé sur du code Python et qu'il interagit avec les fichiers Excel. Cela fonctionne pour au moins .xlsx fichiers, mais je pense que cela fonctionnera également pour .xls. Voici le lien github. J'ai écrit deux versions, une avec chaque ligne sur sa propre ligne, et une autre où chaque cellule est sur sa propre ligne (la dernière a été écrite parce que git diff n'aime pas encapsuler de longues lignes par défaut, du moins ici sous Windows).
Voici mon fichier .gitconfig (cela permet au script différent de résider dans le référentiel de mon projet):
[diff "xlsx"]
binary = true
textconv = python `git rev-parse --show-toplevel`/src/util/git-xlsx-textconv.py
si vous voulez que le script soit disponible pour de nombreux dépôts différents, utilisez ce qui suit:
[diff "xlsx"]
binary = true
textconv = python C:/Python27/Scripts/git-xlsx-textconv.py
mon fichier .gitattributes:
*.xlsx diff=xlsx
Une chose que vous pouvez faire est d’avoir l’extrait suivant dans votre classeur:
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
J'ai trouvé cet extrait sur Internet.
Ensuite, vous pouvez utiliser Subversion pour maintenir le contrôle de version. Par exemple, en utilisant l'interface de ligne de commande de Subversion avec la commande 'Shell' dans VBA. Cela le ferait. Je pense même à le faire moi-même :)
Si vous envisagez de créer un environnement de bureau avec des utilisateurs non techniques habituels, Sharepoint constitue une alternative viable. Vous pouvez configurer des dossiers de documents avec le contrôle de version activé, ainsi que des vérifications et des extractions. Rend le freindlier pour les utilisateurs de bureau réguliers.
en réponse à la réponse de mattlant - sharepoint fonctionnera bien comme contrôle de version uniquement si la fonctionnalité de contrôle de version est activée dans la bibliothèque de documents . De plus, sachez que tout code appelant d'autres fichiers par des chemins relatifs ne fonctionnera pas. et enfin, tous les liens vers des fichiers externes se briseront lorsqu'un fichier est enregistré dans SharePoint.
Utilisez l’un des outils de contrôle de version standard tels que SVN ou CVS. Les limitations dépendent de l'objectif. Mis à part une petite augmentation de la taille du référentiel, je n'ai rencontré aucun problème.
En réalité, il n’existe que très peu de solutions pour suivre et comparer les modifications du code macro, la plupart d’entre elles étant déjà nommées ici. J'ai navigué sur le Web et suis tombé sur ce nouvel outil qui mérite d'être mentionné:
XLTools Version Control pour les macros VBA
Les versions du code VBA côte à côte, les modifications sont visualisées
Après avoir recherché des âges et essayé de nombreux outils, j'ai trouvé ici ma réponse au problème du contrôle de version vba: https://stackoverflow.com/a/25984759/2780179
C'est un simple complément Excel pour lequel le code peut être trouvé ici
Il n'y a pas de modules en double après l'importation. Il exporte votre code automatiquement, dès que vous enregistrez votre classeur, sans modifier aucun classeur existant . Il est fourni avec un formateur de code vba.
Je voudrais recommander un excellent outil open-source appelé Rubberduck qui intègre le contrôle de version du code VBA. Essayez-le!
J'ai aussi étudié cela. Il semble que le dernier Team Foundation Server 2010 ait un complément Excel.
Voici un indice:
http://team-foundation-server.blogspot.com/2009/07/tf84037-there-was-problem-initializing.html
Vous devriez essayer DiffEngineX. Il peut être appelé par programme et également à partir de la ligne de commande en utilisant des arguments de ligne de commande. Il compare non seulement les cellules de feuille de calcul Excel, mais également les macros Visual Basic incorporées dans les classeurs. Compare également les noms définis par Excel et les commentaires, ce que de nombreux outils gratuits ignorent. Il peut être téléchargé à partir de
http://www.florencesoft.com/Excel-differences-download.html
Je suis sûr que votre système de contrôle de version dispose d'une option ou d'une boîte vous permettant d'appeler automatiquement DiffEngineX avec vos classeurs Excel originaux et modifiés.
Vous avez peut-être essayé d'utiliser le format XML Excel de Microsoft dans le conteneur Zip (.xlsx et .xslm) pour le contrôle de version et vous avez trouvé que la vba était stockée dans vbaProject.bin (ce qui est inutile pour le contrôle de version).
La solution est simple.
Lorsque vous répétez cette opération avec la prochaine version de la feuille de calcul, vous devez vous assurer que les fichiers du dossier correspondent exactement à ceux du conteneur Zip (et ne laissez aucun fichier supprimé derrière vous).
J'ai trouvé une solution très simple à cette question qui répond à mes besoins. J'ajoute une ligne au bas de toutes mes macros, qui exporte un fichier *.txt
avec le code de macro entier à chaque exécution. Le code:
ActiveWorkbook.VBProject.VBComponents("moduleName").Export"C:\Path\To\Spreadsheet\moduleName.txt"
(Trouvé sur Les didacticiels de Tom , qui couvre également certaines configurations dont vous pourriez avoir besoin pour que cela fonctionne.)
Comme je vais toujours lancer la macro chaque fois que je travaille sur le code, je suis assuré que git enregistrera les modifications. La seule partie ennuyante est que si je dois extraire une version antérieure, je dois copier/coller manuellement à partir du *.txt
dans la feuille de calcul.
Il existe également un programme appelé Beyond Compare qui contient un fichier Excel plutôt sympa. J'ai trouvé une capture d'écran en chinois qui montre brièvement ceci:
Il y a un essai de 30 jours sur leur page
Voici un projet GitHub qui ne résout que les points 1. et 4. de la question du PO: https://github.com/ColmBhandal/VbaMisc . C'est une solution VC pour les modules VBA uniquement. Il peut être facilement personnalisé pour tout projet en répliquant la structure de projet vue sur GitHub et en ajoutant les modules à placer sous VC à une liste blanche définie dans le module ExportImport. Ce module contrôle l’exportation et l’importation d’une liste blanche de modules VBA, s’incluant éventuellement. Voir le repo GitHub pour des instructions sur l'utilisation.
Mon entreprise travaille énormément à l'automatisation des solutions Microsoft Office. J'ai donc écrit un fichier .DLL qui exportera la source d'une solution chaque fois qu'un modèle est enregistré. Il crée un dossier nommé Source en tant qu'enfant du dossier dans lequel le modèle est enregistré, et sous Source, il crée un dossier du même nom que le projet VBA. Dans le dossier du projet, il exporte tout le code source des modules, des classes et des formulaires utilisateur. Cet arrangement a été choisi pour faciliter la gestion de la source pour de grandes collections de modèles. La DLL peut déverrouiller les projets verrouillés pour accéder au projet VBA si un fichier de configuration local ou un fichier de configuration global est disponible. Avec cet outil, les développeurs peuvent travailler sur des modèles à leur contenu et utiliser leur outil de contrôle de révision favori pour gérer leur travail. Nous utilisons Git principalement dans notre environnement et nous gardons les fichiers binaires du modèle complet ainsi que les ressources VBA sous contrôle de révision.