使用.onAction传递VBA参数

8
这是我的子菜单的样子:
Sub InsertRowWithContent(rowNo As Long)

这是我的.onAction:
.OnAction = "'InsertRowWithContent""" & C & """'"

之前已经声明了一个长整型变量C。

现在出现“未找到宏”的错误。在添加参数之前,它能够正常工作!


我应该先问一下。我的答案背景是Access。 Djikay的回答是从Excel的角度来看的。你问题里的标签是Word。因此这些应用程序在细节方面可能会有显着差异。你用哪个应用程序,用的是哪个版本?-还有一个测试:你能否从“立即窗口”调用InsertRowWithContent (123)?也许它在不可见的范围内(例如其他表/文档和私人)。 - peter_the_oak
我正在使用Word 2010。你所说的从即时窗口调用它是什么意思? - justry
如果你的意思是我从同一个模块中调用它,那么是的。我在一个Word文档中有一个按钮,当点击它时会显示一个弹出菜单,该菜单由来自Excel表格的项目填充。当点击其中一个菜单项时,即当它们的.onAction被激活时,它们应该调用insertRowWithContent方法,同时传递与该项目编号对应的参数。 - justry
我找到了一个看起来很稳健的解决方案。再看一下吧。祝你好运 :-) - peter_the_oak
2个回答

11

我已经成功使用这个语法传递了参数:

.OnAction = "=InsertRowWithContent(" & C & ")"

注意事项:

  • C 是一个 long 类型。所以不要加引号,就像你在代码中调用 Sub 时不会加一样。
  • OnAction 评估一个表达式。据我的经验,该表达式需要有一个等号,而且它必须是一个函数。只有自动化本地回调是 Sub。

编辑

我上面的答案是基于 Access 的背景。Djikay 的答案在 Excel 中也可以工作。但是经过一些调查,我很确定 Word 简单地不理解这些语法中的任何一种。Word VBA 不能将参数传递给一个在 OnAction 语句中的 Sub。至少目前最好接受这一点。

但是以下内容明确适用于 Word(2010):

创建您的命令栏和按钮。对于 OnAction,只传递 Sub 的名称。但使用按钮的 Parameter 属性。

' Add bar
Set cdb = Application.CommandBars.Add("SomeTest", , False, False)
cdb.Visible = True

' Add button
Set cbb = cdb.Controls.Add
cbb.Caption = "PressMe"
cbb.OnAction = "TheCallback"
cbb.Parameter = 456

然后,通过 CommandBars.ActionControl.Parameter 表达式访问参数:

Public Sub TheCallback()

  MsgBox "The parameter passed is: " & CommandBars.ActionControl.Parameter

End Sub

ActionControl与Access下的ActiveControl非常相似(如果不是完全相同),它是上次被单击的控件。

来源:http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_24982922.html

*phuu* :-)


我不明白。我的项目肯定还有其他问题。它也无法工作。 - justry
看起来这个方法实际上会奏效。不幸的是,我现在离我的电脑有些远,但当我回来后大约30分钟左右我会尝试一下。我确实读过这个参数属性,但我没有想到你必须要专门访问它,我以为它只是将参数放在括号之间的另一种选择。 - justry
兄弟,你太牛了!!我已经做了好几个小时了!我欠你一个人情! - justry
很高兴能帮忙 :-) ...我也很惊讶在多个Office程序中相比,事件处理是多么的复杂。祝你好运... - peter_the_oak

10
您需要在Sub名称后添加一个空格,像这样:

您需要在Sub名称后添加一个空格,像这样:

.OnAction = "'InsertRowWithContent " & C & "'"
                                  ^^^^^^^^^^

编辑

此外,由于您正在传递一个Long参数,因此不应将其放在引号中。

编辑2

好的,这将需要一些特殊的代码。我已经进行了实验,并让以下内容起作用。

在Sheet1 Excel对象中:

Option Explicit

Sub DestroyToolbar()

  Application.CommandBars("DoomBar").Delete

End Sub

Sub MakeToolbar()

  Dim C As Long
  C = 100

  With Application
    .CommandBars.Add(Name:="DoomBar").Visible = True
    With .CommandBars("DoomBar")
      .Controls.Add Type:=msoControlButton, ID:=2950, Before:=1
      With .Controls(1)
        .OnAction = "'PressMe " & C & "'"
      End With
    End With
  End With

End Sub

在新的标准代码模块中,添加以下内容:
Public Sub PressMe(C As Long)

  With Application.CommandBars("DoomBar")
    With .Controls(1)
      MsgBox "The value of C that was passed to this macro is: " & C
    End With
  End With

End Sub

如果您运行MakeToolbar,它将在“插件”选项卡中创建一个新的工具栏。要删除它,可以运行DestroyToolbar
一旦工具栏就位,然后点击按钮应该显示一个消息框,其中包含C的值(在我的示例中为100)。
我已经在Excel 2010中进行了测试,并且在全新的.xlsm文件中起作用。

没用。我想我之前试过那个了。 - justry
@Mohamed:我已经添加了另一个更新,这次附带完整的代码。 - djikay
好的,当我将您的代码复制到新的xlsm文件中时,它可以正常工作,但是当我尝试使用.onAction行时,它仍然会给出“找不到宏”错误。除了代码之外,可能还有其他问题吗?两个子程序(一个设置.onAction,另一个由.onAction调用)都在标准模块中。 - justry
我没有冒太大的风险来添加工具栏... 但第一行中的空格确实帮了我一个大忙... 谢谢! - PravyNandas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接