Как задать типы колонок Таблицы значений в коде 1С
Содержание
Типизировать колонку Таблицы значений можно двумя путями: передать описание типов третьим аргументом в Колонки.Добавить() или получить готовую структуру из другой таблицы методами СкопироватьКолонки() и ЗагрузитьКолонки(). Колонка без типа принимает любые значения, а колонка с типом приводит присвоенное к допустимому типу и показывает правильный редактор в форме.
Пример ниже создаёт таблицу с тремя типизированными колонками. Дальше разберём, как собрать описание типов, зачем нужны квалификаторы и где типизация экономит время при отладке.
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
Таблица.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100)));
Что даёт типизация колонок и когда без неё не обойтись
Нетипизированная колонка хранит значение любого типа. Для быстрого скрипта этого хватает. Для рабочего кода — нет.
Типизация нужна в таких случаях:
- 📋 Таблица выводится на форму. Поле ввода подбирает редактор по типу: для даты — календарь, для ссылки — выбор из справочника, для числа — выравнивание вправо. Без типа этого не будет.
- 🔍 Таблица уходит в запрос как параметр или внешняя таблица. Для временной таблицы из Таблицы значений типы колонок должны быть заданы, иначе в запросе поле останется без определённого типа и соединения по нему будут неудобны.
- 🛡️ Нужна защита от мусора. Если в числовую колонку попытаются записать строку, значение приведётся к типу колонки, а не сохранится как есть.
- 📊 Сортировка и свёртка. Сортировать колонку, где вперемешку числа, даты и строки, неудобно: порядок определяется типами, а не логикой пользователя.
Если таблица живёт десять строк кода и исчезает, типизацию можно пропустить. Если она попадает на форму, в запрос или в хранилище настроек — задавайте типы сразу.
Колонки.Добавить: четыре аргумента и их смысл
Метод Колонки.Добавить() принимает до четырёх параметров:
| Параметр | Что это | Обязателен |
|---|---|---|
| Имя | Идентификатор колонки, по нему обращаются из кода | да |
| ТипЗначения | Объект ОписаниеТипов | нет |
| Заголовок | Подпись для пользователя | нет |
| Ширина | Ширина колонки при отображении | нет |
Если пропустить второй параметр, колонка получится без типа. Если пропустить заголовок, в интерфейсе покажется имя.
Имя колонки подчиняется правилам идентификаторов: без пробелов и спецсимволов, не начинается с цифры. Для подписи с пробелами используйте заголовок:
Таблица.Колонки.Добавить("СуммаДокумента", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)), "Сумма документа", 14);
Метод возвращает объект колонки. Его можно сохранить в переменную и менять свойства дальше, но тип у уже созданной колонки изменить нельзя. Если нужен другой тип, колонку удаляют и создают заново — данные в ней при этом теряются.
ОписаниеТипов: простые, ссылочные и составные типы
Конструктор Новый ОписаниеТипов(...) принимает строку с именами типов. Разделитель между типами — запятая.
Простой тип:
Новый ОписаниеТипов("Дата")
Новый ОписаниеТипов("Булево")
Ссылочный тип. Пишете тип так, как он называется в метаданных:
Новый ОписаниеТипов("СправочникСсылка.Контрагенты")
Новый ОписаниеТипов("ДокументСсылка.РеализацияТоваровУслуг")
Составной тип. Перечислите типы через запятую:
Новый ОписаниеТипов("СправочникСсылка.Контрагенты, СправочникСсылка.Организации")
Новый ОписаниеТипов("Число, Строка")
Составной тип удобен там, где колонка хранит значение из нескольких справочников, например «Объект учёта». Но если типов больше трёх-четырёх, подумайте, не проще ли разделить колонку.
Имя типа проверяется при выполнении. Опечатка в СправочникСсылка.Номенклатуры даст исключение именно в этот момент, а не при открытии модуля. Проверяйте код запуском.
Описание типов можно собирать из уже готовых: конструктор принимает в первом параметре и массив типов. Это полезно, когда типы приходят из настроек, а не пишутся в коде.
Квалификаторы числа, строки и даты
Тип «Число» без квалификатора имеет разрядность по умолчанию. Для денег и количества задавайте её явно: так проще понять, что колонка хранит.
Число. КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти, ДопустимыйЗнак):
// 15 знаков всего, 2 после запятой, только неотрицательные
Новый КвалификаторыЧисла(15, 2, ДопустимыйЗнак.Неотрицательный)
Строка. КвалификаторыСтроки(Длина, ДопустимаяДлина). Длина 0 означает неограниченную строку:
Новый КвалификаторыСтроки(50) // до 50 символов
Новый КвалификаторыСтроки(0) // без ограничения
Дата. КвалификаторыДаты(СоставДаты). Значения: ЧастиДаты.Дата, ЧастиДаты.Время, ЧастиДаты.ДатаВремя:
Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата))
Квалификаторы передаются в конструктор по порядку: числа, строки, даты. Лишние позиции пропускают запятыми. Поэтому для строки видим две запятых:
Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100))
Что делает квалификатор на деле
Квалификатор не запрещает присвоение, а приводит значение. Строка длиннее лимита обрежется, число с лишними знаками округлится. Исключения не будет, поэтому при потере данных ошибку можно заметить поздно.
| Случай | Результат |
|---|---|
| В числовую колонку записали строку, которую нельзя превратить в число | Значение станет 0 |
| В колонку «Дата» записали число | Значение станет пустой датой |
| Строка длиннее квалификатора | Обрежется до длины |
| Число с лишними знаками после запятой | Округлится |
Если вам нужно, чтобы некорректные данные приводили к ошибке, проверяйте значение до записи в колонку. Типизация защищает структуру, а не заменяет валидацию.
Типизация через СкопироватьКолонки и ЗагрузитьКолонки
Когда структура уже где-то описана, пересобирать её вручную не нужно.
Копирование структуры из другой таблицы
СкопироватьКолонки() создаёт пустую таблицу с теми же колонками и типами:
НоваяТаблица = ИсходнаяТаблица.СкопироватьКолонки();
Строки не копируются. Это нужный вариант для «такой же таблицы, но пустой», например при сборе промежуточного результата.
Если нужны и строки, используйте Скопировать(). А если часть колонок не нужна — передайте второй параметр со списком имён.
Загрузка колонок из источника
ЗагрузитьКолонки() добавляет колонки в существующую таблицу. Если источник — другая Таблица значений, переносятся имена и типы. Если источник — массив имён, колонки создаются без типа.
ПустаяТаблица = Новый ТаблицаЗначений;
ПустаяТаблица.ЗагрузитьКолонки(ИсходнаяТаблица);
Тут и подвох: загрузка из массива даёт нетипизированные колонки. После загрузки тип можно проверить так:
Для Каждого Колонка Из ПустаяТаблица.Колонки Цикл
Если Колонка.ТипЗначения.Типы().Количество() = 0 Тогда
// колонка без типа — задайте тип заново через пересоздание
КонецЕсли;
КонецЦикла;
Таблица из результата запроса
Самый частый способ получить типизированную таблицу — выгрузить результат запроса:
Таблица = Запрос.Выполнить().Выгрузить();
Колонки получат типы из полей запроса. Тип поля зависит от запроса: если в нём стоит ВЫРАЗИТЬ(... КАК Число(15, 2)) или ВЫРАЗИТЬ(... КАК Строка(50)), колонка получит именно эти квалификаторы. Без выражения тип составного поля может быть составным.
Ссылочные типы и значения неопределённого типа
Колонка со ссылочным типом принимает ссылки на конкретный справочник или документ, а ещё пустую ссылку. Значение Неопределено в такую колонку не попадает: при присвоении оно приводится к пустой ссылке.
Что проверять при работе со ссылками:
- 🔗 Совпадение типа. Если в колонку «СправочникСсылка.Контрагенты» присвоить ссылку на номенклатуру, значение станет пустой ссылкой контрагента. Данные потеряются без ошибки.
- 🔗 Пустая ссылка и «ничего». Пустая ссылка — это значение. Проверка
Не ЗначениеЗаполнено(Значение)ловит и её, иНеопределено. - 🔗 Вложенные свойства. Для типизированной ссылочной колонки в обработке строки можно сразу писать
Строка.Номенклатура.Артикул. Для составного типа предварительно проверьте тип значения черезТипЗнч().
Пример проверки типа в составной колонке:
Для Каждого Строка Из Таблица Цикл
Если ТипЗнч(Строка.Объект) = Тип("СправочникСсылка.Контрагенты") Тогда
// работаем с контрагентом
КонецЕсли;
КонецЦикла;
Заполняя такую таблицу из данных, лучше сразу приводить значение: ОписаниеТипов.ПривестиЗначение(Значение). Метод возвращает значение допустимого типа или пустое значение этого типа.
Описание = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
Сумма = Описание.ПривестиЗначение(ВведённоеЗначение);
Приведение молча заменяет непреобразуемое значение нулём или пустым значением. Если ноль может быть реальной суммой, отличить его от ошибки приведения вы не сможете. Сравните входное значение с результатом, когда это важно.
Что делать, если типы не подошли: ошибки и отладка
Проблемы с типами проявляются по-разному, и симптом не всегда указывает на причину.
- ❌ Колонка «пустая» после заполнения. Скорее всего, присвоили значение несовместимого типа, и оно привелось к пустому. Проверьте тип в источнике через
ТипЗнч(). - ❌ Сумма округлилась до целого. В квалификаторе числа дробная часть равна нулю или задано мало знаков. Проверьте второй параметр
КвалификаторыЧисла. - ❌ Строка обрезана. Длина в
КвалификаторыСтрокименьше данных. Для комментариев и длинных текстов ставьте0. - ❌ В запросе не видно типа поля. Колонки таблицы созданы без
ОписаниеТипов. Пересоздайте их с типами. - ❌ Тип не меняется. У существующей колонки тип менять нельзя: создайте новую колонку, перенесите данные циклом и удалите старую.
Чтобы быстро увидеть, какие типы заданы в таблице, выведите их в цикле:
Для Каждого Колонка Из Таблица.Колонки Цикл
Сообщить(Колонка.Имя + ": " + Колонка.ТипЗначения.Типы().Количество() + " тип(ов)");
КонецЦикла;
Для первичной отладки хватает точки останова и окна просмотра переменных: раскройте Таблица.Колонки и посмотрите свойство ТипЗначения у каждой колонки.
Полный пример: типизированная таблица, заполнение и свёртка
Соберём таблицу остатков с проверкой результата. Задача: получить итог по каждой номенклатуре, не потеряв типы.
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
Таблица.Колонки.Добавить("Склад", Новый ОписаниеТипов("СправочникСсылка.Склады"));
Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
Строка = Таблица.Добавить();
Строка.Номенклатура = ВыбраннаяНоменклатура;
Строка.Склад = ВыбранныйСклад;
Строка.Количество = 12.5;
Таблица.Свернуть("Номенклатура", "Количество");
После Свернуть() в таблице остаются только перечисленные колонки: группировочная «Номенклатура» и суммируемая «Количество». Колонка «Склад» исчезнет вместе с данными. Типы оставшихся колонок сохраняются, поэтому результат можно сразу выводить на форму или передавать в запрос.
Порядок работы, который сэкономит время:
- Опишите структуру в одном месте, в отдельной функции, которая возвращает пустую типизированную таблицу.
- Заполняйте строки через
Добавить(), присваивая значения по именам колонок. - Перед свёрткой убедитесь, что числовая колонка действительно числовая: суммировать можно только числа.
- После обработки проверьте результат на пустые значения в обязательных колонках.
Оптимизация: когда типизация ускоряет код, а когда нет
Типизация сама по себе скорость не меняет. Выигрыш — в предсказуемости: платформа не гадает с типом при сортировке, свёртке и выгрузке.
Несколько практических приёмов:
- ⚡ Создавайте структуру один раз. Если одинаковые таблицы строятся в цикле, соберите
ОписаниеТиповзаранее и переиспользуйте объект, а не конструируйте на каждой итерации. - ⚡ Копируйте структуру, а не пересобирайте.
СкопироватьКолонки()быстрее и безопаснее, чем набор вызововКолонки.Добавить()на 20 колонок. - ⚡ Не используйте широкие составные типы без нужды. Чем больше допустимых типов, тем сложнее разбор значений в коде.
- ⚡ Индексы. Если таблица большая и по ней часто ищут через
НайтиилиНайтиСтроки, задайте индексы колонок — это отдельная настройка, не зависящая от типа.
Для небольших таблиц до нескольких сотен строк разница на практике незаметна. На десятках тысяч строк важнее избежать лишних преобразований и повторных обходов.
Частые вопросы
Можно ли изменить тип колонки после создания?
Что будет, если не указывать тип?
Как узнать тип колонки?
Колонка.ТипЗначения. Список типов вернёт метод Типы(), а проверить конкретный тип можно через СодержитТип(Тип("Число")).Как задать несколько типов сразу?
Новый ОписаниеТипов("Число, Строка"). Квалификаторы передаются отдельными параметрами и действуют на соответствующий тип.Что лучше: ЗагрузитьКолонки или СкопироватьКолонки?
СкопироватьКолонки(). Для добавления колонок в уже созданную таблицу — ЗагрузитьКолонки(). Из массива имён оба варианта не дадут типов, поэтому типы указывайте вручную.Нужна ли типизация для таблицы из запроса?
Выгрузить() проставляет типы по полям запроса. Контролируйте их через ВЫРАЗИТЬ, когда важна точность числа или длина строки.