在其他工作簿上运行 Excel 宏

本文关键字:Excel 运行 其他 工作簿 | 更新日期: 2023-09-27 18:35:28

我正在尝试从另一个工作簿上的一个工作簿运行VBA宏。
我正在使用 Microsoft.Office.Interop.Excel(或等效对象)对象(如果要使用它,请向 Excel 12.0 对象库添加引用 (COM Microsoft)来编辑和使用来自 C# 可执行文件的 Excel 文档。

例如,文档 1 中包含一些数据。文档二包含用于格式化文档一的宏。文档一每天都是新的,所以我无法将宏存储在那里。我正在尝试使用 Excel.Application.Run() 从文档 1 上的文档 2 运行宏。

我使用的示例宏很简单(存储在 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)

这里也问过类似的事情:从 C# 调用 Excel 宏时出错我已经尽我所能来匹配他们所写的内容(包括添加 ReleaseComObject,并在之后设置为 null),但无济于事。

在其他工作簿上运行 Excel 宏

我已经解决了这个问题。

出现的问题是由于尝试在其他文档上运行"xlsm"格式宏。只能在另一个工作簿上运行宏只能使用 Office Excel 二进制工作表(xlsb 格式)Microsoft。如果您遇到同样的问题 - 使用 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;
    }
}