Итак, заказчик захотел реализовать следующий управленческий механизм: вводить в ЗУП предельное значение ФОТ для каждой должности. Также необходим был отчет, который показывает динамику данного управленческого ФОТ. Для решения задачи был создан управленческий документ и регистр сведений. Документ задает размер предельного ФОТ, дату начала и дату окончания действия, то есть интервал. Естественно, один интервал мог накладываться на другой. Соответственно, нужно было или писать сразу интервалы в регистр, или динамически получать их в запросе. В ходе изучения механизмов ЗУП и опыта коллег, было найдено 2 варианта решения:
1. Писать в регистр размер лимита и дату начала действия. И затем, при построении отчетов в запросе строить интервалы. Ранее похожая задача уже решалась для конфигурации 1С:ЕРП, для ресурсных спецификаций. Суть задачи: найти промежутки времени, в которые у готовой продукции не было действующей спецификации. Ресурсная спецификация в 1С:ЕРП имеет дату начала действия и дату окончания действия, которые хранятся в регистре. Решение поставленной задачи для ресурсных спецификаций было сначала реализовано классическим способом, однако, с ростом разнообразия готовой продукции и полуфабрикатов, время выполнения такого запроса начинало увеличиваться нелинейно. Отчет был переписан на ином принципе, очередное спасибо за это замечательному генератору нестандартных решений под ником ildarovich (крайне рекомендую его статьи к прочтению), и его статье Быстрое определение интервалов в запросе. Описываемый отчет для 1С:ЕРП не тема данной статьи, скажу лишь, что сам запрос по методу Ильдаровича вышел на 900 строк, но работал крайне шустро. Как вариант решения текущей задачи, можно было писать как есть в регистр дату начала и дату окончания действия лимита в нужных разрезах, а интервалы получать в запросе по методу Ильдаровича.
2. При проведении документа сразу вычислять и писать интервалы. И конфигурация ЗУП уже имеет такие механизмы. Ничего изобретать не нужно.
Итак, какой же способ решения выбрать?
Опыт применения способа 1 показал следующее. Если редко делать подобные задачи, то приемы и способы забываются, и открыв свою же доработку спустя полгода требуется время вспомнить, как и зачем это было сделано. Для сравнения, аналогичные ситуации могут возникнуть и при использовании такого механизма платформы, как СхемаЗапроса. Поскольку СхемаЗапроса применяется редко, через некоторое время в своих же доработках на её основе трудно уже разобраться. А вот СтрЗаменить въедается на клеточном уровне.. Соответственно, коллега по цеху за СхемаЗапроса скорее всего не придет в восторг... А от СтрЗаменить наверняка не испытает дискомфорта... Способы маэстро Ильдаровича восхититительны, но пожалеем коллег, которым, возможно, придется поддерживать наш код, и применим способ 2.
Попробуем посмотреть, как устроены интервальные регистры. За основу возьмем типовой регистр ПлановыеНачисления. Он наиболее подходит по смыслу. С регистром сведений ПлановыеНачисления идет в связке вспомогательный регистр ПлановыеНачисленияИнтервальный. Вспомогательный интервальный регистр должен называться так ИмяОсновногоРегистра + Интервальный. Повторим структуру ПлановыхНачислений для нашего регистра:
Основной регистр периодический и подчиненный регистратору. Вспомогательный интервальный независимый и непериодический. Запись в интервальный регистр происходит в событии набора записей ПриЗаписи.. Переносим процедуры из "Эталонного" регистра ПлановыеНачисления в наш регистр:
Функцию модуля набора записей ТаблицаИзменившихсяДанныхНабора() так же переносим, она нужна в процессе работы функции ЗарплатаКадрыПериодическиеРегистры.СформироватьДвиженияИнтервальногоРегистраПоИзменениям(
"ИмяОсновногоРегистра", НаборЗаписейОсновнннногоРегистра).
Обязательно переносим функции модуля менеджера:
Основное измерение у нас будет не сотрудник, как в большинстве других регистров в ЗУП, а Должность.
Можно отметить, что механизм интервальных регистров имеет программный интерфейс, к которому мы легко подключились, немного исследовав наиболее подходящий под нашу задачу штатный регистр. Реализован он в общем модуле ЗарплатаИКадрыПериодическиеРегистры.
К сожалению, четкого описания программного интерфейса интервальных регистров нет, и приходится подключаться методом научного тыка.
В итоге механизм готов. Пробуем ввести данные:
Вот так, достаточно просто, штатными средствами ЗУП получили свои интервалы.
Теперь нужно прочитать их запросом. И тут не будем писать свой запрос, воспользуемся предложенными ЗУП способами. Ранее я попытался описать их здесь и здесь. Обработка поможет, подскажет, как составить запрос-пустышку к собственному интервальному регистру:
ВЫБРАТЬ
ДАТАВРЕМЯ(1, 1, 1) КАК Период
ПОМЕСТИТЬ Представления_Периоды_МесяцыОтчета
ГДЕ
"НачалоИнтервала" = &НачалоПериода
И "ОкончаниеИнтервала" = &КонецПериода
И "Периодичность" = "МЕСЯЦ"
И "ИспользоватьКонецПериода" = ЛОЖЬ
;
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Представления_Периоды.Период КАК Период,
ШР.Ссылка КАК ДолжностьПоШтатномуРасписанию,
ШР.Подразделение КАК Подразделение,
Организации.Ссылка КАК Организация
ПОМЕСТИТЬ ВТОтборДляСрезаПоследних
ИЗ
Справочник.ШтатноеРасписание КАК ШР
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Организации КАК Организации
ПО ШР.Владелец = Организации.Ссылка,
Представления_Периоды_МесяцыОтчета КАК Представления_Периоды
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ДАТАВРЕМЯ(1, 1, 1) КАК Период,
ДАТАВРЕМЯ(1, 1, 1) КАК ПериодЗаписи,
ДАТАВРЕМЯ(1, 1, 1) КАК ПериодВозвратногоСобытия,
ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка) КАК Подразделение,
ЗНАЧЕНИЕ(Справочник.ШтатноеРасписание.ПустаяСсылка) КАК ДолжностьПоШтатномуРасписанию,
ЗНАЧЕНИЕ(Документ.демо_ЛимитыПлановыхНачислений.ПустаяСсылка) КАК ДокументОснование,
0 КАК Размер,
ИСТИНА КАК Используется,
ИСТИНА КАК ПересчетНеТребуется,
ИСТИНА КАК ВторичнаяЗапись,
ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка) КАК Организация
ПОМЕСТИТЬ Представления_СрезПоследних_демоЛимитыФОТпоПериодам
ИЗ
ВТОтборДляСрезаПоследних КАК ОтборДляСрезаПоследних
ГДЕ
"ТолькоРазрешенные" = ИСТИНА
;
Теперь если поместить этот запрос в отчет, как это описано здесь, можно легко получить вот такой результат:
Демо пример описанного в статье механизма можно посмотреть в исходниках расширения вот здесь. Параллельно с изучением механизмов ЗУП поддержим отечественный облачный сервис для хранения репозиториев исходного кода.