我正在尝试从另一个工作簿上的一个工作簿运行VBA宏 我正在使用Microsoft.Office.Interop.Excel(或等效)对象(如果要使用它,请将引用(COM)添加到Microsoft Excel 12.0对象库)来编辑和使用C#可执行文件中的Excel文档。
例如,文档1中包含一些数据。文档2包含格式化文档一的宏。文档一是每天都是新的,所以我不能在那里存储宏。我尝试使用Excel.Application.Run()在文档一中运行文档二中的宏。
我使用的示例宏很简单(存储在Microsoft Excel对象:ThisWorkbook中):
Sub Test()
Sheets("Sheet1").Select
Range("A1").Value = 32
End Sub
我需要在不同的工作簿上运行它。我可以使用以下代码在同一工作簿上运行它:
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();
}
当我将xlApp.Workbooks.Open中的DocumentTwoLocation更改为DocumentOneLocation时,宏将不会运行。抛出一个COMException(HRESULT:0x800A03EC),这是NameNotFound(仅在使用xlApp.Run()时抛出)。文件地址是正确的。即使我事先打开这两份文件:
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();
}
仍然出现错误(相同的0x800A03EC异常)。
MSDN几乎没有关于我遗漏的内容或如何处理此问题的文档(https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.applicationclass.run.aspx)
这里有类似的问题: Error when calling Excel macro from C# 并且我已尽我所能来匹配他们所写的内容(包括添加ReleaseComObject,并在之后设置为null)但无济于事。
答案 0 :(得分:1)
我已经解决了这个问题。
问题出现的原因是试图运行" xlsm"格式宏在不同的文档上。只能使用Microsoft Office Excel二进制工作表(xlsb格式)在另一个工作簿上运行宏。如果您遇到同样的问题 - 请使用xlsb保存宏,而不是xlsm。
对于您感兴趣的人,最终代码如下:
/// <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;
}
}