Полезные мелочи в работе ч.7 (Поработаем с группами)

5 5

С чем связана проблема: У нас много групп (справочник: Группы пользователей) и пользователей (не путать с работниками ;) ). Да, мы можем заходить в каждую группу и пересматривать ее глазами, так как никакого массового выбора, или возможности выгрузить ее в Excel у нас нет и не планируется. Можно идти со стороны пользователей - открывать каждого и редактировать его группы из карточки, но тоже - так себе мероприятие. 

Выход: Пишем сценарий для работы с группами.

Как это можно сделать?

Вариант 1: Мы можем открывать список пользователей группы списком и отмечать тех, кого надо удалить из нее.

Вариант 2: Мы можем открывать список пользователей группы списком и отмечать тех, кого надо в ней оставить, убрав неотмеченных.

Что выбрать? Оставим на совесть пользователя данным сценарием и даем возможность выбора:

Перво-наперво, нам надо выбрать группу для работы с ее составом, а так же пути решения появившихся вопросов/проблем:

Group = References.ГПЛ.GetComponent
AddwhereGroup = Group.AddWhere(Format("%s.%s = 'Д'"; ArrayOf(Group.TableName; Group.Requisites('Состояние').SQLFieldName)))   
  View = Group.CreateView('Главное')
  View.ViewMode =  vmSelect 
  View.MultiSelection = FALSE
  View.MainForm.Show
  if View.MainForm.Result = mrOK
    GroupName = References.SYSREF_USER_GROUPS_REFERENCE.GetObjectByID(View.SelectedRecordsID(0))
  else
    exit()
  endif
  
MSG = MessageBox("Минутку внимания."; 'Что необходимо сделать?'; 'Удалить пользователей|Оставить пользователей|Добавить пользователей|Отмена'; 'Отмена'; 'Отмена')

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

// "Удалить пользователей"
if MSG == "Удалить пользователей"  
  Userlist = ''
  DDSGROUP = GroupName.DetailDataSet(1) // Открываем DDS
  DDSGROUP.OpenRecord // Открываем на редактирование DDS
  foreach TabPol in DDSGROUP
    Userlist = AddSubString(ServiceFactory.GetUserByCode(TabPol.Requisites("ПользовательТ").Value).ID; Userlist; ',') // Формируем список пользователей
  endforeach   
  Ref = CreateReference('ПОЛ')       // Указываем справочник 
  Addwhere = Ref.AddWhere(Format("%s.%s in (%s)"; ArrayOf(Ref.TableName; Ref.Requisites('ИД').SQLFieldName; Userlist))) // Отбираем тех, кто в нашей группе
    View = Ref.CreateView('Главное')
    View.ViewMode =  vmSelect 
    View.MultiSelection = TRUE
    ShowMessage('Выберите пользователей на удаление!')
    View.MainForm.Show
    index = 0
    if View.MainForm.Result = mrOK
      FinalText = Сейчас() & CR // Засекаем время
      while index < View.SelectedRecordCount
        IDUser = View.SelectedRecordsID(index) // Получаем ИД Пользователя
        foreach gpol2 in DDSGROUP
          if IDUser == ServiceFactory.GetUserByCode(gpol2.Requisites("ПользовательТ").Value).ID
             gpol2.Delete  // Удаляем отмеченных
             FinalText = FinalText & 'Из группы "' & GroupName.SYSREQ_NAME & '" Удален пользователь: ' & ServiceFactory.GetUserByID(IDUser).FullName & CR // Фиксируем результат работы
          endif 
        endforeach     
        index = index + 1
      endwhile    
      GroupName.Save // Сохраняем изменения
      DDSGROUP.CloseRecord // Закрываем запись
      FinalText = FinalText & Сейчас() // Засекаем время
      EditText(FinalText)  // Выводим текст для ознакомления
    endif
endif

Далее мы сделаем логику обратной - отмечаем не тех, кого надо удалить, а только тех, кто должен в ней остаться:

