К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как типизировать колонки таблицы значений в 1С

Как типизировать колонки таблицы значений в 1С через ОписаниеТипов: составные типы, квалификаторы длины и точности, изменение типов существующих колонок, частые ошибки.

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

Типизация выполняется через объект ОписаниеТипов, который передаётся в метод Колонки.Добавить(). Описание типов определяет не только сам тип (число, строка, дата, ссылка), но и квалификаторы: длину строки, точность числа, состав даты. От корректности этих параметров зависят итоги свёртки, работа индексов и отборов, а также сериализация таблицы.

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

Как создать типизированную колонку через ОписаниеТипов

Базовый приём выглядит так: сначала создаётся объект ОписаниеТипов с указанием типа в виде строки, затем он передаётся вторым параметром в Колонки.Добавить(). Первый параметр — имя колонки, третий (необязательный) — представление для отображения.

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

ОписаниеСтроки = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50));

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

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

ОписаниеСсылки = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");

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

ТЗ.Колонки.Добавить("Сумма", ОписаниеЧисла);

ТЗ.Колонки.Добавить("Период", ОписаниеДаты);

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

Обратите внимание на позиции параметров конструктора ОписаниеТипов: вторым идут квалификаторы числа, третьим — квалификаторы строки, четвёртым — квалификаторы даты. Пропущенные позиции заполняются пустыми значениями, как в примере с датой. Ошибка в порядке параметров — частая причина «молчаливо» неверной типизации.

Если тип не указать вовсе (ТЗ.Колонки.Добавить("Поле")), колонка получит произвольный состав типов. Такая колонка примет любое значение, но сортировка и сравнение смешанных значений (число против строки) дают неочевидный порядок, а свёртка по нетипизированной колонке может завершиться ошибкой при попытке сложить несовместимые типы.

Квалификаторы: длина строки, точность числа, состав даты

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

КвалификаторКонструкторНа что влияет
КвалификаторыСтрокиНовый КвалификаторыСтроки(Длина, ДопустимаяДлина)Ограничение длины, сравнение строк, выгрузка в СУБД
КвалификаторыЧислаНовый КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти, Знак)Точность хранения, округление при присваивании
КвалификаторыДатыНовый КвалификаторыДаты(ЧастиДаты)Отбрасывание времени или даты при записи значения
КвалификаторыДвоичныхДанныхНовый КвалификаторыДвоичныхДанных(Длина)Ограничение размера двоичных данных

Практическое следствие: если колонка «Сумма» объявлена как Число(10,2), а вы присваиваете значение с тремя знаками после запятой, лишний разряд будет округлён при записи в ячейку. Для денежных расчётов с промежуточными вычислениями разумно задавать запас точности, например 15 разрядов и 2–3 знака дробной части, чтобы не терять копейки на промежуточных итогах.

Составные типы и типы-ссылки

Колонка может хранить значения нескольких типов — например, контрагента как ссылку на справочник «Контрагенты» либо «ФизическиеЛица». Для этого в конструктор ОписаниеТипов передаётся массив типов или строка с перечислением типов через запятую.

МассивТипов = Новый Массив;

МассивТипов.Добавить(Тип("СправочникСсылка.Контрагенты"));

МассивТипов.Добавить(Тип("СправочникСсылка.ФизическиеЛица"));

ОписаниеСоставного = Новый ОписаниеТипов(МассивТипов);

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

// Эквивалент строкой:

ОписаниеСтрокой = Новый ОписаниеТипов("СправочникСсылка.Контрагенты,СправочникСсылка.ФизическиеЛица");

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

Для добавления типа к уже существующему описанию используйте методы ОписаниеТипов.СодержитТип() для проверки и конструктор с объединением: новый объект создаётся на базе старого с расширенным массивом типов. Сам объект описания типов после создания неизменяем по составу — модифицировать можно только создавая новый экземпляр.

Как изменить тип колонки в уже заполненной таблице

Свойство ТипЗначения колонки доступно только для чтения — присвоить ему новое описание типов нельзя. Поэтому применяется один из двух приёмов.

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

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

// Исходная таблица ТЗ с нетипизированной колонкой "Количество"

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

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

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

Для Каждого СтрокаТЗ Из ТЗ Цикл

НоваяСтрока = НоваяТЗ.Добавить();

НоваяСтрока.Номенклатура = СтрокаТЗ.Номенклатура;

НоваяСтрока.Количество = Число(СтрокаТЗ.Количество);

КонецЦикла;

Порядок действий при смене типа колонки
  1. 1
    Определите, какие колонки требуют новой типизации, и подготовьте объекты ОписаниеТипов
  2. 2
    Создайте новую таблицу значений с корректной структурой колонок
  3. 3
    Перенесите данные построчно с явным приведением значений (Число(), Строка(), Дата())
  4. 4
    Проверьте на контрольных строках, что значения не потеряли точность и не стали пустыми
  5. 5
    Замените ссылку на старую таблицу новой и удалите временные переменные

При переносе обязательно выполняйте явное приведение значений. Если в старой колонке число хранилось как строка («1 234,56» с пробелом-разделителем), простое присваивание в числовую колонку даст ошибку преобразования или ноль — в зависимости от содержимого. Функции Число(), Строка(), Дата() и обработка исключений через Попытка...Исключение страхуют от потери данных.

Типизация колонок результата запроса и внешних источников

