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