Добавление колонки в таблицу значений 1С 8.3 из встроенного языка

· 9 мин

Содержание

Колонку в таблицу значений добавляют методом Колонки.Добавить(): Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число")). Вызов возвращает объект колонки, а сама колонка появляется у таблицы и в каждой её строке. Всё делается на встроенном языке 1С 8.3, в интерфейсе для этого нет ни одной кнопки.

Таблица значений (ТаблицаЗначений) нужна, когда данные надо собрать в памяти, обработать и отдать дальше: на форму, в запрос, в отчёт, в обмен. Структура у неё не фиксирована. Сначала вы задаёте колонки, потом добавляете строки. Если порядок нарушить, получите ошибку обращения к несуществующему полю.

Что такое колонки и как они устроены

Таблица значений — это коллекция строк и коллекция колонок. Колонки живут в свойстве Колонки и хранятся в том порядке, в каком вы их добавили. Каждая колонка — объект КолонкаТаблицыЗначений со свойствами:

  • 🔹 Имя — идентификатор, по нему обращаются к полю строки;
  • 🔹 ТипЗначения — описание допустимых типов (ОписаниеТипов);
  • 🔹 Заголовок — подпись, которую увидит пользователь, если таблицу выведут в табличное поле;
  • 🔹 Ширина — ширина в символах для отображения.

Имя колонки подчиняется правилам идентификатора: буквы, цифры, подчёркивание, первой цифры быть не может. Пробелы и точки в имени недопустимы. Для красивой подписи есть заголовок, его и заполняйте человеческим текстом.

Таблица значений существует только в оперативной памяти на время выполнения процедуры. В базу она не записывается. Хотите сохранить — кладите в реквизит документа (табличную часть) или в хранилище значения.

Базовый синтаксис: Колонки.Добавить

Полная сигнатура метода такая:

Колонки.Добавить(<Имя>, <ТипЗначения>, <Заголовок>, <Ширина>)

Обязательно только имя. Остальные параметры можно опустить. Минимальный рабочий пример:

Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Номенклатура");
Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка"), "Примечание", 30);

НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Номенклатура = "Стул офисный";
НоваяСтрока.Количество = 5;
НоваяСтрока.Комментарий = "Из резерва";

Здесь Номенклатура создана без типа. В неё можно положить что угодно: строку, ссылку, число. Для временных расчётов так удобно, но для данных, которые пойдут на форму или в запрос, тип лучше задавать.

Колонка с типом, длиной и точностью

Тип задают через ОписаниеТипов. Для числа и строки к нему добавляют квалификаторы:

ТипСумма = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
ТипТекст = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100));
ТипДата  = Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата));

Таблица.Колонки.Добавить("Сумма", ТипСумма);
Таблица.Колонки.Добавить("Наименование", ТипТекст);
Таблица.Колонки.Добавить("ДатаОтгрузки", ТипДата);

КвалификаторыЧисла(15, 2) означает до 15 цифр, из них 2 после запятой. Если число в колонку не помещается по разрядности, значение будет приведено к ограничению типа, поэтому запас разрядов лучше заложить сразу.

Для ссылок указывают имя типа строкой:

Таблица.Колонки.Добавить("Контрагент", Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));
Таблица.Колонки.Добавить("Документ", Новый ОписаниеТипов("ДокументСсылка.РеализацияТоваровУслуг"));

Имена объектов зависят от конфигурации. В БП 3.0, ЗУП 3.1 и УТ 11 справочник Контрагенты есть, а вот состав документов различается. Не уверены в имени — откройте конфигуратор и посмотрите ветку «Документы» в дереве метаданных.

Заголовок и ширина: зачем они нужны

Третий и четвёртый параметры Добавить влияют только на отображение. Заголовок показывается в шапке, когда таблицу выводят на управляемую форму как реквизит с типом «Таблица значений». Ширина задаёт размер колонки в символах. Если параметры не передать, заголовком станет имя, а ширина подберётся платформой.

На логику кода они не действуют. Обращаться к полю всё равно нужно по имени, а не по заголовку. Поэтому имя делайте коротким и без пробелов, а в заголовок пишите то, что должен прочитать пользователь: «Сумма к оплате», «Дата отгрузки».

Ещё одно правило: не используйте в качестве имён колонок слова, которые совпадают со свойствами или методами строки, если не уверены в результате. Безопасный приём — давать предметные имена вроде СуммаДокумента вместо общего Значение.

Составные типы и особые случаи

Колонка может принимать несколько типов сразу. Перечислите их через запятую:

ТипЗначение = Новый ОписаниеТипов("Число, Строка, Дата");
Таблица.Колонки.Добавить("Значение", ТипЗначение);

