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