在哪里为自定义功能区编写回调函数

where to write callback functions for custom ribbon

我有一个自定义功能区,它只有 1 个按钮作为测试,当我在 onAction 属性中使用宏时它工作得很好但是当我添加一个正常的回调函数时我写它就是找不到它。 所以问题是在哪里编写这些回调(在我的例子中,我制作了一个模块并将我的回调函数设为该模块中的 public 子)。

这里是 xml 代码:

    <Relationship Id="customUIRelID" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
    <ribbon startFromScratch="true">
        <tabs>
            <tab id="CustomTab" label="My Tab">
                <group id="SimpleControls" label="My Group">
                    <button id="Button1" imageMso="HappyFace" size="large" label="Large Button" onAction="ribbonOpenForm"/>
                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI> 

回调函数为:

Public Sub ribbonOpenForm(control As IRibbonControl)
    Dim formName As String
    formName = control.Tag
    If formName = "" Then
        MsgBox "No Name"
        Exit Sub
    End If
    DoCmd.OpenForm formName
End Sub

当我在 xml 代码中添加一个 smale 编辑时:onAction="ribbonOpenForm" 我收到一个新错误。

第一个错误:

编辑后的错误:

如果您不熟悉管理来自 RibbonX 的回调,我建议您使用 Case 语句方法

C考虑以下内容

改变

<button id="Button1" imageMso="HappyFace" size="large" label="Large Button" onAction="ribbonOpenForm"/>

<button id="OpenForm" imageMso="HappyFace" size="large" label="Large Button" onAction="Button_OnAction"/>

并假设我们还有一些其他按钮

<button id="OpenForm2" imageMso="HappyFace" size="large" label="Large Button" onAction="Button_OnAction"/>
<button id="OpenForm3" imageMso="HappyFace" size="large" label="Large Button" onAction="Button_OnAction"/>
<button id="OpenForm4" imageMso="HappyFace" size="large" label="Large Button" onAction="Button_OnAction"/>

在 VBA 你会写

Public Function Button_OnAction(byRef Control as IRibbonCOntrol,BYVal pressed as Boolean)

    Select Case Control.Id

        Case "OpenForm1"

             ' Do open form 1 stuff

        Case "OpenForm2"
  
               ' Do open Form 2 stuff

        Case "Open Form3"

               ' Do open form 3 stuff
        Case "Open form 4
 
               ' do open form 4 stuff

        Else

    End Select

End Sub

我们的想法是,每种 object/action 类型只有一个回调,然后通过控件 ID 进行区分。

通过这种方式,您可以将模块专用于每种类型的对象、按钮、tohggle 按钮、下拉列表等。每个对象模块都将具有相同的前缀,用于对象所需的回调

例如,模块 CheckBoxCallbacks 将有

的 Sub
togglebutton_getPressed
toggleButton_onAction

DropDownCallbacks 的模块将有 subs

DropDown_getItemCount
DropDown_GetItemLabel
DropDown_getSelectedItem
DropDown_onAction

等等等等

嗯,第一个也是最好的答案?不要使用回调。使用回调的最大缺点当然是您编写的代码必须位于标准的全局代码模块中。这样的代码不能是表单代码模块。 考虑到按钮,甚至自定义菜单栏(过去)在大多数情况下都会在表单中执行 运行 代码?那么按理说,您想对自定义功能区执行相同的操作 - 特别是针对给定表单的功能区。

所以,ribbon中的一个回调函数是这样定义的:

 onAction="MyDelete"

然后你需要一个标准代码模块中的 Public sub(注意我说的是 Public Sub)。这样的代码不能放在表单代码模块中(正如我在大多数情况下指出的那样,它属于并且需要)。

但是,当您放置按钮、自定义菜单栏甚至宏代码(不是 VBA)时,您可以让那个“东西”在表单代码模块中执行代码!!!

你这样做的方法是使用这样的表达式:

onAction="=MyDelete()"

请注意“=”符号和 () 的使用。现在?

您不需要回调函数 - 您只需将这段代码放在 CURRENT 形式的代码模块中:

Public Function MyDelete()

  dim lngID as Long
  lngID = me!id
  bla bla bla.

但是,它变得更好了。另一个很棒的功能是您可以将值传递给函数。

所以,你可以这样说:

<button id="MyDelete" label="Delete Record"
    imageMso="Delete" size="large"
    onAction="=MyDelete('Staff','tblStaff')"
    supertip="Delete this record"
 />

而我们的 public 函数形式可能是这样的:

Public Function MyDelete(strPrompt As String, strTable As String)
  Dim strSql        As String
  Dim f             As Form
  Set f = Screen.ActiveForm
  If MsgBox("Delete this " & strPrompt & " record?", _
                vbQuestion + vbYesNoCancel, "Delete?") = vbYes Then

      currentdb.Execute "DELETE * from " & strTable & " WHERE ID = " & me!id

所以在上面,我们传递了“提示文本”和 table 名称。现在上面有点蹩脚,因为如果代码已经在当前表单中,那么你当然可以删除当前记录 - 但它展示了我们如何将值从功能区传递到函数的想法。

奖金部分!!!!

如果表单中不存在公共函数,则在标准(非表单)代码模块中具有相同名称的全局 public 函数是 运行。因此,实际上,您可以有 5 种形式——删除代码可以是一个全局函数,但一种有特殊需要的形式只是在 FORMS 代码模块中有一个同名的 public 函数——它将 运行 如果在表格中找到。

值得注意的是,使用 =MyPublicFunctionNameGoesHere()

也是右键单击和自定义菜单栏使用的完全相同的格式。那么,如果您要将现有的菜单条码转换为功能区?您使用相同的函数和语法 - 您的所有代码都保留在给定的形式中。和菜单栏一样,如果窗体中不存在该函数,则使用同名的全局函数。因此,您可以再次构建一个菜单(或功能区),该菜单(或功能区)“主要”使用所有相同的功能,例如删除或添加记录,但对于具有不同需求的特殊表单,您可以将这些功能放在表单中 - 这样功能区可以在功能区中具有相同“选项”的许多不同表单上工作 - 但是非常不同的代码将 运行 基于当前打开并具有焦点的表单。

因此,如果您使用格式“=MyPublicFunction()”,那么您不需要也不会使用回调,更好的是,函数名称现在可以放在表格。

如前所述,如果您使用回调,则此类代码(子代码)不能放在当前表单代码模块中 - 它必须放在标准代码模块中。函数调用不是这样 - 它们可以自由地放置在表单代码模块中,或者放在全局代码模块中。