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