Тема: Как объявить новую коллекцию пользователей?

Возникла необходимость объявить в памяти объект типа Коллекция Пользователей для следующей задачи:

Большой процент пользователей в системе имеет несколько должностей (совмещает), соответственно часто необходимо делать выборку пользователей по конкретной должности. Решено было сделать это следующим образом:

1) Пользователям добавлен табличный аттрибут, в котором по классификатору прописаны все должности
2) Сделать функцию, возвращающую коллекцию пользователей, имеющих заданную должность

Использовать выборки для такой простой задачи - перебора всех пользователей системы и выделения только тех, кто имеет нужную должность - неудобно, слишком много нажимать, так сказать  :)

По ходу написания функции я не нашёл, как объявить новую коллекцию пользователей (просто не знаю имя класса). В итоге вынужден объявлять ненужный SelectUserDlg и использовать его коллекцию SelectFromUser  :)

В общем, изврат каких мало  :) Можно ли это реализовать проще и притом корректно с точки зрения техники программирования?

Re: Как объявить новую коллекцию пользователей?

По ходу написания функции я не нашёл, как объявить новую коллекцию пользователей (просто не знаю имя класса). В итоге вынужден объявлять ненужный SelectUserDlg и использовать его коллекцию SelectFromUser

Да, действительно это единственная "открытая" фича позволяющая редактировать коллекцию пользователей.

P.S. Но я бы использовал выборку с параметрами.

(изменено: Anatoly, 12 августа 2008г. 16:20:59)

Re: Как объявить новую коллекцию пользователей?

По ходу написания функции я не нашёл, как объявить новую коллекцию пользователей (просто не знаю имя класса). В итоге вынужден объявлять ненужный SelectUserDlg и использовать его коллекцию SelectFromUser

Да, действительно, это единственная "открытая" фича позволяющая редактировать коллекцию пользователей.

P.S. Но я бы использовал выборку с параметрами.

(изменено: Ilya_VK, 13 августа 2008г. 04:57:40)

Re: Как объявить новую коллекцию пользователей?

Anatoly пишет:

Да, действительно, это единственная "открытая" фича позволяющая редактировать коллекцию пользователей.

P.S. Но я бы использовал выборку с параметрами.


Изначально так и хотел, но оказалось сложно создать такую выборку, которая позволила бы проверить как свойство User.Position, так и поля табличного атрибута, так как пользователи совмещают несколько должностей.
Кроме того, прочитав тему "Выборка пользователей с табличным атрибутом" понял, что придётся делать дополнительные поля в табличном атрибуте. В итоге решил всё следующим кодом:

Function GetUsersByPosition(NeededPosition)
    Set Container = ThisApplication.Dialogs.SelectUserDlg
    For Each User In ThisApplication.Users
        AddThisUser = False
        If User.Position = NeededPosition.Description Then: AddThisUser = True: End If
        For Each Row in User.Attributes("ATTR_USER_POSITIONSTABLE").Rows
            Set Position = Row.Attributes("ATTR_USER_POSITIONSTABLE_ROWS")
            If Position Is NeededPosition Then: AddThisUser = True: End If
        Next
        If AddThisUser Then: Container.SelectFromUsers.Add User: End If
    Next
    Set GetUsersByPosition = Container.SelectFromUsers
End Function


А можно узнать, почему возможность объявлять те же коллекции пользователей и объектов закрыта?.. Я, конечно, не мастер в программировании, но всё же не вижу потенциальных минусов доступности этих классов.

PS: Комментарий не в тему: не совсем понятно, почему User.Position даёт string, а не Classifier. Приходится делать сравнение через User.Position = NeededPosition.Description, а не через User.Position Is NeededPosition

Re: Как объявить новую коллекцию пользователей?

Еще малнький совет:
Необязательно использовать SelectUserDlg. Вы можете использовать обычный массив, для передачи в него SysId пользователя.
При добавлении роли, на входе может быть не только TDMSUser, а также просто его SysId.

Например:
Пишем "свою" библиотеку функций:

'---- создать массив, в котором элементы = SysId пользователя с должностью "Главный специалист"
'---- при этом, пользователи ищутся в подразделении (см. первый аргумент в функции)
Function GetMainSpecialist(Department)
  GetMainSpecialist = False
  i = 0 
  Redim Preserve MainSpecialists(i)
  MainSpecialists(i) = ""

  For Each User in Department.AssignedUsers
    If (User.Position = "Главный специалист") and (User.AllowLogin = True) Then
      Redim Preserve MainSpecialists(i)
      MainSpecialists(i) = User.SysName  
      i = i + 1
    End If
  Next
  GetMainSpecialist = MainSpecialists
End Function

Далее, непосредственно присвоение:

USE "CommandSysId"

' ---- данная процедура создаёт роль "ROLE_MAIN_SPECIALIST" главному специалисту на текущем объекте
' ---- если в отделе больше одного пользователя с ролью "Главный специалист", то необходимо выбрать одного.
Sub X() 
  Set CreatorDepartment = ThisApplication.Departments.Classifiers.find("АСО")
  MainSpecialists = GetMainSpecialist(CreatorDepartment)

  If MainSpecialists(0) = "" Then
    Msgbox "В отделе " & """" & CreatorDepartment.Description & """ не назначен гл.специалист отдела!", VbExclamation, "Ошибка"
  Else
    If UBound(MainSpecialists)>0 Then
      Set Dlg = ThisApplication.Dialogs.SelectDlg
      Dlg.SelectFrom = MainSpecialists
      Dlg.Caption = "Выберите гл.специалиста отдела, подпись которого необходима!"
      If Dlg.Show = False Then 
        Obj.Roles.Create "ROLE_MAIN_SPECIALIST", MainSpecialists(0) 
      Else
        SelectedArray = Dlg.Objects
        Obj.Roles.Create "ROLE_MAIN_SPECIALIST", SelectedArray(0)        
      End If  
    Else  
      Obj.Roles.Create "ROLE_MAIN_SPECIALIST", MainSpecialists(0)
    End If
  End If
End Sub

Re: Как объявить новую коллекцию пользователей?

Ilya_VK пишет:

PS: Комментарий не в тему: не совсем понятно, почему User.Position даёт string, а не Classifier. Приходится делать сравнение через User.Position = NeededPosition.Description, а не через User.Position Is NeededPosition

Да, классификатор конечно немного странный, но это очень старый функционал, так что вряд ли будет менятся.