2009-04-20 30 views
7

El objetivo es crear menús que se puedan utilizar con ciertos controles en un formulario de MS Access y poder hacer clic derecho en un control, por ejemplo en un cuadro de lista y un menú emergente de menú contextual específico con opciones, que si se hace clic, activaría una subrutina o función predefinida.Cómo agregar un elemento de menú al menú contextual predeterminado del botón derecho

¿Cuál es el mejor método para lograr esto programáticamente?

Estoy utilizando MS Access 2003 y me gustaría hacer esto usando VBA.

+0

La respuesta depende en gran medida de la versión de Access. Si A2007, una respuesta, cualquier versión anterior, una respuesta completamente diferente. –

Respuesta

13

en primer lugar crear un evento _MouseUp a ejecutar en el respectivo co Siga buscando para ver si se hizo clic con el botón derecho del mouse y, de ser así, llame al método .ShowPopup.

Por supuesto, esto supone que el

Private Sub MyListControlName_MouseUp(ByVal Button As Integer, _ 
             ByVal Shift As Integer, _ 
             ByVal X As Long, ByVal Y As Long) 

    ' Call the SetUpContextMenu function to ensure it is setup with most current context 
    ' Note: This really only needs to be setup once for this example since nothing is 
    ' changed contextually here, but it could be further expanded to accomplish this 
    SetUpContextMenu 
    ' See if the right mouse button was clicked 
    If Button = acRightButton Then 
    CommandBars("MyListControlContextMenu").ShowPopup 
    End If 
End Sub 

Dado que en este punto la barra de comandos MyListControlContextMenu es indefinido, defino el menú en un módulo separado de la siguiente manera:

Public Sub SetUpContextMenu() 
    ' Note: This requires a reference to Microsoft Office Object Library 
    Dim combo As CommandBarComboBox 

    ' 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("MyListControlContextMenu").Delete 
    On Error GoTo 0 

    ' Make this menu a popup menu 
    With CommandBars.Add(Name:="MyListControlContextMenu", Position:=msoBarPopup) 

    ' Provide the user the ability to input text using the msoControlEdit type 
    Set combo = .Controls.Add(Type:=msoControlEdit) 
     combo.Caption = "Lookup Text:"   ' Add a label the user will see 
     combo.OnAction = "getText"    ' Add the name of a function to call 

    ' Provide the user the ability to click a menu option to execute a function  
    Set combo = .Controls.Add(Type:=msoControlButton) 
     combo.BeginGroup = True     ' Add a line to separate above group 
     combo.Caption = "Lookup Details"   ' Add label the user will see 
     combo.OnAction = "LookupDetailsFunction" ' Add the name of a function to call 

    ' Provide the user the ability to click a menu option to execute a function   
    Set combo = .Controls.Add(Type:=msoControlButton) 
     combo.Caption = "Delete Record"   ' Add a label the user will see 
     combo.OnAction = "DeleteRecordFunction" ' Add the name of the function to call 

    End With 

End Sub 

Desde tres funciones han sido referenciado, podemos pasar a definir estos de la siguiente manera:

getText: Tenga en cuenta, esto La opción requiere una referencia tanto al nombre del nombre de menú de la barra de comandos como al nombre del título de control.

Public Function getText() As String 

    getText = CommandBars("MyListControlContextMenu").Controls("Lookup Text:").Text 

    ' You could optionally do something with this text here, 
    ' such as pass it into another function ... 
    MsgBox "You typed the following text into the menu: " & getText 

End Function 

LookupDetailsFunction: Para este ejemplo, voy a crear una función de shell y devolver el texto "Hello World!".

Public Function LookupDetailsFunction() As String 

    LookupDetailsFunction = "Hello World!" 

    MsgBox LookupDetailsFunction, vbInformation, "Notice!" 

End Function 

DeleteRecordFunction: Para este ejemplo, voy a garantizar el control sigue siendo válida comprobando contra nulo, y si sigue siendo válido, se ejecutará una consulta para retirar el registro de una tabla.

Public Function DeleteRecordFunction() As String 

    If Not IsNull(Forms!MyFormName.Controls("MyListControlName").Column(0)) Then 
    Currentdb.Execute _ 
     "DELETE * FROM [MyTableName] " & _ 
     "WHERE MyKey = " & Forms!MyFormName.Controls("MyListControlName").Column(0) & ";" 
    MsgBox "Record Deleted", vbInformation, "Notice!" 
    End If 

End Function 

Nota: Para LookupDetailsFunction, DeleteRecordFunction y getText funciones, éstas deben estar dentro de un ámbito público para que funcione correctamente.

Finalmente, el último paso es probar el menú. Para hacerlo, abra el formulario, haga clic con el botón derecho en el control de lista y seleccione una de las opciones del menú emergente.

Opcionalmente button.FaceID se puede utilizar para indicar un icono de oficina conocido para asociar con cada instancia del control emergente de menú.

Encontré Pillai Shyam's work en la creación de un complemento de navegador FaceID para ser muy útil.

Referencias: Microsoft FaceID

+0

FYI También tuve que agregar 'DoCmd.CancelEvent' dentro del bloque' If' en el controlador '_MouseUp' para mi control de lista para evitar que el menú predeterminado del botón derecho aparezca después de mi menú personalizado, también encontré que estaba presionando el tipo errores para 'combo como CommandBarComboBox', que se resolvió fácilmente cambiando al tipo genérico' CommandBarControl'. Pero, en general, esta es una respuesta clara y bien escrita, +1. – DaveRandom

