Access 2016 Switchboard 将宏转换为 vba

Access 2016 Switchboard convert macro to vba

在 Access 2016 Switchboard 上,我将表单后面的宏转换为 VBA,但无法编译。我发现的创可贴解决方案是将 .Value 添加到 TempVars.Add "CurrentItemNumber", ItemNumber 并更改两个实例Call Argument & "()"Call Eval(Argument & "()")。这解决了编译错误。

然后我向总机添加了另一个按钮 "Reports Menu",但是当我点击新按钮时出现此错误。

当我单击“调试”时,它会突出显示此行 TempVars.Add "SwitchboardID",参数。当我将 .Value 添加到此行的末尾时 TempVars.Add "SwitchboardID", Argument.Value 它解决了断点问题和新按钮可以使用,但现在报告菜单无法正确填写。

我可以单击 Return 到主菜单返回主菜单,主菜单上的所有其他按钮都可以正常工作,除了新的报告菜单按钮。

这是交换机背后的代码...

    Option Compare Database

'------------------------------------------------------------
' Form_Current
'
'------------------------------------------------------------
Private Sub Form_Current()
On Error GoTo Form_Current_Err

  'TempVars.Add "CurrentItemNumber", ItemNumber
  TempVars.Add "CurrentItemNumber", ItemNumber.Value

Form_Current_Exit:
  Exit Sub

Form_Current_Err:
  MsgBox Error$
  Resume Form_Current_Exit

End Sub


'------------------------------------------------------------
' Form_Open
'
'------------------------------------------------------------
Private Sub Form_Open(Cancel As Integer)
On Error GoTo Form_Open_Err

  TempVars.Add "SwitchboardID", DLookup("SwitchboardID", "Switchboard Items", "[ItemNumber] = 0 AND [Argument] = 'Default'")
  DoCmd.SetProperty "Label1", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
  DoCmd.SetProperty "Label2", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
  DoCmd.Requery ""


Form_Open_Exit:
  Exit Sub

Form_Open_Err:
  MsgBox Error$
  Resume Form_Open_Exit

End Sub


'------------------------------------------------------------
' Option1_Click
'
'------------------------------------------------------------
Private Sub Option1_Click()
On Error GoTo Option1_Click_Err

  On Error GoTo 0
  If (Command = 1) Then
    'TempVars.Add "SwitchboardID", Argument
    TempVars.Add "SwitchboardID", Argument.Value
    DoCmd.SetProperty "Label1", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
    DoCmd.SetProperty "Label2", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
    DoCmd.Requery ""
    Exit Sub
  End If
  If (Command = 2) Then
    DoCmd.OpenForm Argument, acNormal, "", "", acAdd, acNormal
    Exit Sub
  End If
  If (Command = 3) Then
    DoCmd.OpenForm Argument, acNormal, "", "", , acNormal
    Exit Sub
  End If
  If (Command = 4) Then
    DoCmd.OpenReport Argument, acViewReport, "", "", acNormal
    Exit Sub
  End If
  If (Command = 5) Then
    DoCmd.RunCommand acCmdSwitchboardManager
    TempVars.Add "SwitchboardID", DLookup("SwitchboardID", "Switchboard Items", "[ItemNumber] = 0 AND [Argument] = 'Default'")
    DoCmd.SetProperty "Label1", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
    DoCmd.SetProperty "Label2", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
    DoCmd.Requery ""
    Exit Sub
  End If
  If (Command = 6) Then
    DoCmd.CloseDatabase
    Exit Sub
  End If
  If (Command = 7) Then
    DoCmd.RunMacro Argument, , ""
    Exit Sub
  End If
  If (Command = 8) Then
    'Call Argument & "()"
    Call Eval(Argument & "()")
    Exit Sub
  End If
  Beep
  MsgBox "Unknown option.", vbOKOnly, ""


Option1_Click_Exit:
  Exit Sub

Option1_Click_Err:
  MsgBox Error$
  Resume Option1_Click_Exit

End Sub