Когда таблица значений получается методом Запрос.Выполнить().Выгрузить(), колонки уже типизированы — платформа берёт типы из метаданных полей запроса. Однако вычисляемые поля (выражения, функции, ВЫБОР КОГДА) могут получить составной или неточный тип. Если дальше таблица используется для свёртки или помещается во временную таблицу, типы стоит проверить и при необходимости уточнить через ВЫРАЗИТЬ(... КАК Число(15,2)) прямо в тексте запроса.

При загрузке данных из файлов (CSV, Excel через табличный документ) все значения изначально строковые. Типичный сценарий: сначала данные читаются в «сырую» таблицу со строковыми колонками, затем строится типизированная таблица с преобразованием значений. Пытаться типизировать колонки «на лету» в процессе чтения файла — распространённая ошибка: одна некорректная строка в файле прервёт всю загрузку.

Маршрут решения

Как выбрать подход

Таблица создаётся в коде с нуляТипизируйте колонки сразу через ОписаниеТипов в Колонки.Добавить()
Таблица получена из запроса и типы устраиваютНичего не меняйте — типы уже заданы метаданными
Вычисляемые поля запроса дали неточный типУточните тип функцией ВЫРАЗИТЬ в тексте запроса
Данные пришли из файла или внешнего источника строкамиСоздайте вторую типизированную таблицу и перенесите данные с приведением типов
Нужно изменить тип в заполненной таблицеПересоздайте таблицу: прямое изменение типа колонки невозможно

Проверка результата и диагностика типов

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

Колонка = ТЗ.Колонки.Найти("Сумма");

Если НЕ Колонка.ТипЗначения.СодержитТип(Тип("Число")) Тогда

ВызватьИсключение "Колонка ""Сумма"" имеет неверный тип";

КонецЕсли;

Косвенные признаки корректной типизации: ТЗ.Свернуть("Товар", "Сумма,Количество") отрабатывает без ошибок и даёт ожидаемые итоги; сортировка по числовой колонке идёт как числовая, а не строковая («2» раньше «10» — признак строкового типа); отбор структурой Новый Структура("Товар", Ссылка) находит строки.

Контрольные точки

Как проверить результат

Сортировка числовой колонки
Норма

Значения упорядочены по величине: 2, 10, 100

Тревожный признак

Порядок строковый: 10, 100, 2 — колонка строковая

Свёртка по суммовым колонкам
Норма

Свернуть() выполняется, итоги сходятся с контрольными

Тревожный признак

Ошибка несоответствия типов или нулевые итоги

Состав типа колонки
Норма

СодержитТип() возвращает Истина для ожидаемого типа

Тревожный признак

Тип произвольный или не содержит нужного

Значения после переноса
Норма

Дробная часть и даты сохранились без обрезки

Тревожный признак

Числа округлены, даты потеряли время — неверные квалификаторы

Типичные ошибки и ограничения

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

Вторая группа ошибок связана с ожиданием автоматического приведения типов. Платформа не преобразует строку «1200» в число при присваивании в числовую колонку в некоторых контекстах, а при свёртке смешанных значений выбрасывает исключение. Всегда приводите значения явно.

Типичные ошибки
01
Перепутан порядок квалификаторов в конструкторе ОписаниеТипов — ограничения длины и точности не применяются
02
Попытка присвоить новый ОписаниеТипов свойству ТипЗначения существующей колонки — свойство доступно только для чтения
03
Создание колонок без типа «на потом» — сортировка и свёртка ведут себя непредсказуемо
04
Числовая колонка с недостаточной дробной частью — копейки теряются при присваивании значений
05
Перенос данных из файла без явного приведения типов — одна «битая» строка обрывает всю загрузку
06
Строка неограниченной длины в колонках соединения временных таблиц — ошибки и падение производительности запроса

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

Итог

Что важно запомнить

Типизация задаётся один раз — при добавлении колонки через ОписаниеТипов с квалификаторами. Изменить тип существующей колонки нельзя, только пересоздать таблицу с переносом данных и явным приведением значений. Проверяйте результат через СодержитТип(), сортировку и свёртку — они сразу выявляют неверную типизацию.

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

Можно ли изменить тип колонки без потери данных?

Напрямую — нет, свойство ТипЗначения доступно только для чтения. Безопасный путь: создать новую таблицу с нужной типизацией и перенести строки циклом, приводя значения функциями Число(), Строка(), Дата(). Данные сохранятся, если приведение выполнимо для каждого значения.

Чем отличается строка «Число» от массива типов в ОписаниеТипов?

Строковое перечисление («Число,Строка») и массив с элементами Тип("Число") дают одинаковый результат. Массив удобнее, когда состав типов формируется динамически; строка компактнее для фиксированного набора. Для ссылочных типов в строке указывается полное имя: «СправочникСсылка.Номенклатура».

Почему сортировка числовой колонки работает как строковая?

Значит, колонка на самом деле строковая или имеет составной тип, а значения записаны как строки. Проверьте Колонка.ТипЗначения и тип фактических значений через ТипЗнч(). Исправление — пересоздание колонки с типом Число и перенос значений через Число().

Как задать дату без времени в колонке?

Передайте квалификатор даты: Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата)). Тогда при присваивании значения со временем время будет отброшено. Учтите: уже записанные до смены подхода значения сами не очистятся.

Нужно ли типизировать колонки таблицы, полученной из запроса?

Обычно нет: Выгрузить() переносит типы из метаданных полей запроса. Исключение — вычисляемые поля и выражения ВЫБОР, где тип может получиться составным или с избыточной точностью. В таких случаях уточняйте тип оператором ВЫРАЗИТЬ прямо в тексте запроса.

Какой тип выбрать для колонки с комментариями произвольной длины?

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