Search code examples
c#excelnpoivba

Change macros text in Excel programmatically


I've got about thousand of Excel (xls, old format) files spread out across many folders on the hard-drive. These files have the same macros that connects to a database. And the macros contains connection string. Macros is password protected, but luckily I know the password.

Question: what is the best way to change the connection string in macros inside all the files?

I have experience of working with NPOI to create/modify xls files. I have seen Interop libraries unlocking password-protected Word files and doing some editing. But I have never seen examples of programmatically changing of the macros text inside Excel file. Is that even possible?

p.s. I don't have problems writing code. The problem is choosing the right tools.


Solution

  • You might want use the following code as a starting point. This code uses COM Interop to extract the VBA script and perform a find-replace. I tried this out on a password-protected spreadsheet with a very basic script and it worked well. It is, admittedly, basic, but you may be able to extract what you need.

    string filename = "Test.xls";
    string password = "password";
    
    Excel._Application app = new Excel.Application();
    Excel._Workbook workbook = app.Workbooks.Open(Filename: filename, Password: password);
    
    if (workbook.HasVBProject)
    {
        VBProject project = workbook.VBProject;
    
        foreach (VBComponent component in project.VBComponents)
        {
            if (component.Type == vbext_ComponentType.vbext_ct_StdModule ||
                component.Type == vbext_ComponentType.vbext_ct_ClassModule)
            {
                CodeModule module = component.CodeModule;
    
                string[] lines =
                    module.get_Lines(1, module.CountOfLines).Split(
                        new string[] { "\r\n" },
                        StringSplitOptions.RemoveEmptyEntries);
    
                for (int i = 0; i < lines.Length; i++)
                {
                    if (lines[i].Contains("A1"))
                    {
                        lines[i] = lines[i].Replace("A1", "D1");
                        module.ReplaceLine(i + 1, lines[i]);
                    }
                }
            }
        }
    }
    
    workbook.Save();
    workbook.Close();
    app.Quit();