CommandBarControl выполняет .OnAction перед нажатием на кнопку - PullRequest
1 голос
/ 29 апреля 2019

Код в моем вопросе вдохновлен решением в ответе на этот вопрос:
Как добавить пункт меню в контекстное меню по умолчанию, вызываемое правой кнопкой мыши

У меня есть объект ListBox на форме, показывающий список действий. Я хочу, чтобы пользователь мог щелкнуть правой кнопкой мыши элемент этого списка, чтобы отобразить контекстное меню, в котором он может:

  1. открыть новую форму, где он может просматривать и редактировать действие (соответствует выполнению события двойного щелчка по элементу списка)
  2. удалить элемент из списка

    Private Sub List_actions_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single
    
        'set up commandBar
        Dim combo As CommandBarControl
    
        'Since it may have been defined in the past, it should be deleted,
        'or if it has not been defined in the past, the error should be ignored
        On Error Resume Next
        CommandBars("RCActionContextMenu").Delete
        On Error GoTo 0
    
        'Make this menu a popup menu
        With CommandBars.Add(Name:="RCActionContextMenu", Position:=msoBarPopup)
            Set combo = .Controls.Add(Type:=msoControlButton)
                combo.BeginGroup = True
                combo.Caption = "View action"              ' Add label the user will see
                combo.OnAction = "List_actions_DblClick"    'Add the name of a function to call
    
            Set combo = .Controls.Add(Type:=msoControlButton)
                combo.Caption = "Delete action"
                combo.OnAction = DelAction()
        End With
    
        If Button = acRightButton Then
            DoCmd.CancelEvent
            CommandBars("RCActionContextMenu").ShowPopup
        End If
    End Sub
    
    Public Function DelAction()
        If Not IsNull(Me.Controls("RCActionContextMenu").Column(0)) Then
            CurrentDb.Execute "DELETE * FROM T_ACTIONS " & _
                      "WHERE ID = " & List_actions.Column(9) & ";"
            MsgBox "Action supprimée", vbInformation, "Information"
        End If
    End Function
    
    Private Sub List_actions_DblClick(Cancel As Integer)
        Dim vStatus As String
    
        'Get the record's index of the action
        rowNumber = Me.List_actions.ListIndex + 1
    
        id_action = List_actions.Column(9, rowNumber)
        vStatus = List_actions.Column(5, rowNumber)
    
        'Open the action
        DoCmd.OpenForm "F_ACTIONS", , , "[ID] = " & List_actions.Column(9)
    
        Form_F_ACTIONS.Effective_date.Visible = Effdatefunction(vStatus)
    
    End Sub
    

Проблема, которую я получаю, состоит в том, что функция DelAction () выполняется перед отображением всплывающего окна, и я получаю run-time error 2465 с указанием "Microsoft Access can't find the field 'RCActionContextMenu' referred to in your expression."
Я попытался отменить строку combo.OnAction = DelAction() на combo.OnAction = "DelAction". В результате появляется контекстное меню, но при нажатии на любую кнопку ничего не происходит.

1 Ответ

2 голосов
/ 29 апреля 2019

Здесь есть несколько проблем.

        combo.OnAction = DelAction()

Это вызовет функцию, как вы уже видели. Вам нужно установить строку здесь.

        combo.OnAction = "DelAction()"

Это все равно не будет работать, так как DelAction() находится в вашем модуле формы.
Либо переместите функцию в открытый модуль с параметрами, либо жестко закодируйте имена объектов там,

combo.OnAction = "DelAction(""MyFormName"", ""List_actions"")"

или попробуйте (не уверен, что это работает):

        combo.OnAction = "Form_YourFormName_DelAction()"

То же самое с "List_actions_DblClick" - функцию нужно вызывать «извне», как из окна «Немедленно».


If Not IsNull(Me.Controls("RCActionContextMenu").Column(0)) Then

Панель команд контекстного меню не является элементом управления, вам нужен список:

If Not IsNull(Me.Controls("List_actions").Column(0)) Then

или просто

If Not IsNull(Me!List_actions.Column(0)) Then

После удаления действия вам необходимо запросить список.

CurrentDb.Execute "DELETE * FROM T_ACTIONS " ...
Me!List_actions.Requery
...