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