Добавление колонки в таблицу значений 1С: код и примеры

· 9 мин

Содержание

Колонку в таблицу значений добавляют методом Колонки.Добавить(): он принимает имя, тип, заголовок и ширину, а новая колонка встаёт в конец. Если нужно поставить её в середину, берите Колонки.Вставить() с индексом позиции. Всё остальное в этой теме — нюансы: что будет с уже заполненными строками, как задать тип и как показать колонку на форме.

Ниже — рабочие приёмы для платформы 8.3: от простого добавления до копирования структуры из запроса и динамических колонок на управляемой форме. Примеры на встроенном языке можно копировать в обработку или модуль.

Из чего состоит таблица значений

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

У каждой колонки есть четыре свойства:

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

Заголовок и ширина нужны только для отображения. В расчётах участвуют имя и тип.

Создаётся таблица так:

ТЗ = Новый ТаблицаЗначений;

После этой строки таблица пустая: ни колонок, ни строк.

Как добавить колонку методом Добавить

Синтаксис: Колонки.Добавить(<Имя>, <ТипЗначения>, <Заголовок>, <Ширина>). Обязателен только первый параметр. Метод возвращает объект колонки, и им можно сразу воспользоваться.

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

Первая колонка создана без типа: в неё можно положить что угодно — ссылку, число, строку. Вторая принимает только числа и покажет заголовок «Кол-во».

Тип значения: задавать или нет

Колонка без типа гибкая, но платит за это. Платформа не проверяет, что вы положили, и ошибка вылезет позже, например при сложении строки с числом. С типом платформа приводит значение к нужному виду сама.

ВариантКогда подходитРиск
Без типаВременная таблица в 10–20 строк, значения разнородныеОшибки типов всплывают далеко от места записи
Простой тип (Число, Дата)Колонка с однотипными даннымиМало: значение приводится автоматически
Тип с квалификаторамиДеньги, количество, строки заданной длиныНужно заранее знать разрядность
Ссылочный типКолонка хранит элементы справочникаТип должен существовать в конфигурации

Для чисел с дробной частью задайте разрядность явно:

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

15 — общая длина числа, 2 — знаков после запятой. Для строки есть Новый КвалификаторыСтроки(100), для даты — Новый КвалификаторыДаты(ЧастиДаты.Дата).

Ссылочный тип указывают так: Новый ОписаниеТипов("СправочникСсылка.Номенклатура"). Колонка с таким типом принимает только номенклатуру, а при пустом значении хранит пустую ссылку.

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

Как вставить колонку в середину таблицы

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

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

// Новая колонка станет второй: индекс 1
ТЗ.Колонки.Вставить(1, "Количество", Новый ОписаниеТипов("Число"), "Кол-во");

Порядок получится такой: Номенклатура, Количество, Сумма. Остальные параметры те же, что у Добавить.

Индекс текущей колонки узнаете через ТЗ.Колонки.Индекс(Колонка). Колонку по имени ищет ТЗ.Колонки.Найти("Сумма"): если такой нет, вернётся Неопределено.

Проверка перед добавлением

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

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

Что произойдёт с уже заполненными строками

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

  • Колонка без типа: в существующих строках значение Неопределено.
  • Колонка с типом: значение по умолчанию для этого типа — 0 для числа, пустая строка, пустая дата, пустая ссылка.

Если колонка нужна для расчёта, заполните её сразу после добавления:

ТЗ.Колонки.Добавить("Итого", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));

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

Есть короткий путь: ТЗ.ЗаполнитьЗначения(0, "Итого") проставит одно значение во всех строках колонки. Для формулы он не годится, только для константы.

Если у колонки не задан тип, а в расчёте участвует Неопределено, получите ошибку. Либо задавайте числовой тип, либо заполняйте колонку сразу после добавления.

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

Писать десяток колонок руками долго. Есть способы получить готовую структуру.

Из другой таблицы значений

СкопироватьКолонки() создаёт пустую таблицу с теми же колонками, типами, заголовками и ширинами:

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

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

Из результата запроса

Запрос возвращает структуру сам: выгрузка в таблицу значений создаёт колонки по именам и типам полей выборки.

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |    Номенклатура.Наименование КАК Наименование,
    |    Номенклатура.Артикул КАК Артикул
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура";
ТЗ = Запрос.Выполнить().Выгрузить();

Колонки Наименование и Артикул появятся автоматически. Когда понадобится ещё одна, добавьте её уже после выгрузки обычным Колонки.Добавить.

Хитрость: если нужна служебная колонка вроде «Отмечено», можно прямо в тексте запроса написать ЛОЖЬ КАК Отмечено. Колонка получит булев тип без лишнего кода.

Через конструктор в конфигураторе

В конфигураторе на форме запроса есть конструктор запроса, а в модуле — конструктор запроса с обработкой результата. Он собирает текст запроса и сразу пишет код выгрузки. Для таблицы значений как таковой отдельного визуального конструктора колонок нет: структуру задают кодом или берут из запроса.

