Приветствуем вас, уважаемые разработчики! Сегодня мы детально разберем три крайне популярные и одновременно каверзные проблемы, с которыми регулярно сталкиваются специалисты при проектировании отчетов на базе Системы компоновки данных (СКД) в 1С. Эти вопросы часто ставят в тупик из-за неочевидного поведения платформы. Мы подробно проанализируем каждую ситуацию, выясним внутренние причины такого поведения системы и разберем по шагам готовые практические решения.
Разберем типичную ситуацию: вы изменили заголовок или структуру отчета в Конфигураторе, сохранили изменения, но при запуске отчета в режиме «1С:Предприятие» продолжаете наблюдать старое название или прежний состав колонок. Даже перенос схемы компоновки данных в абсолютно новый отчет не всегда помогает исправить ситуацию.
Выясним причину поведения системы: В современных конфигурациях 1С (особенно построенных на базе Библиотеки стандартных подсистем — БСП) активно используется механизм Хранилища вариантов отчетов и пользовательских настроек. Как только пользователь хотя бы один раз открывает отчет или сохраняет какие-то персональные параметры, платформа 1С записывает эти настройки в специальное системное хранилище (таблицы базы данных) под уникальным ключом, привязанным к имени объекта метаданных. При всех последующих открытиях отчета система отдает приоритет именно сохраненным в базе данных настройкам, полностью игнорируя новые дефолтные значения из Конфигуратора.
Проанализируем три надежных способа решения этой проблемы без варварского переименования самого отчета в метаданных.
Это самый простой и быстрый способ для конечного пользователя или разработчика в процессе отладки. Чтобы заставить систему перечитать настройки из Конфигуратора, выполним следующие действия:
После выполнения этого действия старый кэш в пользовательских настройках будет перезаписан актуальными данными из вашей схемы компоновки.
Если вам необходимо сбросить старые заголовки или варианты настроек сразу у нескольких пользователей централизованно, воспользуемся стандартными возможностями БСП:
Для разработчиков тиражных решений ручной сброс настроек у клиентов невозможен. В таком случае лучшим решением будет программный сброс настроек при очередном обновлении конфигурации. Для этого мы можем применить методы программного интерфейса БСП. Рассмотрим следующий пример кода:
// Пример программного сброса пользовательских настроек для конкретного отчета
Процедура СброситьНастройкиОтчета() Экспорт
ИмяОтчета = "ИмяВашегоОтчета";
ОбъектМетаданных = Метаданные.Отчеты[ИмяОтчета];
Если ОбъектМетаданных <> Неопределено Тогда
// Вызываем метод БСП для сброса сохраненных вариантов и настроек пользователей
ВариантыОтчетов.СброситьПользовательскиеНастройки(ОбъектМетаданных);
КонецЕсли;
КонецПроцедуры
Использование этого метода гарантирует, что при первом запуске обновленной конфигурации все пользователи гарантированно увидят новый заголовок и актуальную структуру отчета.
Перейдем ко второму вопросу. Иногда стандартных периодов группировки в СКД (таких как день, неделя, декада, месяц) оказывается недостаточно. Бизнес-пользователи могут потребовать разбить данные по специфическим интервалам внутри каждого месяца. Например, нам нужно вывести колонки с 1 по 7 число, с 8 по 14, с 15 по 21, с 22 по 28, а также остаток месяца.
Проанализируем ситуацию: стандартная группировка по неделям здесь не подойдет, так как неделя может начинаться в одном месяце, а заканчиваться в другом, ломая строгую привязку к календарному месяцу. Нам нужны изолированные интервалы внутри каждого конкретного месяца. Разберем два отличных варианта реализации этой задачи.
Этот способ хорош тем, что нам не нужно усложнять сам запрос к базе данных. Запрос остается максимально простым и извлекает базовую дату операции. Всю логику распределения по интервалам мы перекладываем на плечи процессора компоновки данных.
Разберем по шагам настройку вычисляемого поля:
ИнтервалМесяцаВ поле Выражение напишем следующую логическую конструкцию выбора:
Выбор
Когда День(Дата) <= 7 Тогда "01-07"
Когда День(Дата) <= 14 Тогда "08-14"
Когда День(Дата) <= 21 Тогда "15-21"
Когда День(Дата) <= 28 Тогда "22-28"
Иначе "29+"
Конец
После этого перейдем на вкладку Настройки. В структуре отчета (если вы используете Таблицу) в области Колонки добавим сначала группировку по месяцу (используем системное поле или выражение НАЧАЛОПЕРИОДА(Дата, "МЕСЯЦ")), а внутрь этой группировки поместим подчиненную группировку по нашему новому вычисляемому полю ИнтервалМесяца. Теперь данные будут разложены по заданным периодам внутри каждого месяца.
Если вы хотите предоставить пользователю возможность быстрой фильтрации или хотите оптимизировать производительность вычислений на стороне СУБД, аналогичную логику можно прописать прямо в тексте запроса. Посмотрим на пример реализации такого запроса:
ВЫБРАТЬ
Продажи.Контрагент КАК Контрагент,
Продажи.СуммаОбороты КАК Сумма,
НАЧАЛОПЕРИОДА(Продажи.Период, МЕСЯЦ) КАК МесяцПериода,
ВЫБОР
КОГДА ДЕНЬ(Продажи.Период) <= 7 ТОГДА "01-07"
КОГДА ДЕНЬ(Продажи.Период) <= 14 ТОГДА "08-14"
КОГДА ДЕНЬ(Продажи.Период) <= 21 ТОГДА "15-21"
КОГДА ДЕНЬ(Продажи.Период) <= 28 ТОГДА "22-28"
ИНАЧЕ "29+"
КОНЕЦ КАК ИнтервалМесяца
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК Продажи
Важное предостережение для обоих вариантов: Если в каком-то интервале (например, с 8 по 14 число) не было совершено ни одной операции, эта колонка просто пропадет из результирующей таблицы отчета. Чтобы пустые интервалы гарантированно выводились на экран (даже с нулевыми значениями), вам потребуется в тексте запроса сделать левое соединение вашей таблицы продаж с искусственным календарем-генератором, содержащим все интервалы для выбранного периода.
Это классическая проблема многомерного анализа данных в СКД. Представим ситуацию: у нас есть счета на оплату, выставленные в апреле, и платежные поручения, подтверждающие их оплату в мае. Пользователь хочет видеть горизонтальную временную шкалу по месяцам (Апрель, Май, Июнь...), где сумма счета попадет строго в колонку «Апрель», а сумма оплаты по этому же счету — строго в колонку «Май».
Если вы попытаетесь связать эти данные напрямую и сгруппировать по дате счета, то оплата майская привяжется к апрелю. Если сгруппируете по дате оплаты — апрельский счет «переедет» в май. Нам необходимо выполнить нормализацию данных, объединив разные временные показатели в единую хронологическую шкалу. Рассмотрим два профессиональных метода реализации этой задачи.
Этот подход является наиболее производительным и рекомендуемым для большинства задач. Мы разделяем одну строку (где есть и счет, и оплата) на две независимые записи с общим виртуальным полем Период. Посмотрим на структуру такого запроса:
// Объединяем начисления (счета) и движения денежных средств (оплаты) в единую таблицу
ВЫБРАТЬ
Счет.Контрагент КАК Контрагент,
НАЧАЛОПЕРИОДА(Счет.Дата, МЕСЯЦ) КАК Период,
Счет.СуммаДокумента КАК СуммаСчета,
0 КАК СуммаОплаты
ИЗ
Документ.СчетНаОплату КАК Счет
ГДЕ
Счет.Проведен = ИСТИНА
ОБЪЕДИНЕНИЕ ВСЕ
ВЫБРАТЬ
Оплата.Контрагент КАК Контрагент,
НАЧАЛОПЕРИОДА(Оплата.Дата, МЕСЯЦ) КАК Период,
0 КАК СуммаСчета,
Оплата.СуммаДокумента КАК СуммаОплаты
ИЗ
Документ.ОплатаПокупателя КАК Оплата
ГДЕ
Оплата.Проведен = ИСТИНА
После того как текст запроса готов, правильно настроим СКД:
СуммаСчета и СуммаОплаты ресурсами (с функцией Сумма(СуммаСчета) и Сумма(СуммаОплаты) соответственно).Контрагент.Период (оформив его представление как Месяц).СуммаСчета и СуммаОплаты.Теперь система отработает идеально: за апрель вы увидите сумму выставленного счета, а за май — сумму пришедшей оплаты, и все это будет находиться в рамках одной красивой и понятной таблицы.
Если исходные запросы для получения счетов и оплат слишком сложные, громоздкие или собираются из разных источников, использовать один тяжелый SQL-запрос с ОБЪЕДИНЕНИЕ ВСЕ может быть неудобно. В таком случае на помощь приходит встроенный механизм СКД по объединению наборов данных:
НаборДанныхСчета. Напишите туда запрос, извлекающий данные по счетам. Поле даты назовите Период, сумму — СуммаСчета.НаборДанныхОплаты. Напишите туда запрос, извлекающий оплаты. Поле даты также назовите Период, сумму — СуммаОплаты.ОбъединениеДанных.Контрагент и Период из обоих наборов сопоставлены друг с другом.При формировании отчета процессор СКД самостоятельно выполнит аналог операции UNION ALL на уровне внутренней обработки данных, предоставив вам единую аналитическую картину.
Мы подробно рассмотрели три важнейших аспекта разработки сложных отчетов в СКД. Надеемся, что эти практические приемы помогут вам создавать быстрые, точные и удобные отчеты для ваших пользователей. Успешной разработки!