'------------------------------------------------------------
' OptionLabel1_Click
'
'------------------------------------------------------------
Private Sub OptionLabel1_Click()
On Error GoTo OptionLabel1_Click_Err

  On Error GoTo 0
  If (Command = 1) Then
    'TempVars.Add "SwitchboardID", Argument
    TempVars.Add "SwitchboardID", Argument.Value
    DoCmd.SetProperty "Label1", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
    DoCmd.SetProperty "Label2", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
    DoCmd.Requery ""
    Exit Sub
  End If
  If (Command = 2) Then
    DoCmd.OpenForm Argument, acNormal, "", "", acAdd, acNormal
    Exit Sub
  End If
  If (Command = 3) Then
    DoCmd.OpenForm Argument, acNormal, "", "", , acNormal
    Exit Sub
  End If
  If (Command = 4) Then
    DoCmd.OpenReport Argument, acViewReport, "", "", acNormal
    Exit Sub
  End If
  If (Command = 5) Then
    DoCmd.RunCommand acCmdSwitchboardManager
    TempVars.Add "SwitchboardID", DLookup("SwitchboardID", "Switchboard Items", "[ItemNumber] = 0 AND [Argument] = 'Default'")
    DoCmd.SetProperty "Label1", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
    DoCmd.SetProperty "Label2", acPropertyCaption, DLookup("ItemText", "Switchboard Items", "[SwitchboardID] = " & TempVars("SwitchboardID"))
    DoCmd.Requery ""
    Exit Sub
  End If
  If (Command = 6) Then
    DoCmd.CloseDatabase
    Exit Sub
  End If
  If (Command = 7) Then
    DoCmd.RunMacro Argument, , ""
    Exit Sub
  End If
  If (Command = 8) Then
    'Call Argument & "()"
    Call Eval(Argument & "()")
    Exit Sub
  End If
  Beep
  MsgBox "Unknown option.", vbOKOnly, ""


OptionLabel1_Click_Exit:
  Exit Sub

OptionLabel1_Click_Err:
  MsgBox Error$
  Resume OptionLabel1_Click_Exit

End Sub

如有任何建议,我们将不胜感激..

提前致谢。

对您的代码的一些批评:

  1. Call Eval(Argument & "()") 没有任何意义。 Call 是多余的; Eval(Argument & "()")才是真正调用Argument中的函数名。请尝试 Application.Run Me.Argument.Value
  2. 您应该在代码中完全指定所有控件值。示例:Me.Command.ValueMe.Argument.ValueMe.ItemNumber.Value
  3. 而不是 DoCmd.SetProperty "Label1", acPropertyCaption, "caption",使用:Me.Lable1.Caption = "caption"
  4. 在任何情况下,都不需要使用与 Label1 相同的 DLookup 函数来设置 Lable2。只需使用 Me.Label2.Caption = Me.Label1.Caption
  5. 而不是TempVars.Add "SwitchboardID", Argument,写成TempVars("SwitchboardID") = Me.Argument.Value
  6. 可能更简洁

这将帮助您实现目标,但我不能保证这会解决您的问题。您将不得不使用传统的调试方法找出其他可能出错的地方,并修复它。

我非常感谢您的回复,但由于时间限制,我放弃了尝试修复由 Access 2016(当它转换宏时)生成的代码,并从旧数据库的代码中获取 Switchboard。我相信该代码是使用 Access 2003 创建的,但它仍然可以完美运行(见下文)每个总机有 8 个按钮的限制,但对于大多数应用程序来说应该足够了。

Option Compare Database

Private Sub Form_Open(Cancel As Integer)
' Minimize the database window and initialize the form.

' Move to the switchboard page that is marked as the default.
Me.Filter = "[ItemNumber] = 0 AND [Argument] = 'Default' "
Me.FilterOn = True

End Sub

Private Sub Form_Current()
' Update the caption and fill in the list of options.

Me.Caption = Nz(Me![ItemText], "")
FillOptions

End Sub

Private Sub FillOptions()
' Fill in the options for this switchboard page.

' The number of buttons on the form.
Const conNumButtons = 8

Dim con As Object
Dim RS As Object
Dim stSql As String
Dim intOption As Integer

' Set the focus to the first button on the form,
' and then hide all of the buttons on the form
' but the first.  You can't hide the field with the focus.
Me![Option1].SetFocus
For intOption = 2 To conNumButtons
    Me("Option" & intOption).Visible = False
    Me("OptionLabel" & intOption).Visible = False
Next intOption

' Open the table of Switchboard Items, and find
' the first item for this Switchboard Page.
Set con = Application.CurrentProject.Connection
stSql = "SELECT * FROM [Switchboard Items]"
stSql = stSql & " WHERE [ItemNumber] > 0 AND [SwitchboardID]=" & Me![SwitchboardID]
stSql = stSql & " ORDER BY [ItemNumber];"
Set RS = CreateObject("ADODB.Recordset")
RS.Open stSql, con, 1   ' 1 = adOpenKeyset

' If there are no options for this Switchboard Page,
' display a message.  Otherwise, fill the page with the items.
If (RS.EOF) Then
    Me![OptionLabel1].Caption = "There are no items for this switchboard page"
