Reputation: 1752
I am trying to run a VBA macro from one workbook on another workbook.
I am using the Microsoft.Office.Interop.Excel (or equivalent) object (add a reference (COM) to Microsoft Excel 12.0 Object Library if you want to use it) to edit and use Excel documents from a C# executable.
For example, document one has some data in it. Document two contains macros to format document one. Document one is new every day, so I can't store the macros there. I'm trying to run a macro from document two on document one using the Excel.Application.Run().
The example macro I'm using is simple (stored in the Microsoft Excel Object: ThisWorkbook):
Sub Test()
Sheets("Sheet1").Select
Range("A1").Value = 32
End Sub
I need this to run on a different workbook. I can run it on the same workbook with the following code:
Application xlApp = new Application(); //Excel app
Workbook xlWbk = null;
try
{
xlWbk = xlApp.Workbooks.Open(DocumentTwoLocation);
xlApp.Run("'" + DocumentTwoLocation + "'!" + MacroName); //MacroName example: ThisWorkbook.Test
}
finally
{
if (xlWbk != null)
try
{
xlWbk.Close(true); //Saves changes
}
catch
{
xlWbk.Close(false);
}
xlApp.Quit();
}
When I change DocumentTwoLocation in the xlApp.Workbooks.Open to DocumentOneLocation, the macro will not run. A COMException is thrown (HRESULT: 0x800A03EC) which is NameNotFound (only thrown when the xlApp.Run() is used). The file addresses are correct. Even if I open both documents beforehand like so:
Application xlApp = new Application(); //Excel app
Workbook xlWbk = null;
Workbook xlMacroBook = null;
try
{
xlWbk = xlApp.Workbooks.Open(DocumentOneLocation);
xlMacroBook = xlApp.Workbooks.Open(DocumentTwoLocation);
xlApp.Run("'" + DocumentTwoLocation + "'!" + MacroName); //MacroName example: ThisWorkbook.Test
}
finally
{
if (xlWbk != null)
try
{
xlWbk.Close(true); //Saves changes
}
catch
{
xlWbk.Close(false);
}
if (xlMacroBook != null)
xlMacroBook.Close(false) //Don't save changes
xlApp.Quit();
}
An error still occurs (same 0x800A03EC exception).
MSDN has virtually no documentation on what I am missing or how I should approach this (https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.applicationclass.run.aspx)
Something similar has been asked here: Error when calling Excel macro from C# and I've done all I can to match what they have written (including adding the ReleaseComObject, and setting to null after) but to no avail.
Upvotes: 3
Views: 2001
Reputation: 1752
I have since solved the issue.
The issue occuring was as a result of trying to run an "xlsm" format macro on a different document. Running macros on another workbook is only possible with Microsoft Office Excel Binary Worksheet (xlsb format). If you're facing the same issue - use an xlsb to save the macros in, not xlsm.
For those of you interested, the final code is as follows:
/// <summary>
/// Run a macro from an xlsb file on another excel file
/// </summary>
/// <param name="ExcelFile">The excel file to run the macro on</param>
/// <param name="MacroFileLocation">The xlsb file the macro is saved in</m>
/// <param name="Macro">The macro name to run (e.g. Module1.Example)</param>
static void Test(string ExcelFile, string MacroFileLocation, string Macro)
{
Application xlApp = new Application(); //Excel app
Workbook xlWbk = null;
try
{
xlWbk = xlApp.Workbooks.Open(ExcelFile);
string MacroCommand = "'" + MacroFileLocation + "'!" + Macro;
xlApp.Run(MacroCommand);
}
finally
{
//Clean up
if (xlWbk != null)
try
{
xlWbk.Close(true);
}
catch
{
//Couldn't save - consider alerting user
xlWbk.Close(false);
}
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWbk);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
xlWbk = null;
xlApp = null;
}
}
Upvotes: 3