Введение
Привет всем! Отвлечемся от разбора функционала библиотеки стандартных подсистем и уделим немного внимания возможностям типовой конфигурации Зарплата и управление персоналом 3.1 (ЗУП). В текущей статье я рассмотрю и приведу примеры работы с подсистемой ЗУПа - "ЗарплатаКадрыПериодическиеРегистры". Если быть кратким, то в статье рассмотрим функционал получения данных и создания запросов к периодическим регистрам конфигурации ЗУП через фильтр отбора на основе менеджера временных таблиц.
Разработку примеров буду вести на платформе 1С:Предприятия 8.3.21.1484 и конфигурации "Зарплата и управление персоналом 3.1" (3.1.23.68) - последняя на момент написания этой статьи - середина сентября 2022 г.
Статья ориентирована исключительно на программистов-разработчиков, думаю, среднего уровня, как работающим с ЗУП, так и желающим узнать тонкости работы с этой конфигурацией. Сразу переходим к примерам:
Практические примеры статьи
1.Вернем таблицу записей периодического регистра.
Для этого воспользуемся функцией подсистемы - ТаблицаВТИмяРегистра(Знач ИмяРегистра, МенеджерВременныхТаблиц, ТолькоРазрешенные, ОписаниеФильтра, ПараметрыПостроения = Неопределено) Экспорт
Код применения функции вот такой:
&НаСервере
Процедура ВыполнитьЗапросНаСервере()
ИмяРегистра = "ЗаработанныеПраваНаОтпуска"; // Периодический регистр сведений СтандартныйПериод
// сформируем менеджер временных таблиц для использования в качестве "фильтра" отбора
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст = "ВЫБРАТЬ
| Сотрудники.Ссылка КАК Сотрудник,
| &Период КАК Период,
| &ДатаНачала КАК ДатаНачала,
| &ДатаОкончания КАК ДатаОкончания,
| &ВидЕжегодногоОтпуска КАК ВидЕжегодногоОтпуска
|ПОМЕСТИТЬ ВТСотрудник
|ИЗ
| Справочник.Сотрудники КАК Сотрудники
|ГДЕ
| Сотрудники.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Период", дата(1,1,1));
Запрос.УстановитьПараметр("ДатаНачала", дата(1,1,1));
Запрос.УстановитьПараметр("ДатаОкончания", ТекущаяДата());
Запрос.УстановитьПараметр("Ссылка", Справочники.Сотрудники.НайтиПоКоду("0000-00015"));
Запрос.УстановитьПараметр("ВидЕжегодногоОтпуска", Справочники.ВидыОтпусков.НайтиПоНаименованию("За интенсивный труд и ответственность"));
Запрос.Выполнить();
ТолькоРазрешенные = Ложь;
ПараметрыПостроения = ЗарплатаКАдрыПериодическиеРегистры.ПараметрыПостроенияДляСоздатьВТИмяРегистра(); // конструктор
ОписаниеФильтра = ЗарплатаКадрыПериодическиеРегистры.ОписаниеФильтраДляСоздатьВТИмяРегистра("ВТСотрудник","Сотрудник, ВидЕжегодногоОтпуска");
ТабЗнч = ЗарплатаКадрыПериодическиеРегистры.ТаблицаВТИмяРегистра(ИмяРегистра, Запрос.МенеджерВременныхТаблиц, ТолькоРазрешенные, ОписаниеФильтра,ПараметрыПостроения);
// результат - таблица значения по фильтру - отбору
КонецПроцедуры
где, ПараметрыПостроенияДляСоздатьВТИмяРегистра - это "конструктор" такого вида
Функция ПараметрыПостроенияДляСоздатьВТИмяРегистра() Экспорт
ПараметрыПостроения = ПараметрыПостроенияВТИмяРегистра();
ПараметрыПостроения.Вставить("ВключатьЗаписиНаНачалоПериода", Ложь);
ПараметрыПостроения.Вставить("ИмяВременнойТаблицыЗаписейНаНачалоПериода", "");
ПараметрыПостроения.Вставить("ИспользуемоеИмяВременнойТаблицыЗаписейНаНачалоПериода", "");
ПараметрыПостроения.Вставить("ОтборыЗаписейНаНачалоПериода", Неопределено);
Возврат ПараметрыПостроения;
КонецФункции
а ОписаниеФильтраДляСоздатьВТИмяРегистра - функция, возвращающая структуру "отбора" к основному регистру
Функция ОписаниеФильтраДляСоздатьВТИмяРегистра(Знач ТаблицаФильтра, ИзмеренияФильтра = "", ДополнительныеПоляФильтра = "") Экспорт
Если ТипЗнч(ТаблицаФильтра) = Тип("Строка") Тогда
Возврат ОписаниеФильтраДляСоздатьВТИмяРегистраПоВременнойТаблице(ТаблицаФильтра, ИзмеренияФильтра, ДополнительныеПоляФильтра);
Иначе
Если Не ЗначениеЗаполнено(ИзмеренияФильтра) Тогда
ИзмеренияФильтра = Новый Массив;
Для Каждого Колонка Из ТаблицаФильтра.Колонки Цикл
Если ВРег(Колонка.Имя) <> ВРег("Период")
И ВРег(Колонка.Имя) <> ВРег("ДатаНачала")
И ВРег(Колонка.Имя) <> ВРег("ДатаОкончания") Тогда
ИзмеренияФильтра.Добавить(Колонка.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ОписаниеФильтраДляСоздатьВТИмяРегистраПоТаблицеЗначений(ТаблицаФильтра, ИзмеренияФильтра, ДополнительныеПоляФильтра);
КонецЕсли;
КонецФункции
Выглядит это вот так:
Рис.1. Структура фильтра-отбора, который применим к основной таблице регистра.
Далее, ТаблицаВТИмяРегистра обрабатывает вот такой сконструированный запрос, по результату которого, мы получим нашу выборку из регистра в таблице значений. Запрос автоматически сформирован вот так:
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(РегистрСведений.Период,ДЕНЬ) КАК Период,
РегистрСведений.Период КАК ПериодЗаписи,
(РегистрСведений.Период >= ИзмеренияДаты.ДатаНачала
И РегистрСведений.Период <=
ВЫБОР
КОГДА ИзмеренияДаты.ДатаОкончания = ДАТАВРЕМЯ(1, 1, 1)
ТОГДА ДАТАВРЕМЯ(3999, 12, 31, 23, 59, 59)
ИНАЧЕ КОНЕЦПЕРИОДА(ИзмеренияДаты.ДатаОкончания,ДЕНЬ)
КОНЕЦ) КАК ЗаписьПериода,
РегистрСведений.Сотрудник КАК Сотрудник,
РегистрСведений.ВидЕжегодногоОтпуска КАК ВидЕжегодногоОтпуска,
РегистрСведений.КоличествоДней КАК КоличествоДней,
РегистрСведений.ДатаНачала КАК ДатаНачала,
РегистрСведений.ДатаОкончания КАК ДатаОкончания,
РегистрСведений.КоличествоДнейЗаПериод КАК КоличествоДнейЗаПериод
ПОМЕСТИТЬ ВТДоступныеЗаписиЗаработанныеПраваНаОтпуска
ИЗ
ВТСотрудник КАК ИзмеренияДаты
Внутреннее СОЕДИНЕНИЕ РегистрСведений.ЗаработанныеПраваНаОтпуска КАК РегистрСведений
ПО (
(РегистрСведений.Период >= ИзмеренияДаты.ДатаНачала
И (РегистрСведений.Период <=
ВЫБОР
КОГДА ИзмеренияДаты.ДатаОкончания = ДАТАВРЕМЯ(1, 1, 1)
ТОГДА ДАТАВРЕМЯ(3999, 12, 31, 23, 59, 59)
ИНАЧЕ КОНЕЦПЕРИОДА(ИзмеренияДаты.ДатаОкончания,ДЕНЬ)
КОНЕЦ)))
И (РегистрСведений.Сотрудник = ИзмеренияДаты.Сотрудник)
И (РегистрСведений.ВидЕжегодногоОтпуска = ИзмеренияДаты.ВидЕжегодногоОтпуска)
Внутреннее соединение нашей таблицы фильтра и таблицы регистра даст нам необходимы результат отбора по регистру:
Рис.2. Внутреннее соединение таблиц "фильтра" и регистра дает нам корректный отбор по заданным параметрам фильтра.
Далее, перейдем ко второму примеру данной подсистемы:
2.Возвращает таблицу среза последних регистра
Для этого воспользуемся функцией - ТаблицаВТИмяРегистраСрезПоследних(Знач ИмяРегистра, МенеджерВременныхТаблиц, ТолькоРазрешенные, ОписаниеФильтра, ПараметрыПостроения = Неопределено) Экспорт
Код вот такой - он практически идентичен:
&НаСервере
Процедура ВыполнитьЗапросНаСервере()
ИмяРегистра = "ЗаработанныеПраваНаОтпуска"; // Периодический регистр сведений СтандартныйПериод
// сформируем менеджер временных таблиц для использования в качестве "фильтра" отбора
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст = "ВЫБРАТЬ
| Сотрудники.Ссылка КАК Сотрудник,
| &Период КАК Период,
| &ДатаНачала КАК ДатаНачала,
| &ДатаОкончания КАК ДатаОкончания,
| &ВидЕжегодногоОтпуска КАК ВидЕжегодногоОтпуска
|ПОМЕСТИТЬ ВТСотрудник
|ИЗ
| Справочник.Сотрудники КАК Сотрудники
|ГДЕ
| Сотрудники.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Период", дата(1,1,1));
Запрос.УстановитьПараметр("ДатаНачала", дата(1,1,1));
Запрос.УстановитьПараметр("ДатаОкончания", ТекущаяДата());
Запрос.УстановитьПараметр("Ссылка", Справочники.Сотрудники.НайтиПоКоду("0000-00015"));
Запрос.УстановитьПараметр("ВидЕжегодногоОтпуска", Справочники.ВидыОтпусков.Основной);
Запрос.Выполнить();
ТолькоРазрешенные = Ложь;
ПараметрыПостроения = ЗарплатаКАдрыПериодическиеРегистры.ПараметрыПостроенияДляСоздатьВТИмяРегистра(); // конструктор
ОписаниеФильтра = ЗарплатаКадрыПериодическиеРегистры.ОписаниеФильтраДляСоздатьВТИмяРегистра("ВТСотрудник","Сотрудник, ВидЕжегодногоОтпуска");
ТабЗнч = ЗарплатаКадрыПериодическиеРегистры.ТаблицаВТИмяРегистраСрезПоследних(ИмяРегистра, Запрос.МенеджерВременныхТаблиц, ТолькоРазрешенные, ОписаниеФильтра,ПараметрыПостроения);
// результат - таблица значения по фильтру - отбору
КонецПроцедуры
Отмечу, что параметры фильтра отбора "Период", "ДатаНачала" и "ДатаОкончания" - являются всегда обязательными для периодических регистров. "Период" - для получения представлений среза. "ДатаНачала" и "ДатаОкончания" - для получения таблицы регистра.
3.Другие функции запросов "через фильтр менеджера временных таблиц".
Так же в подсистеме существуют другие процедуры и функции запросов к регистрам - работают они "по-аналогии". Вот часть из них:
3.1. Возвращает таблицу периодов регистра.
ТаблицаВТИмяРегистраПериоды(Знач ИмяРегистра, МенеджерВременныхТаблиц, ТолькоРазрешенные, ОписаниеФильтра, ПараметрыПостроения = Неопределено) Экспорт
3.2. Создает временную таблицу записей регистра в менеджере временных таблиц, переданном в качестве параметра.
СоздатьВТИмяРегистра(Знач ИмяРегистра, МенеджерВременныхТаблиц, ТолькоРазрешенные, ОписаниеФильтра, ПараметрыПостроения = Неопределено, ИмяРезультирующейТаблицы = Неопределено) Экспорт
3.3. Возвращает запрос представления ВТИмяРегистра.
ЗапросВТИмяРегистра(ИмяРегистра, ТолькоРазрешенные, ОписаниеФильтра, ПараметрыПостроения = Неопределено, ИмяСоздаваемойТаблицы = Неопределено) Экспорт
3.4. Возвращает запрос представления ВТИмяРегистраСрез.
ЗапросВТИмяРегистраСрез(ИмяРегистра, ТолькоРазрешенные, ОписаниеФильтра, ПараметрыПостроения = Неопределено, СрезПоследних = Истина, ИмяСоздаваемойТаблицы = Неопределено) Экспорт
3.5. Возвращает запрос представления ВТИмяРегистраПериоды.
ЗапросВТПериодыИмяРегистра(ИмяРегистра, ТолькоРазрешенные, ОписаниеФильтра, ПараметрыПостроения = Неопределено, ИмяСоздаваемойТаблицы = Неопределено) Экспорт
и другие.... Перейдем к заключению и сделаем выводы
Заключение и выводы
В статье мы разобрали универсальный механизм запроса к периодическим регистрам через "фильтр менеджера временных таблиц" в подсистеме "ЗарплатаКадрыПериодическийРегистры" конфигурации "Зарплата и управление персоналом 3.1." Отмечу, что данная подсистем характерна только для ЗУПа, никакого отношения к БСП и прочим универсальным вещам не имеет. Подсистема позволяет исключить топорное написание "в лоб" запроса к регистру, а воспользоваться более элегантным подходом к получению данных.
Информация будет полезна (еще раз отмечу) для программистов среднего уровня и выше - ну это мое предположение (все-таки это уже "повыше", чем написание запроса к регистру).
Убежден, что представленный в статье материал сократит вам время на разработку, выполнение ваших задач - как я обычно пишу - некий "мануал" - "шпаргалка".
В конце статьи по традиции прошу обратить внимание на мои предыдущие материалы, которые посвящены практике использования БСП.
Актуальные из них:
Базовые принципы работы с регламентными заданиями подсистем БСП
Оценка производительности с помощью БСП
Печать макета MS Word в любом документе с помощью БСП
В заключении оставлю мессадж всем, кому интересно:
Кому интересны мои статьи по программированию, а также практические разработки (платные и бесплатные), - можете связаться со мой через этот профиль и мой личный телеграмм-канал. Готов к любому профессиональному сотрудничеству.