Использование динамических меню в Access.

Наверняка все знакомы с ситуацией, когда в современных приложениях вид меню меняется в зависимости от, например прав доступа зарегистрировавшегося пользователя, контекста или другой ситуации. Меню в Access можно создавать по старинке на основе макросов или как своя панель инструментов. Далее будем предполагать, что меню создана на основе панели инструментов. Если у Вас меню создано на основе макросов, настоятельно рекомендую переделать. Вы получите ряд возможностей. Такое меню можно перетаскивать мышью в любую часть экрана, для пунктов меню вставлять button image, динамически управлять пунктами меню - гасить или вообще удалять конкретные пункты из программного кода. Что бы использовать возможности по управлению меню подключите библиотеку Microsoft Office 8.0 Object Library  в Tools > References. Или 9.0 если установлен Office 2000. В этой библиотеке есть объекты: CommandBar - панель инструментов, CommandBarControl - элемент панели инструментов, может быть или подменю или командой. Соответственно CommandBars - семейство всех панелей инструментов, Controls - позволяет как бы перейти в подменю объекта CommandBarControl. Ниже приведенная функция работает с трехуровневым меню. Координаты конкретного пункта задаются (i, j, k), где i - номер пункта в основном меню, нумерация начинается с единицы, j - в подменю, k - в подменю этого меню. В зависимости от Par = true - включает пункт меню, false - выключает пункт меню. EnVis = true - пункт меню при выключении становится не активным, false - вообще исчезает. Соответственно если какая то ветка имеет только два уровня, то значение k = 0, если один уровень, то j = 0 и k = 0.

Public Function SetMenuUserSecurity(i As Long, j As Long, K As Long, Par As Boolean, EnVis As Boolean)
'устанавливает/гасит (Par) меню с координатами (i,j,k) EnVis - True - Enabled False - Visible
On Error GoTo Err_SetMenuUserSecurity
Dim MyMenu As CommandBar
Dim MyControl1 As CommandBarControl
Dim MyControl2 As CommandBarControl
Dim MyControl3 As CommandBarControl
Set MyMenu = CommandBars("Главное меню Information") 'здесь Вы должны указать имя вашей панели инструментов

Set MyControl1 = MyMenu.Controls(i)
    If j = 0 Then
        If EnVis Then
            MyControl1.Enabled = Par
        Else
            MyControl1.Visible = Par
    End If
    Exit Function
    End If
Set MyControl2 = MyControl1.Controls(j)
    If K = 0 Then
        If EnVis Then
            MyControl2.Enabled = Par
        Else
            MyControl2.Visible = Par
        End If
        Exit Function
    End If
Set MyControl3 = MyControl2.Controls(K)
    If EnVis Then
        MyControl3.Enabled = Par
    Else
        MyControl3.Visible = Par
    End If
Exit_SetMenuUserSecurity:
    Exit Function
Err_SetMenuUserSecurity:
    MsgBox Err.Description
    Resume Exit_SetMenuUserSecurity
End Function

Пример части меню:

Примеры вызова:

SetMenuUserSecurity(1,2,3,False,True) результат:


видно, что пункт Хранилище счет-фактур не активен и пользователь не сможет его выбрать. Вызов SetMenuUserSecurity(1,2,3,True,True) востановит исходное состояние.

Вызов SetMenuUserSecurity(1,2,3,False,False) вообще удалит пункт меню, так, что пользователь и не будет догадываться о его наличии:

Кроме использования в каких либо контекстных случаях, эти методы можно применить для создания своеобразной системы разграничения прав доступа. Которая будет очень гибкой - вплоть до конкретного пункта меню. Создайте таблицу UserMenuItems, с полями: IDMenuItem - счетчик - код пункта меню, ItemDescription - название меню словами, ID1, ID2, ID3 - адрес меню. И таблицу UserRight, с полями: EmployerID - код пользователя,  IDMenuItem - код пункта меню из таблицы UserMenuItems, Right - право (boolean). Соответственно для любого пользователя можно определить его 'профиль' меню. Данная система может работать на ряду с защитой, организованной стандартным методом на уровне таблиц. В тех случаях когда не возможно все права задать на этом уровне или есть противоречия. Например пользователь имеет право вносить исходные данные в таблицу, но не должен запускать отчет построенный на основе этой таблицы. Понятно, что права можно назначить и на отчет, но я знаю, что обычно мало кто идет дальше прав на уровне таблиц.

Следующая функция, запускаемая при инициализации программы устанавливает профиль зарегистрировавшегося пользователя.
Public Function UserMenuControl()
'устанавливает пользовательский профиль меню, если он есть (или его часть)
On Error GoTo Err_UserMenuControl
Dim MySet As Recordset
Set MySet = InfoDB.OpenRecordset("Select UserRight.EmployerID,UserRight.Right,ID1,ID2,ID3 From (UserRight inner Join UserMenuItems on UserRight.IDMenuItem=UserMenuItems.IDMenuItem) Where EmployerID=" & Str$(GlUserID)) 'GlUserID - код пользователя, соответствует EmployerID из таблицы UserRight
    If Not MySet.EOF Then
        MySet.MoveFirst
        While Not MySet.EOF
            Call SetMenuUserSecurity(MySet!ID1, MySet!ID2, MySet!ID3, MySet!Right, False)
            MySet.MoveNext
        Wend
    End If
Exit_UserMenuControl:
    Exit Function
Err_UserMenuControl:
    MsgBox Err.Description
    Resume Exit_UserMenuControl
End Function

21.3.2001     Сакович Роман     sakovich@oma.by





Сайт создан в системе uCoz