Search code examples
excelmsbuildbuild-automationxlavba

Change .xla File with MSBuild


I'm trying to create a build script for my current project, which includes an Excel Add-in. The Add-in contains a VBProject with a file modGlobal with a variable version_Number. This number needs to be changed for every build. The exact steps:

  1. Open XLA document with Excel.
  2. Switch to VBEditor mode. (Alt+F11)
  3. Open VBProject, entering a password.
  4. Open modGlobal file.
  5. Change variable's default value to the current date.
  6. Close & save the project.

I'm at a loss for how to automate the process. The best I can come up with is an excel macro or Auto-IT script. I could also write a custom MSBuild task, but that might get... tricky. Does anyone else have any other suggestions?


Solution

  • An alternative way of handling versioning of an XLA file is to use a custom property in Document Properties. You can access and manipulate using COM as described here: http://support.microsoft.com/?kbid=224351.

    Advantages of this are:

    • You can examine the version number without opening the XLA file

    • You don't need Excel on your build machine - only the DsoFile.dll component

    Another alternative would be to store the version number (possibly other configuration data too) on a worksheet in the XLA file. The worksheet would not be visible to users of the XLA. One technique I have used in the past is to store the add-in as an XLS file in source control, then as part of the build process (e.g. in a Post-Build event) run the script below to convert it to an XLA in the output directory. This script could be easily extended to update a version number in a worksheet before saving. In my case I did this because my Excel Add-in used VSTO, and Visual Studio doesn't support XLA files directly.

    '
    '   ConvertToXla.vbs
    '
    '   VBScript to convert an Excel spreadsheet (.xls) into an Excel Add-In (.xla)
    '
    '   The script takes two arguments:
    '
    '   - the name of the input XLS file.
    '
    '   - the name of the output XLA file.
    '
    Option Explicit
    Dim nResult
    On Error Resume Next
    nResult = DoAction
    If Err.Number <> 0 Then 
        Wscript.Echo Err.Description
        Wscript.Quit 1
    End If
    Wscript.Quit nResult
    
    Private Function DoAction()
    
        Dim sInputFile, sOutputFile
    
        Dim argNum, argCount: argCount = Wscript.Arguments.Count
    
        If argCount < 2 Then
            Err.Raise 1, "ConvertToXla.vbs", "Missing argument"
        End If
    
        sInputFile = WScript.Arguments(0)
        sOutputFile = WScript.Arguments(1)
    
        Dim xlApplication
    
        Set xlApplication = WScript.CreateObject("Excel.Application")
        On Error Resume Next 
        ConvertFileToXla xlApplication, sInputFile, sOutputFile
        If Err.Number <> 0 Then 
            Dim nErrNumber
            Dim sErrSource
            Dim sErrDescription
            nErrNumber = Err.Number
            sErrSource = Err.Source
            sErrDescription = Err.Description
            xlApplication.Quit
            Err.Raise nErrNumber, sErrSource, sErrDescription
        Else
            xlApplication.Quit
        End If
    
    End Function
    
    Public Sub ConvertFileToXla(xlApplication, sInputFile, sOutputFile)
    
        Dim xlAddIn
        xlAddIn = 18 ' XlFileFormat.xlAddIn
    
        Dim w
        Set w = xlApplication.Workbooks.Open(sInputFile,,,,,,,,,True)
        w.IsAddIn = True
        w.SaveAs sOutputFile, xlAddIn
        w.Close False
    End Sub