【问题标题】:How to Call VBA Function from Excel Cells? [duplicate]如何从 Excel 单元格调用 VBA 函数? [复制]
【发布时间】:2013-10-26 00:54:41
【问题描述】:

我是 VBA 新手,我正在尝试编写一个可以从 Excel 单元格调用的函数,它可以打开一个已关闭的工作簿,查找一个单元格值并返回它。

到目前为止,我知道如何编写这样的宏:

Sub OpenWorkbook()
    Dim path As String
    path = "C:\Users\UserName\Desktop\TestSample.xlsx"

    Dim currentWb As Workbook
    Set currentWb = ThisWorkbook


    currentWb.Sheets("Sheet1").Range("A1") = OpenWorkbookToPullData(path, "B2")
End Sub


Function OpenWorkbookToPullData(path, cell)

    Dim openWb As Workbook
    Set openWb = Workbooks.Open(path, , True)

    Dim openWs As Worksheet
    Set openWs = openWb.Sheets("Sheet1")

    OpenWorkbookToPullData = openWs.Range(cell)

    openWb.Close (False)

End Function

宏 OpenWorkbook() 运行良好,但是当我尝试直接从 Excel 单元格调用 OpenWorkbookToPullData(...) 时,它不起作用。声明:

    Set openWb = Workbooks.Open(path, , True)

不返回任何内容。

有谁知道如何将其转换为可以从 Excel 单元格调用的有效 VBA 函数?

【问题讨论】:

  • 感谢您的帮助。 @pnuts我的问题不是一般如何编写VBA函数,而是在这里更具体。 OpenWorkbookToPullData(...) 确实被调用了,我可以介入。但问题出在 Workbooks.Open(...) 执行的那一行,它返回为 Nothing。调用 OpenWorkbookToPullData(...) 的子 OpenWorkbook() 工作正常。
  • 感谢@PortlandRunner 但是,从宏子 OpenWorkbook() 工作正常的意义上说,函数本身“工作”。问题不在于那里的语法。问题是,如果您从 Excel 单元格调用 OpenWorkbookToPullData(...),Workbooks.Open(...) 行将返回 Nothing。如果它是从子例程中调用的,它可以正常工作。
  • @PortlandRunner 不幸的是没有。即使通过 Excel 调用,字符串“path”也会正确传递到函数中。问题是方法调用 Workbooks.Open(...) 无论是从子例程还是从 Excel 单元格调用,其行为都不同。在前一种情况下,它可以工作。在后者中,它返回 Nothing。

标签: vba excel


【解决方案1】:

Here's the answer

要遵循的步骤:

  1. 打开 Visual Basic 编辑器。在 Excel 中,点击 Alt+F11 如果在 Windows 上,点击 Fn+Option+F11 如果在 Mac 上。

  2. 插入一个新模块。从菜单中:插入 -> 模块(不要跳过这个!)。

  3. 创建一个Public 函数。示例:

    Public Function findArea(ByVal width as Double, _
                             ByVal height as Double) As Double
        ' Return the area
        findArea = width * height
    End Function
    
  4. 然后在任何单元格中使用它,就像使用任何其他函数一样:=findArea(B12,C12)

【讨论】:

  • 我一输入第二个参数(高度)的值,它就会报告我的公式存在“一些一般性问题”,并拒绝将其存储在单元格中。不幸的是,它以德语报告,因此我无法在此处提供文本作为示例。
  • @Paul 没有错误消息、版本和环境详细信息,很难进一步深入研究
  • 通常我认为我可以做得更好,而不仅仅是按照说明进行操作。第 2 步很重要!
  • 并在函数顶部添加Application.Volatile,以便在修改依赖单元格时更新值
【解决方案2】:

你遇到的问题是UDFs不能修改Excel环境,只能给调用单元格返回一个值。

有几种选择

  1. 对于给定的示例,您实际上并不需要 VBA。这个公式会起作用
    ='C:\Users\UserName\Desktop\[TestSample.xlsx]Sheet1'!$B$2

  2. 使用相当混乱的解决方法:See this answer

  3. 您可以使用ExecuteExcel4MacroOLEDB

【讨论】:

  • @chrisneilson,谢谢。语法 ='filepath' 的问题是必须打开工作簿。周围有大约 100 个工作簿,我想要每个工作簿中的特定单元格。你有其他解决方法吗?我尝试了 ExecuteExcel4Macro,但这似乎也无法在 Excel 单元调用下运行。你有使用 OLEDDB 的例子吗?
  • 仅供参考,我正在查看选项 #2。看起来很有希望。您对如何修改它有任何提示吗?我不太确定如何修改它来做我想做的事......
  • 使用公式选项,wb 确实不需要 需要打开。这就是我将其包含在答案中的原因。
【解决方案3】:

函数不起作用,也没有必要:

Sub OpenWorkbook()
    Dim r1 As Range, r2 As Range, o As Workbook
    Set r1 = ThisWorkbook.Sheets("Sheet1").Range("A1")
    Set o = Workbooks.Open(Filename:="C:\TestFolder\ABC.xlsx")
    Set r2 = ActiveWorkbook.Sheets("Sheet1").Range("B2")
    [r1] = [r2]
    o.Close
End Sub

【讨论】:

  • 谢谢。我知道如何编写子程序,但我想要一个可以做同样事情的函数。如果您编写一个子例程,您或多或少必须对路径、单元格位置等进行硬编码。我正在尝试更新一些可以从我拥有的 100 个 Excel 工作簿中的每一个中提取几个单元格的内容,并且函数很多更灵活。
  • 我认为你能做的最好的是将文件规格、工作表名称和单元格地址存储在数组中,并在循环中运行类似于我的代码......祝你好运!
猜你喜欢
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多