Квалификаторы при этом работают на соответствующую часть: числовые ограничения — на число, длина — на строку. Составные колонки полезны для универсальных таблиц вроде «показатель — значение», но с ними надо аккуратнее: перед использованием проверяйте ТипЗнч(Строка.Значение).

Несколько способов задать тип

СпособПримерКогда подходит
Без типаКолонки.Добавить("Поле")Временный расчёт, тип заранее неизвестен
Простой типНовый ОписаниеТипов("Число")Числа, строки, даты, булево
Ссылочный типНовый ОписаниеТипов("СправочникСсылка.Склады")Колонка под элементы справочника
СоставнойНовый ОписаниеТипов("Число, Строка")Значения разных видов в одной колонке
Из реквизита метаданныхРеквизит.ТипСтруктура должна повторять объект конфигурации

Для типа «Булево» значение по умолчанию — Ложь, для числа — 0, для строки — пустая строка. Если задан только один тип, новая строка получит пустое значение этого типа. У колонки без типа в поле будет Неопределено.

Куда вставить колонку и как обращаться к ней потом

Добавить всегда ставит колонку в конец. Нужна определённая позиция — используйте Вставить:

Таблица.Колонки.Вставить(0, "НомерСтроки", Новый ОписаниеТипов("Число"), "№");

Первый параметр — индекс, нумерация идёт с нуля. Индекс 0 ставит колонку первой. Порядок важен, когда таблицу показывают пользователю или выгружают в табличный документ: колонки идут слева направо в порядке коллекции.

Что ещё можно делать с коллекцией колонок:

  1. Таблица.Колонки.Количество() — сколько колонок сейчас.
  2. Таблица.Колонки.Найти("Сумма") — вернёт колонку или Неопределено, если такой нет.
  3. Таблица.Колонки.Удалить("Комментарий") — удалить колонку вместе с данными в ней.
  4. Таблица.Колонки.Индекс(Колонка) — узнать позицию колонки.
  5. Обращение по индексу: Таблица.Колонки[0].Имя.

Перед добавлением колонки в код, который может выполниться дважды, проверяйте, нет ли её уже:

Если Таблица.Колонки.Найти("Сумма") = Неопределено Тогда
    Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
КонецЕсли;

Добавление колонки с именем, которое уже занято, приведёт к ошибке выполнения. Особенно часто это бывает в общих модулях, где таблицу собирают из нескольких кусков кода.

Динамическое создание колонок по метаданным

Когда структура таблицы должна совпадать с объектом конфигурации, колонки создают циклом по реквизитам. Пример для табличной части документа:

Таблица = Новый ТаблицаЗначений;
ТабЧасть = Метаданные.Документы.РеализацияТоваровУслуг.ТабличныеЧасти.Товары;

Для Каждого Реквизит Из ТабЧасть.Реквизиты Цикл
    Таблица.Колонки.Добавить(Реквизит.Имя, Реквизит.Тип, Реквизит.Синоним);
КонецЦикла;

Здесь имя берётся из метаданных, тип копируется, а синоним становится заголовком. Таблица получает ровно те поля, что и табличная часть, и в неё можно загрузить данные одной командой.

То же работает для регистра, справочника, любого объекта, у которого есть коллекция Реквизиты. Для измерений и ресурсов регистров используют Измерения и Ресурсы.

Второй частый случай — колонки по списку имён, которые приходят извне:

ИменаКолонок = СтрРазделить("Артикул,Цена,Остаток", ",");
Для Каждого Имя Из ИменаКолонок Цикл
    Таблица.Колонки.Добавить(СокрЛП(Имя));
КонецЦикла;

Так делают при разборе файлов, когда набор столбцов определяется по заголовку. Но имя из внешнего файла может содержать пробелы или точки. Перед Добавить его чистят или заменяют, иначе получите ошибку.

Заполнение таблицы после добавления колонки

Колонка уже есть, теперь данные. Три рабочих способа.

Построчно через цикл. Универсально, медленнее на больших объёмах:

Для Каждого Строка Из Таблица Цикл
    Строка.Сумма = Строка.Количество * Строка.Цена;
КонецЦикла;

Одним значением на все строки. Метод ЗаполнитьЗначения задаёт одно значение в колонке сразу у всех строк:

Таблица.ЗаполнитьЗначения(Ложь, "Обработано");

Из массива. ЗагрузитьКолонку кладёт элементы массива в строки по порядку, ВыгрузитьКолонку делает обратное:

Таблица.ЗагрузитьКолонку(МассивЦен, "Цена");
МассивИмён = Таблица.ВыгрузитьКолонку("Номенклатура");

Размер массива должен соответствовать числу строк. Если строк больше, лишние останутся без значения.

Если колонка добавлена в уже заполненную таблицу, у существующих строк в ней стоит значение по умолчанию. Для расчётных колонок после добавления сразу пройдите циклом и заполните.

