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