How to put Excel VBA into git

后端 未结 4 585
眼角桃花
眼角桃花 2020-12-18 19:46

I\'ve inherited some VBA in Excel and want to put it into git. As it stands, git sees it as binary and doesn\'t want to do file change deltas but duplicate the whole file. <

相关标签:
4条回答
  • 2020-12-18 20:28

    If you use Rubberduck VBA, after clicking

    You can use the file menu to "Export Active Project", which exports the form binaries and the code as BAS objects, which are just plain text. Then you can commit to git.

    0 讨论(0)
  • 2020-12-18 20:29

    You should be able to export modules as text to a git folder then commit as follows.

    In The VBA Editor Add modules for each macro (Menu Insert/Module) copy each macros code into a module and save as a text file with control + E. Save into your git folder and use the normal git procedures to commit any changes.

    When you change the vba code re save (control+E) the module and update git as normal.

    0 讨论(0)
  • 2020-12-18 20:36

    I had this problem and solved it by creating a VBA module to export other VBA modules. Usage instructions for this, and the raw code, can be found at the following location:

    https://github.com/ColmBhandal/VbaSync.

    C# Alternative

    There is a C# alternative for putting VBA under Excel version control. The code has been added to a C# library which can be used to do version control e.g. via a CLI tool or via a VSTO AddIn:

    https://gitlab.com/hectorjsmith/csharp-excel-vba-sync

    Disclaimer

    I was involved in the coding of the above repos. They are both free to use and open source.

    0 讨论(0)
  • 2020-12-18 20:42

    You can create a git pre-commit hook that runs the following Python script to automatically extract your VBA code and add it to your commit (see https://www.xltrail.com/blog/auto-export-vba-commit-hook):

    import os
    import shutil
    from oletools.olevba3 import VBA_Parser
    
    
    EXCEL_FILE_EXTENSIONS = ('xlsb', 'xls', 'xlsm', 'xla', 'xlt', 'xlam',)
    
    
    def parse(workbook_path):
        vba_path = workbook_path + '.vba'
        vba_parser = VBA_Parser(workbook_path)
        vba_modules = vba_parser.extract_all_macros() if vba_parser.detect_vba_macros() else []
    
        for _, _, _, content in vba_modules:
            decoded_content = content.decode('latin-1')
            lines = []
            if '\r\n' in decoded_content:
                lines = decoded_content.split('\r\n')
            else:
                lines = decoded_content.split('\n')
            if lines:
                name = lines[0].replace('Attribute VB_Name = ', '').strip('"')
                content = [line for line in lines[1:] if not (
                    line.startswith('Attribute') and 'VB_' in line)]
                if content and content[-1] == '':
                    content.pop(len(content)-1)
                    lines_of_code = len(content)
                    non_empty_lines_of_code = len([c for c in content if c])
                    if non_empty_lines_of_code > 0:
                        if not os.path.exists(os.path.join(vba_path)):
                            os.makedirs(vba_path)
                        with open(os.path.join(vba_path, name + '.bas'), 'w') as f:
                            f.write('\n'.join(content))
    
    
    if __name__ == '__main__':
        for root, dirs, files in os.walk('.'):
            for f in dirs:
                if f.endswith('.vba'):
                    shutil.rmtree(os.path.join(root, f))
    
            for f in files:
                if f.endswith(EXCEL_FILE_EXTENSIONS):
                    parse(os.path.join(root, f))
    

    For further details, have a look at https://www.xltrail.com/blog/auto-export-vba-commit-hook.

    0 讨论(0)
提交回复
热议问题