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