Результат запроса превращается в таблицу значений через Выгрузить(), и колонки там уже готовы: имена и типы берутся из полей запроса. Добавлять колонки вручную нужно, когда хотите дополнить такую таблицу своими расчётными полями:

Результат = Запрос.Выполнить();
Таблица = Результат.Выгрузить();
Таблица.Колонки.Добавить("Наценка", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2)));

Что делать с колонками дальше: свёртка, сортировка, индексы

Колонки нужны не только для хранения. На них опираются остальные методы таблицы, поэтому имена и типы стоит продумать заранее.

Сортировка. Таблица.Сортировать("Контрагент, Сумма Убыв") упорядочивает строки по колонкам. Имена в строке перечисляют через запятую, направление убывания дописывают словом Убыв.

Свёртка. Таблица.Свернуть("Контрагент", "Сумма") группирует строки по первой группе колонок и суммирует числовые колонки из второй. Колонки, которых нет ни в одном списке, из результата исчезают. Поэтому если после свёртки вы обращаетесь к «потерянному» полю, причина именно здесь.

Поиск. Таблица.Найти(Значение, "Артикул") ищет строку по значению в колонке. Для отбора нескольких строк используют НайтиСтроки(Новый Структура("Контрагент", Контрагент)): ключи структуры совпадают с именами колонок.

Индексы. Если по колонке часто ищут в большой таблице, ей можно задать индекс через Таблица.Индексы.Добавить("Артикул"). Это ускоряет НайтиСтроки на десятках тысяч строк.

Для вложенных данных, где у строки есть подчинённые строки, вместо таблицы берут ДеревоЗначений. Колонки в нём добавляются тем же способом: Дерево.Колонки.Добавить("Имя").

Копирование структуры

Бывает нужна вторая таблица с теми же колонками. Вручную их переносить незачем:

НоваяТаблица = Таблица.СкопироватьКолонки();

Метод создаёт пустую таблицу с такими же именами и типами. Если нужна копия вместе со строками, используйте Таблица.Скопировать(). Для отбора части колонок передайте их имена вторым параметром: Таблица.Скопировать(, "Номенклатура, Сумма").

Колонки одной таблицы можно перенести в другую в цикле, сохраняя тип и заголовок:

Для Каждого Колонка Из Таблица.Колонки Цикл
    Приёмник.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения, Колонка.Заголовок);
КонецЦикла;

Так удобно собирать итоговую таблицу из нескольких источников, когда набор полей у них одинаковый.

Типичные ошибки при добавлении колонок

  • ⚠️ Обращение к полю до создания колонки. Если вы пишете Строка.Сумма раньше, чем добавили колонку Сумма, платформа сообщит о том, что поле объекта не обнаружено. Сначала структура, потом данные.
  • ⚠️ Дубль имени. Одна и та же колонка добавляется в цикле. Решение: Найти перед Добавить или вынос создания структуры из цикла.
  • ⚠️ Недопустимое имя. Колонка «Цена за штуку» не создастся. Пишите ЦенаЗаШтуку, а красивый текст кладите в заголовок.
  • ⚠️ Слишком узкий квалификатор. Колонка с КвалификаторыЧисла(5, 0) не вместит 123456. Для денег берите (15, 2), для количества — (15, 3).
  • ⚠️ Тип не совпадает с данными. В колонку со ссылочным типом нельзя положить строку «Склад №1»: значение не сохранится как ссылка, и в колонке окажется пустое значение. Для разнородных данных задавайте составной тип.
  • ⚠️ Путаница с индексами. В Вставить индексация с нуля. Ставите на позицию 1, думая, что это первая колонка, и получаете вторую.

Перед удалением колонки методом Колонки.Удалить убедитесь, что код ниже не обращается к ней. Удаление необратимо: данные в колонке пропадают вместе со структурой.

Диагностика: выберите симптом

Чек-лист перед запуском

Проверьте таблицу значений
Выполнено: 0 / 5

Частые вопросы

Можно ли добавить колонку в таблицу значений через интерфейс, без кода?
Нет. ТаблицаЗначений — программный объект. Для визуального редактирования используют табличную часть или табличное поле на форме, где колонки можно задать в конфигураторе.
Как узнать, есть ли в таблице нужная колонка?
Вызовите Таблица.Колонки.Найти("Имя"). Если колонки нет, метод вернёт Неопределено.
Как заменить тип у готовой колонки?
Надёжнее создать новую колонку нужного типа, перенести в неё значения циклом и удалить старую методом Колонки.Удалить.
Как скопировать структуру таблицы без данных?
Метод СкопироватьКолонки() возвращает новую пустую таблицу с теми же колонками и их типами. Затем строки добавляют вручную или копируют выборочно.