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