Работа с наборами данных справочников

8 6

Введение

Продолжаем серию статей о разработке на ISBL, в которую ранее вошли следующие материалы:

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

  • дадим пользователю, ответственному за раздачу прав на программное обеспечение, возможность поиска работников, использующих конкретное ПО;
  • автоматизируем процесс задания работнику прав на программное обеспечение с использованием типовых прав.

Решать нашу задачу мы будем, используя наборы данных  множества однотипных объектов (в нашем случае это будут записи справочников).

Получение списка пользователей ПО

Давайте создадим инструмент поиска работников, которым были выданы права на определенное программное обеспечение. Логика работы создаваемого инструмента задумана простая: пользователь, ответственный за выдачу работникам прав на ПО, находит в справочнике Программное обеспечение интересующее ПО, открывает карточку записи, нажимает на ее форме кнопку Пользователи и получает в ответ список пользователей данного программного обеспечения. Собственно задача заключается в поиске записей справочника Права доступа работников к ПО, детальные наборы которых содержат искомое ПО, и формирование списка кодов соответствующих работников. Полученный список кодов затем используется в качестве условия отбора при открытии формы списка справочника Работники, которая и является результатом работы нашего инструмента.

Запустите компоненту разработчика Типы справочников, найдите тип справочника Программное обеспечение и откройте его карточку. На закладке «Действия» создайте новое действие с именем «FindUsers» и заголовком «Пользователи» (или любыми другими на ваш вкус) и сохраните изменения.

После этого добавьте на форму карточки записи справочника кнопку, связанную с созданным нами действием, сохраните и закройте форму, вернитесь в карточку типа справочника. Нам осталось написать вычисление действия – вот его исходный код:

// Код программного обеспечения из открытой карточки
SoftwareCode = Object.SYSREQ_CODE

// Переменная, в которой будем собирать список кодов работников,
// имеющих доступ к ПО
Users = ''

// Создать объект IReference справочника "Права доступа работников на ПО"
RefUserPermissions = CreateReference('UserPermissions')

// Открыть набор данных
RefUserPermissions.Open()

// Последовательный обход записей набора
foreach UserPermission in RefUserPermissions

  // открыть текущую запись
  UserPermission.OpenRecord()

  // получить детальный набор текущей записи,
  // содержащий список прав пользователя
  DDS_UserPermissions = UserPermission.DetailDataSet(1)

  // если в правах пользователя упоминается искомое ПО, то... 
  if DDS_UserPermissions.Locate('SoftwareT'; SoftwareCode)

    // Получить код работника, дополнив его ведущими пробелами,
    // до длины 10 символов (длина поля «Код» в справочнике)
    UserCode = FormatString('10|'; UserPermission.Работник)

    // Заключить получившийся код в одинарные кавычки 
    QuotedUserCode = Format("'%s'"; UserCode)

    // Добавить код в список кодов, отделив запятой
    Users = AddSubString(QuotedUserCode; Users; ',')

  endif

  // Закрыть текущую запись
  UserPermission.CloseRecord()

endforeach

// Закрыть набор данных справочника
RefUserPermissions.Close()

// Создать объект IReference справочника "Работники" 
Ref = CreateReference('РАБ')

// Ограничить набор полученным списком кодов  
AddWhere = Format("MBAnalit.Kod in (%s)"; Users)
WhereID = Ref.AddWhere(AddWhere)

// Открыть набор
Ref.Open()

// Отобразить на экране форму списка справочника
Ref.ComponentForm.Show()

// Закрыть набор и снять ограничение
Ref.Close()
Ref.DelWhere(WhereID)

В данном примере мы работали с наборами данных справочников: открывали набор, осуществляли навигацию, получали доступ к детальному набору данных, выполняли поиск по реквизиту, открывали форму списка справочника. Стоит заметить, что решение подобных задач методом перебора записей в наборе является неэффективным и при большом количестве записей приводит к падению производительности. В качестве альтернативного решения в данном случае может быть использован SQL-запрос, позволяющий получить все необходимые данные в требуемом виде всего за одно обращение к серверу, что, безусловно, быстрее. Однако работа с SQL-запросами требует знания структуры хранения данных в DIRECTUM, что выходит за рамки данной статьи и будет рассмотрено в последующих материалах.

Задание прав на ПО с использованием типовых прав

Теперь разработаем механизм заполнения прав доступа работника к ПО с использованием заранее созданных типовых наборов прав, хранящихся в справочнике Типовые права доступа. Логика работы механизма должна быть следующей. При нажатии на кнопку Добавить типовые права в карточке справочника Права доступа работников к ПО пользователю предлагается выбрать набор типовых прав из справочника Типовые права доступа. Если пользователь совершает выбор, то список программного обеспечения и прав к нему из выбранного типового набора построчно добавляется в табличную часть открытой карточки. Причем права, уже присутствующие в списке, повторно не добавляются. Действие для добавления типового набора прав и связанная с ним кнопка на форме уже были добавлены в рамках предыдущей статьи.

Нам осталось написать вычисление:

// Создать объект IReference справочника "Типовые права доступа"
Ref = CreateReference('TypicalPermissions')

// Получить главное представление справочника
View = Ref.CreateView(Ref.MainViewCode)

// Установить режим формы представления справочника: для выбора
View.ViewMode =  vmSelect
 
