从Excel VBA函数返回的值始终为null

时间:2019-05-12 00:34:26

标签: c# excel vba excel-interop

我试图运行excel vba宏并获取结果,但我总是返回null(对我的无知,我是这个宏的新手)

Public Function TestMacro() As Boolean
    If Len(Range("A1").Value) <> 9 Then
        TestMacro = False
    Else
        TestMacro = True
    End If
End Function

调用它的C#代码

Excel.Application excelApp = new Excel.Application { DisplayAlerts = false };
object misValue = Missing.Value;
excelApp.Visible = false;
Excel.Workbook ExcelWorkBook = excelApp.Workbooks.Open(filePath);
try
{
    var result = excelApp.Run("Sheet1.TestMacro");
    ExcelWorkBook.Close(false, misValue, misValue);
}
catch (Exception e)
{
    Console.WriteLine(e);
}
finally
{
    excelApp.Quit();
    if (ExcelWorkBook != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelWorkBook); }
    if (excelApp != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp); }
}

1 个答案:

答案 0 :(得分:0)

要用作UDF(用户定义函数)的函数必须位于模块中,而不是工作簿对象(如工作表)中。

此外,在可能的情况下,您的UDF不应触发任何用户交互(例如MessageBox)。请记住,您的UDF可以在任何阶段重新计算(很好,使用了容易理解的触发器,有时甚至是不太了解的触发器),并且您不希望用户在明显的无穷循环中被消息框淹没(例如,尝试在UDF中使用消息框)然后可以复制到1000个单元中!)

当我执行VBA编码时,我创建一个名为(想象中!)“ UDF”的模型,其中存储了所有UDF。这使我更容易理解哪些功能是后端代码的一部分,以及哪些功能专门设计用于前端。

最重要的是,UDF代表一种功能-简单的输入而只有一个输出。以下示例应放在模块中:

Option Explicit

Public Function TestMacro(inputcell as range) As Boolean
    If Len(inputcell.Value) <> 9 Then
        TestMacro = False
    Else
        TestMacro = True
    End If
End Function

在单元格中(不是A1,您要在其中获得结果的单元格):

=TestMacro(A1)

您可以做一些更复杂的事情,包括其他错误检查并返回Excel错误,例如#Value#Ref#Name,但这又是一个问题。