Else
    While (Not (RS.EOF))
        Me("Option" & RS![ItemNumber]).Visible = True
        Me("OptionLabel" & RS![ItemNumber]).Visible = True
        Me("OptionLabel" & RS![ItemNumber]).Caption = RS![ItemText]
        RS.MoveNext
    Wend
End If

' Close the recordset and the database.
RS.Close
Set RS = Nothing
Set con = Nothing

End Sub

Private Function HandleButtonClick(intBtn As Integer)
' This function is called when a button is clicked.
' intBtn indicates which button was clicked.

' Constants for the commands that can be executed.
Const conCmdGotoSwitchboard = 1
Const conCmdOpenFormAdd = 2
Const conCmdOpenFormBrowse = 3
Const conCmdOpenReport = 4
Const conCmdCustomizeSwitchboard = 5
Const conCmdExitApplication = 6
Const conCmdRunMacro = 7
Const conCmdRunCode = 8
Const conCmdOpenPage = 9

' An error that is special cased.
Const conErrDoCmdCancelled = 2501

Dim con As Object
Dim RS As Object
Dim stSql As String

On Error GoTo HandleButtonClick_Err

' Find the item in the Switchboard Items table
' that corresponds to the button that was clicked.
Set con = Application.CurrentProject.Connection
Set RS = CreateObject("ADODB.Recordset")
stSql = "SELECT * FROM [Switchboard Items] "
stSql = stSql & "WHERE [SwitchboardID]=" & Me![SwitchboardID] & " AND [ItemNumber]=" & intBtn
RS.Open stSql, con, 1    ' 1 = adOpenKeyset

' If no item matches, report the error and exit the function.
If (RS.EOF) Then
    MsgBox "There was an error reading the Switchboard Items table."
    RS.Close
    Set RS = Nothing
    Set con = Nothing
    Exit Function
End If

Select Case RS![Command]

    ' Go to another switchboard.
    Case conCmdGotoSwitchboard
        Me.Filter = "[ItemNumber] = 0 AND [SwitchboardID]=" & RS![Argument]

    ' Open a form in Add mode.
    Case conCmdOpenFormAdd
        DoCmd.OpenForm RS![Argument], , , , acAdd

    ' Open a form.
    Case conCmdOpenFormBrowse
        DoCmd.OpenForm RS![Argument]

    ' Open a report.
    Case conCmdOpenReport
        DoCmd.OpenReport RS![Argument], acPreview

    ' Customize the Switchboard.
    Case conCmdCustomizeSwitchboard
        ' Handle the case where the Switchboard Manager
        ' is not installed (e.g. Minimal Install).
        On Error Resume Next
        Application.Run "ACWZMAIN.sbm_Entry"
        If (Err <> 0) Then MsgBox "Command not available."
        On Error GoTo 0
        ' Update the form.
        Me.Filter = "[ItemNumber] = 0 AND [Argument] = 'Default' "
        Me.Caption = Nz(Me![ItemText], "")
        FillOptions

    ' Exit the application.
    Case conCmdExitApplication
        CloseCurrentDatabase

    ' Run a macro.
    Case conCmdRunMacro
        DoCmd.RunMacro RS![Argument]

    ' Run code.
    Case conCmdRunCode
        Application.Run RS![Argument]

    ' Open a Data Access Page
    Case conCmdOpenPage
        DoCmd.OpenDataAccessPage RS![Argument]

    ' Any other command is unrecognized.
    Case Else
        MsgBox "Unknown option."

End Select

' Close the recordset and the database.
RS.Close

HandleButtonClick_Exit:
On Error Resume Next
Set RS = Nothing
Set con = Nothing
Exit Function

HandleButtonClick_Err:
' If the action was cancelled by the user for
' some reason, don't display an error message.
' Instead, resume on the next line.
If (Err = conErrDoCmdCancelled) Then
    Resume Next
Else
    MsgBox "There was an error executing the command.", vbCritical
    Resume HandleButtonClick_Exit
End If

End Function

希望这可以帮助别人...

在 Access 365 中,将 Switchboard 宏转换为 VBA 时似乎有两个错误:一个在 On Current 事件过程中,一个在 打开时 事件过程。错误消息仅指向 On Open 过程,而 On Current 事件过程似乎也需要更改。

当前: 这会生成 运行 时间错误 32538 "TempVars can only store data. They cannot store objects."。 将TempVars.Add"CurrentItemNumber"、ItemNumber改为
TempVars.Add"CurrentItemNumber",ItemNumber.Value.

打开时: 这会产生编译错误。 将 Call Argument & "()" 的所有实例更改为 Eval (Argument & "()")。 虽然不是必需的,但是良好的编码习惯,将所有具有 Argument 的 DoCmd 语句更改为 Argument.Value.

希望对您有所帮助。