【问题标题】:Returning value from Excel VBA function is always nullExcel VBA 函数的返回值始终为空
【发布时间】:2019-09-29 09:48:09
【问题描述】:

我正在尝试运行 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); }
}

【问题讨论】:

  • This says 在模块中比在工作表中效果更好,但我个人不知道。

标签: c# excel vba excel-interop


【解决方案1】:

用作 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 - 但这是另一天的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    相关资源
    最近更新 更多