// "Оставить пользователей"
if MSG == "Оставить пользователей"
  Userlist = ''
  ListOst = ''
  DDSGROUP = GroupName.DetailDataSet(1)
  DDSGROUP.OpenRecord
  foreach TabPol in DDSGROUP
    Userlist = AddSubString(ServiceFactory.GetUserByCode(TabPol.Requisites("ПользовательТ").Value).ID; Userlist; ',') 
  endforeach   
  Ref = CreateReference('ПОЛ')    
  Addwhere = Ref.AddWhere(Format("%s.%s in (%s)"; ArrayOf(Ref.TableName; Ref.Requisites('ИД').SQLFieldName; Userlist)))
    View = Ref.CreateView('Главное')
    View.ViewMode =  vmSelect 
    View.MultiSelection = TRUE
    ShowMessage('Выберите пользователей которых надо ОСТАВИТЬ в группе!')
    View.MainForm.Show
    index = 0
        if View.MainForm.Result = mrOK
      FinalText = Сейчас() & CR
      while index < View.SelectedRecordCount
        IDUser = View.SelectedRecordsID(index)
        ListOst = AddSubString(IDUser; ListOst; ',')     
        index = index + 1
      endwhile
      foreach gpol2 in DDSGROUP
        if FindSubString(ServiceFactory.GetUserByCode(gpol2.Requisites("ПользовательТ").Value).ID; ListOst; ',') = 0          
           gpol2.Delete
           FinalText = FinalText & 'Из группы "' & GroupName.SYSREQ_NAME & '" Удален пользователь: ' & ServiceFactory.GetUserByCode(gpol2.Requisites("ПользовательТ").Value).FullName & CR 
        endif 
      endforeach   
      GroupName.Save
      DDSGROUP.CloseRecord
      FinalText = FinalText & Сейчас()
      EditText(FinalText)  
    endif
endif

Теперь последний пункт - добавление в группу пользователей из списка. Отберем только  действующих пользователей и предложим их для выбора:

// "Добавить пользователей"
if MSG == "Добавить пользователей"
  Userlist = ''
  DDSGROUP = GroupName.DetailDataSet(1)
  try
    DDSGROUP.OpenRecord
  except  
  endexcept    
  Ref = CreateReference('ПОЛ')       // Указываем справочник 
  Addwhere = Ref.AddWhere(Format("%s.%s = 'Д'"; ArrayOf(Ref.TableName; Ref.Requisites('Состояние').SQLFieldName)))
    View = Ref.CreateView('Главное')
    View.ViewMode =  vmSelect 
    View.MultiSelection = TRUE
    ShowMessage('Выберите пользователей которых надо добавить в группу!')
    View.MainForm.Show
    index = 0
    FinalText = Сейчас() & CR
    if View.MainForm.Result = mrOK
      while index < View.SelectedRecordCount
        IDUs = View.SelectedRecordsID(index)
        CodeUs = ServiceFactory.GetUserByID(Trim(IDUs)).Code
        FinalText = FinalText & 'В группу "' & GroupName.SYSREQ_NAME & '" добавлен пользователь: ' & ServiceFactory.GetUserByID(Trim(IDUs)).FullName & CR
        DDSGROUP.Append
        DDSGROUP.ПользовательТ = CodeUs
        index = index + 1
      endwhile        
    endif
    GroupName.Save
    DDSGROUP.CloseRecord
    FinalText = FinalText & Сейчас()
    EditText(FinalText) 
endif

Теперь все это, можно взять по отдельности, а можно затолкать все в один сценарий (как у меня). Так в целом и все. Все довольно однотипно, но проще сократить, чем создавать с нуля. Пригодится кому или нет - вопрос, но все же оставим это здесь. :) 

Анна Забалуева

Печальный нюанс - метод CreateView не является рекомендуемым, его даже из справки изъяли вроде бы ещё в 4.9. По этому поводу есть статья в базе знаний: Как программно получить представление справочника.

Павел Леонов

>>except

>>endexcept

Пустой блок обработки исключений - очень плохая практика. Если уж не должны обрабатывать, то хотя бы для истории пишите комментарии о том, почему так сделано.

Тарас Асачёв

Павел, Да, это у меня пережиток остался, как апендицит - ранее там была строка с выводом ошибки на время тестирования (ErrorMSG = GetLastException().message), потом я ее вырезал, но фрагмент остался 

Тарас Асачёв

Анна, не у всех есть доступ на указанную вами ссылку. Пришлите лучше из нее фрагмент - всем будет наука)

Павел Леонов

Тарас, это даже не конкретно к вам комментарий был. А для новичков, чтобы не использовали не глядя. )

Авторизуйтесь, чтобы написать комментарий