Колонки таблицы на управляемой форме

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

  1. Добавляете колонку в реквизит формы через ИзменитьРеквизиты.
  2. Создаёте элемент формы (поле) через Элементы.Добавить.
  3. Связываете поле с данными через ПутьКДанным.
&НаСервере
Процедура ДобавитьКолонкуНаФорму()

    НовыеРеквизиты = Новый Массив;
    НовыеРеквизиты.Добавить(Новый РеквизитФормы(
        "Сумма", Новый ОписаниеТипов("Число"), "Таблица", "Сумма"));
    ИзменитьРеквизиты(НовыеРеквизиты);

    Поле = Элементы.Добавить("ТаблицаСумма", Тип("ПолеФормы"), Элементы.Таблица);
    Поле.Вид = ВидПоляФормы.ПолеВвода;
    Поле.ПутьКДанным = "Таблица.Сумма";

КонецПроцедуры

Здесь Таблица — имя реквизита типа «Таблица значений», он же имя элемента на форме. Подставьте свои названия.

Три нюанса, на которых чаще всего спотыкаются:

  • ИзменитьРеквизиты выполняется только на сервере;
  • вызов пересоздаёт реквизиты формы, поэтому делайте его один раз за набор колонок, а не в цикле по одной;
  • динамические колонки не сохраняются: при следующем открытии формы код надо выполнить снова.

Если обработчик вызывается повторно, сначала проверьте Элементы.Найти("ТаблицаСумма"). Без этого второй вызов упадёт на дубле имени элемента.

Что делать с колонкой после добавления

Пустая колонка бесполезна, пока в неё не попали данные. Есть три удобных способа наполнить её, кроме цикла Для Каждого.

Загрузка из массива

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

Цены = Новый Массив;
Цены.Добавить(120);
Цены.Добавить(85.5);
Цены.Добавить(300);

ТЗ.ЗагрузитьКолонку(Цены, "Цена");

Если элементов в массиве меньше, чем строк, остальные строки не изменятся. Если больше, лишние значения пропускаются. Метод удобен, когда данные уже лежат в массиве после чтения файла или ответа сервиса.

Одно значение на всю колонку

Для константы или флага по умолчанию подойдёт ЗаполнитьЗначения:

ТЗ.ЗаполнитьЗначения(Истина, "Выбран");

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

Расчёт по строкам

Если значение колонки зависит от других колонок, считайте в цикле. Пример для скидки в 10 процентов:

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

Для Каждого Строка Из ТЗ Цикл
    Строка.СуммаСоСкидкой = Окр(Строка.Сумма * 0.9, 2);
КонецЦикла;

При сумме 1 000 в строке окажется 900, при 1 234,56 — 1 111,10 (произведение 1 111,104 округляется до сотых).

Сортировка, свёртка и порядок колонок

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

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

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

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

Типичные ошибки и производительность

Часть проблем повторяется из раза в раз. Вот ошибки по убыванию частоты.

Колонку добавили, а обращение к ней падает. Обычно это опечатка в имени или добавление в другую таблицу. Имя в обращении Строка.Сумма должно совпадать с именем колонки до буквы. Для отладки выведите список: Для Каждого Колонка Из ТЗ.Колонки Цикл Сообщить(Колонка.Имя); КонецЦикла;.

Колонка есть, значения нет. Колонку добавили после заполнения строк и забыли про расчёт, см. выше про Неопределено и значения по умолчанию.

Присвоили значение не того типа. В числовую колонку записали строку «abc»: платформа приведёт её к 0 без сообщения. Работа с типом экономит отладку, но проверять входные данные всё равно придётся.

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

Для больших объёмов работают три правила:

  • задавайте колонки один раз, до заполнения строк;
  • по возможности берите структуру из запроса, а не собирайте в цикле;
  • если нужна только часть колонок, выбирайте их в запросе, лишние тянут память.

Когда колонка больше не нужна, удалите её: ТЗ.Колонки.Удалить("Комментарий"). Принимает имя или объект колонки.

Перед добавлением колонки
Выполнено: 0 / 5

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

Чем Вставить отличается от Добавить?
Добавить ставит колонку в конец, Вставить — на позицию по индексу. Остальные параметры одинаковые.
Можно ли переименовать колонку?
Да, свойство Имя колонки доступно для записи: ТЗ.Колонки.Найти("Сумма").Имя = "Итого". Старые обращения в коде по прежнему имени перестанут работать.
Можно ли изменить тип колонки, когда в таблице уже есть данные?
Свойство ТипЗначения только для чтения. Создайте новую колонку нужного типа, перенесите значения в цикле и удалите старую.
Как узнать количество колонок?
Через ТЗ.Колонки.Количество(). К колонке по порядковому номеру обращаются как ТЗ.Колонки[0].
Видно ли добавленную колонку пользователю автоматически?
В обычном табличном документе и на форме с автоматически созданными колонками да. На управляемой форме с таблицей значений нужно создать поле вручную, как показано выше.