// Разрешить множественный выбор в форме
View.MultiSelection = false

// Показать форму списка пользователю для выбора
View.MainForm.Show()

// Если совершен выбор, то...
if View.MainForm.Result = mrOK

  // получить ID выбранной записи
  SelectedItemID = View.SelectedRecordsID(0)
  
  // Найти запись справочника "Типовые права доступа" по ID
  TypicalPermission = References.TypicalPermissions.GetObjectByID(SelectedItemID)
  
  // Получить детальный набор данных найденной записи записи
  Permissions = TypicalPermission.DetailDataSet(1)
  
  // Получить детальный набор данных, содержащий
  // набор прав текущего пользователя
  UserPermissions = Object.DetailDataSet(1)
  
  foreach Permission in Permissions
  
    // Получить ПО и тип прав к нему из типовых прав
    Software        = Permission.SoftwareT
    PermissionsType = Permission.PermissionsTypeT
     
    // если в наборе прав пользователя еще нет строки с комбинацией значений
    // Software и PermissionsType, то...
    if not UserPermissions.Locate(
                           ArrayOf('SoftwareT'; 'PermissionsTypeT');
                           ArrayOf(Software; PermissionsType)
                                 )
      // добавить новую запись и заполнить ее поля
      UserPermissions.Append()
      UserPermissions.SoftwareT = Software
      UserPermissions.PermissionsTypeT = PermissionsType
    endif

  endforeach

endif

 

В этом примере нами были использованы интерактивный выбор из справочника, поиск записи по ее ID, а также работа с детальными наборами –  из одного набора мы считывали данные, в другой добавляли.

Резюме

Подведем итоги. В рамках данной статьи мы разработали дополнительный функционал для двух справочников:

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

     

Попутно мы посмотрели, как конкретные свойства и методы наборов данных используются для решения конкретных задач: навигация и поиск записей в наборе, чтение реквизитов, работа с детальными наборами данных. Кроме того, нами было отмечено, что наборы данных, как правило, малоэффективны при получении значительных объемов сложно взаимосвязанной информации, в этих случаях рекомендуется пользоваться SQL-запросами.

 

Андрей Подкин

Алгоритм вида

  1. Открыть набор данных
  2. Пробежаться по записям
  3. Если запись удовлетворяет некому условию - обработать ее.

Чреват серьезными проблемами быстродействия на больших объемах данных. Поэтому, если количество записей в справочнике хотя бы теоретически может превысить несколько тысяч, то обязательно надо использовать AddWhere, обрабатывая только нужные записи.

Я новичок в разработке и мне не понятно как и куда добавлять эти куски кода.

В предыдущих статьях было описано более подробно!

Алексей Семакин
Я новичок в разработке и мне не понятно как и куда добавлять эти куски кода

Константин, в первом случае мы находимся на закладке "Действия" карточки типа справочника, где и создаем новое действие. У действия есть всего три атрибута: *Имя, *Заголовок и Вычисление. При открытии Вычисления мы попадем в редактор исходных текстов, куда и следует вставить приведенный код. Во втором случае - ровно тоже самое, только в карточке другого типа справочника. В абзацах непосредственно перед листингами я постарался достаточно подробно описать действия разработчика. При этом я не стал особо заострять внимание на манипуляциях, уже рассмотренных в предыдущих материалах, полагая, что читатель с ними ознакомился. В любом случае я принимаю ваше замечание к сведению. Возможно, следует делать больше скриншотов.

Константин Судаков
Константин, в первом случае мы находимся на закладке "Действия" карточки типа справочника, где и создаем новое действие. У действия есть всего три атрибута: *Имя, *Заголовок и Вычисление. При открытии Вычисления мы попадем в редактор исходных текстов, куда и следует вставить приведенный код. Во втором случае - ровно тоже самое, только в карточке другого типа справочника. В абзацах непосредственно перед листингами я постарался достаточно подробно описать действия разработчика. При этом я не стал особо заострять внимание на манипуляциях, уже рассмотренных в предыдущих материалах, полагая, что читатель с ними ознакомился. В любом случае я принимаю ваше замечание к сведению. Возможно, следует делать больше скриншотов.
Алексей, спасибо за ответ. Я сразу самостоятельно разобрался куда вставлять первый код. А вот со вторым возникли трудности. Но после Вашего ответа выяснил, что у нас с Вами немного по-разному называются типы справочников, именно поэтому в первый раз я не нашел "нужную кнопку" куда вставлять второй код.
Константин Судаков

Пожалуй, проходя курс по разработке на IS-Builder, стоит делать перерывы между чтением статей для лучшего усвоения материала!

Татьяна Ларионова

Добрый день, подскажите пожалуйста, не могу понять,делала по аналогии с вашей статьей, есть список Кодов справочника договоры, по которому нужно отфильтровать справочник Проекты, при выполнении кода выводит пустой справочник:

List = 'Д000003','Д000002'

Reference = References.ПРТ.GetComponent()
  // Создать View для справочника 
  RefView = Reference.CreateView(Reference.MainViewCode)
   AddWhere1 =  Reference.AddWhere(Format("MBAnalit.Kod in (%s)"; List))
  // Установить отображения представления в режиме "Выбор"
  RefView.ViewMode = vmSelect  
  RefViewFrom = RefView.MainForm  
  // Показать форму справочника
  RefViewFrom.Show  

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