Разработка и Конфигурация · 9 мин
Как заполнить колонку в таблице значений 1С
Как заполнить колонку в таблице значений 1С: добавление колонки, заполнение в цикле, метод ЗаполнитьЗначения, загрузка из другой таблицы. Примеры кода и ошибки.
Таблица значений — один из самых востребованных объектов встроенного языка 1С. С ней работают при выгрузке данных, построении отчётов, обмене между конфигурациями и промежуточной обработке результатов запросов. Заполнение отдельной колонки — типовая задача, которая решается несколькими способами в зависимости от источника данных и логики расчёта.
Выбор подхода зависит от трёх факторов: есть ли уже строки в таблице, откуда берутся значения (константа, вычисление, другая таблица) и нужно ли заполнять всю колонку целиком или только часть строк. Ниже разобраны рабочие варианты с примерами кода, которые можно переносить в свою обработку практически без изменений.
Добавление колонки перед заполнением
Прежде чем заполнять колонку, убедитесь, что она существует. Если таблица создана программно, колонку добавляют методом Колонки.Добавить(), где указывают имя, тип значения и при необходимости заголовок для отображения.
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
Тип колонки задавать не обязательно — тогда в ней можно хранить значения любого типа. Но явное указание типа дисциплинирует код: платформа не даст записать строку в числовую колонку, и ошибка вылезет сразу, а не при дальнейших расчётах. Если таблица получена из запроса (Запрос.Выполнить().Выгрузить()), колонки уже созданы по полям выборки, и добавлять их повторно не нужно — это вызовет ошибку дублирования имени.
Заполнение колонки в цикле по строкам
Базовый и самый гибкий способ — перебор строк с присвоением значения каждой ячейке. Он подходит, когда значение вычисляется индивидуально: по формуле, по условию, по данным другой колонки той же строки.
Для Каждого Строка Из ТЗ Цикл
Строка.Сумма = Строка.Количество * Строка.Цена;
КонецЦикла;
Если значение зависит от условия, логика описывается прямо внутри цикла:
Для Каждого Строка Из ТЗ Цикл
Если Строка.Количество > 100 Тогда
Строка.Статус = "Крупная отгрузка";
ИначеЕсли Строка.Количество > 0 Тогда
Строка.Статус = "Обычная";
Иначе
Строка.Статус = "Нет движения";
КонецЕсли;
КонецЦикла;
Цикл удобен ещё и тем, что в нём легко сделать отладку: поставьте точку останова внутри тела цикла и посмотрите значения текущей строки в табло. Это быстрее, чем искать причину неверного итога после пакетного заполнения.
- 1Убедитесь, что колонка существует: при необходимости добавьте через Колонки.Добавить
- 2Проверьте, что в таблице есть строки (ТЗ.Количество() > 0)
- 3Напишите цикл Для Каждого Строка Из ТЗ с присвоением значения
- 4Запустите в отладке и проверьте первую и последнюю строку
- 5Проверьте итог: сверните таблицу или выведите колонку в табличный документ
Заполнение всей колонки одним значением
Когда всю колонку нужно заполнить одинаковым значением — например, проставить текущую дату, признак обработки или значение по умолчанию, — цикл не нужен. Используйте метод ЗаполнитьЗначения(), который работает быстрее и короче.
ТЗ.ЗаполнитьЗначения(ТекущаяДатаСеанса(), "ДатаОбработки");
ТЗ.ЗаполнитьЗначения(Истина, "Выгружать");
Вторым параметром можно передать список имён колонок через запятую, если заполняется сразу несколько: ТЗ.ЗаполнитьЗначения(0, "СуммаНДС, СуммаСкидки"). Это удобно для инициализации числовых колонок нулями перед последующими расчётами — иначе в незаполненных ячейках останется Неопределено, и арифметика выдаст ошибку или неожиданный результат.
ТЗ.ЗаполнитьЗначения(0, "Сумма, Скидка, Наценка");Заполнение колонки из другой таблицы или запроса
Частая ситуация: основная таблица уже есть, а значения для новой колонки лежат в результате запроса или другой таблице значений. Здесь есть два рабочих подхода.
Сопоставление через соответствие
Если таблицы связываются по ключу (например, по номенклатуре), быстрее всего построить соответствие «ключ → значение» и пройтись по основной таблице один раз:
Цены = Новый Соответствие;
Для Каждого СтрокаЦены Из ТаблицаЦен Цикл
Цены.Вставить(СтрокаЦены.Номенклатура, СтрокаЦены.Цена);
КонецЦикла;
Для Каждого Строка Из ТЗ Цикл
НайденнаяЦена = Цены[Строка.Номенклатура];
Строка.Цена = ?(НайденнаяЦена = Неопределено, 0, НайденнаяЦена);
КонецЦикла;
Такой подход работает за линейное время. Обратный вариант — для каждой строки вызывать ТаблицаЦен.Найти() — на больших таблицах заметно медленнее, потому что поиск выполняется перебором.
Загрузка колонки целиком
Если порядок строк в обеих таблицах гарантированно совпадает (например, вторая таблица получена из той же выборки с сортировкой), можно использовать ЗагрузитьКолонку:
ТЗ.ЗагрузитьКолонку(ТаблицаЦен.ВыгрузитьКолонку("Цена"), "Цена");
Метод требует, чтобы количество значений совпадало с количеством строк, иначе будет ошибка. Перед использованием убедитесь, что источник отсортирован так же, как приёмник, — иначе значения «уедут» на чужие строки, и заметить это сложно.
Сравнение способов заполнения
Подходит для вычисляемых и условных значений. Гибкий, но многословный
Одно значение на всю колонку. Самый быстрый и короткий вариант
Подстановка данных из другой таблицы по ключу. Оптимален для больших объёмов
Перенос колонки целиком при совпадающем порядке строк. Требует контроля сортировки
Заполнение колонки в табличной части документа
Табличная часть документа — не таблица значений, но синтаксис заполнения колонки почти идентичен: перебор строк с присвоением. Отличие в том, что изменения нужно записать в базу, иначе они пропадут.
ДокументОбъект = ДокументСсылка.ПолучитьОбъект();
Для Каждого Строка Из ДокументОбъект.Товары Цикл
Строка.Цена = Строка.Сумма / ?(Строка.Количество = 0, 1, Строка.Количество);
КонецЦикла;
ДокументОбъект.Записать();
Обратите внимание на защиту от деления на ноль в примере выше — это типичный источник падения обработки. Любые вычисления с данными из других колонок должны учитывать пустые и нулевые значения.
Типичные ошибки и проверка результата
После заполнения всегда проверяйте результат, а не только отсутствие ошибок. Самый быстрый способ — вывести таблицу в табличный документ или посмотреть её в отладчике через «Вычислить выражение». Для числовых колонок полезно свернуть таблицу методом Свернуть и сравнить итог с контрольным значением.
Как проверить результат
Совпадает с ТЗ.Количество() для обязательной колонки
Часть строк содержит Неопределено или пустые значения
Все значения соответствуют типу колонки
Смешанные типы: где-то число, где-то строка
Сумма совпадает с контрольным значением из источника
Расхождение — ищите пропущенные или задвоенные строки
FAQ
Как заполнить колонку значением по умолчанию только в пустых ячейках?
Метод ЗаполнитьЗначения перезапишет все значения, поэтому для выборочного заполнения используйте цикл с проверкой: Если Не ЗначениеЗаполнено(Строка.ИмяКолонки) Тогда — присвоить значение по умолчанию. Так сохранятся уже заполненные ячейки.
Можно ли заполнить колонку без цикла разными значениями?
Да, если значения уже собраны в массив — используйте ЗагрузитьКолонку(Массив, "ИмяКолонки"). Массив должен содержать ровно столько элементов, сколько строк в таблице, и порядок элементов должен соответствовать порядку строк.
Почему после присвоения в цикле колонка остаётся пустой?
Чаще всего цикл идёт по копии таблицы или по другой переменной, а не по той таблице, которую вы потом проверяете. Вторая причина — таблица пуста, и цикл не выполнился ни разу. Проверьте ТЗ.Количество() перед циклом.
Как заполнить колонку нумерацией строк?
В цикле используйте счётчик: Сч = 0; затем внутри цикла Сч = Сч + 1; Строка.НомерСтроки = Сч. Альтернатива — цикл Для Сч = 0 По ТЗ.Количество() - 1 с обращением ТЗ[Сч].НомерСтроки = Сч + 1.
Чем отличается заполнение колонки в таблице значений и в динамическом списке?
Динамический список нельзя редактировать программно напрямую — он отображает результат запроса. Чтобы «заполнить колонку» в нём, нужно изменить текст запроса источника, добавив вычисляемое поле, либо заменить динамический список таблицей значений.
Как перенести заполненную колонку из таблицы значений в табличную часть документа?
Если структура совпадает, проще всего загрузить всю таблицу: ДокументОбъект.Товары.Загрузить(ТЗ). Если нужно перенести только одну колонку, перебирайте строки обеих таблиц параллельно по индексу или сопоставляйте по ключевому полю через соответствие.
Что важно запомнить
Сначала убедитесь, что колонка существует и в таблице есть строки. Одно значение на всю колонку — ЗаполнитьЗначения, вычисляемые данные — цикл, подстановка из другой таблицы — соответствие. После заполнения проверяйте количество заполненных строк и итог по числовым колонкам.