+0

¿Conoce algún mecanismo para organizar el código de devolución de llamada un poco mejor? No me gustan todos estos módulos públicos acoplados a mi código de formulario, idealmente quisiera llamar a un sub público en el módulo del formulario, y posiblemente también incluir esto en un módulo de clase genérico. – DaveRandom

+0

Mecanismo? No. Colocación del código sí. Puede hacerlo fácilmente haciendo las llamadas necesarias en el módulo respectivo usándolas. Esto funcionó mejor para mi caso de uso ya que todo lo demás estaba muy controlado. En otros proyectos, he movido el código al área haciendo llamadas. –

2

Para reemplazar el menú contextual predeterminado con un menú que incluye las acciones predeterminadas más sus acciones personalizadas, debe crear un menú contextual personalizado que incluya las acciones predeterminadas. No hay forma de extender el menú contextual predeterminado.

Los menús de acceso directo en Access 2003 y anteriores son un tipo especial de barra de herramientas. Los creas de la misma manera (más o menos) que creas una barra de herramientas personalizada. Sin embargo, la IU es un poco extraña, ya que hay un lugar especial donde los creas.

Para comenzar, haga clic con el botón derecho en la barra de herramientas de su MDF de acceso frontal. Elija PERSONALIZAR. En la lista de barras de herramientas, marque MENÚS AJUSTADOS. Esto le dará una lista de todos los menús contextuales incorporados, excepto que en realidad no terminan luciendo así en uso real. Por ejemplo, si haga clic derecho en una forma, se obtiene este menú contextual:

Form Design 
Datasheet View 
PivotTable View 
PivotChart View 
Filter By Form 
Apply Filter/Sort 
Remove Filter/Sort 
Cut 
Copy 
Paste 
Properties 

Ahora, ¿dónde está este menú en el menú contextual? Bueno, éste es el menú FORM VIEW TITLE BAR, aunque aparece cada vez que hace clic en un lugar que no sea un control en el formulario. Entonces, si ese es el menú que desea modificar, puede editarlo agregándole elementos de menú (una operación de arrastrar y soltar).

Creo que es mejor (como dije anteriormente) crear un menú de acceso directo personalizado que replique el menú incorporado y agregue sus mejoras, ya que le permite conservar el menú contextual predeterminado de Access y también tener su versión personalizada de para usar cuando lo desee. En ese caso, necesitaría iniciar un nuevo menú contextual, y aquí es donde la interfaz de usuario es extraña:

Haga clic en la última opción en el menú contextual, PERSONALIZADO. Usted ve que cae un marcador de posición. No puedes arrastrar/soltarlo. En su lugar, debe hacer clic en NUEVO en la ventana principal de edición de la barra de herramientas y crear una nueva barra de herramientas de acceso directo (asígnele el nombre que desea que tenga su menú contextual personalizado). Su nueva barra de herramientas ahora aparece en la lista de barras de herramientas. Resalte y haga clic en PROPIEDADES, y cambie el tipo a POPUP. Esto le dará una advertencia informativa de que esta alteración lo cambia de una barra de herramientas a un menú contextual. Luego puede cerrar la hoja de propiedades de su barra de herramientas/menú contextual, y ahora si marca MENSAJES AJUSTADOS nuevamente y mira el menú PERSONALIZADO, verá su menú recién creado. Ahora puede arrastrar y soltar los elementos de menú para el menú incorporado a su nuevo menú, pero no los deje en el menú, sino en el marcador de posición en el menú emergente desde la> a la derecha del nombre del menú.

Puede arrastrar y soltar cualquier opción que desee desde cualquier menú o barra de herramientas a su menú personalizado.

Supongo que sabe cómo usar el menú contextual, ya que es parte de la hoja de propiedades de todos los objetos de formulario.

ACTUALIZACIÓN 2009/05/21: El blog oficial de Access 2007 acaba de publicar un article on doing this programmatically en Access 2007. Debido a la interfaz de cinta, no va a haber diferencias, pero algunas cosas será el mismo.

+0

¿Access utiliza los objetos Office.CommandBar y Office.CommandBarButton, según Excel, Word, etc.? – onedaywhen

+0

David, Esto es muy útil para entender cómo funciona Access con Command Bar's. Sin embargo, estoy buscando hacer lo que usted declaró programáticamente. –

+0

Es programáticamente viable, pero bastante quisquilloso, en mi experiencia. En VBE, busque "barras de herramientas del programa" y lea la ayuda allí. Como los menús contextuales son solo una forma de barra de herramientas, usaría los mismos métodos. Sin embargo, yo no lo haría de esa manera. Creé menús personalizados y luego les mostraba/ocultaba elementos particulares según el contexto. –

2

intenta esto

Sub Add2Menu() 
    Set newItem = CommandBars("Form View Popup").Controls.Add(Type:=1) 
    With newItem 
    .BeginGroup = True 
    .Caption = "Make Report" 
    .FaceID = 0 
    .OnAction = "qtrReport" 
    End With 
End Sub 

Como se puede ver que va a añadir el artículo en "Vista formulario emergente" barra de comandos y cuando se hace clic en este artículo que va a cargar procedimiento qtrReport

Y utilizar esta función para ver todos Commandbars de acceso

Sub ListAllCommandBars() 
For i = 1 To Application.CommandBars.Count 
    Debug.Print Application.CommandBars(i).Name 
Next 
End Sub 
+0

Esto es exactamente lo que estaba buscando. Gracias –

Cuestiones relacionadas