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

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

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

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

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

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

Почему тип колонки нельзя изменить напрямую

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

Из этого следует главное правило: любая смена типа — это всегда операция «удалить старое, создать новое». Вопрос только в том, как сохранить данные и порядок колонок. Если таблица пустая, задача тривиальна. Если в ней уже есть строки, потребуется промежуточное хранение значений и их приведение к новому типу.

Способ 1. Удалить колонку и добавить заново

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

ТЗ.Колонки.Удалить("Сумма");

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

Новый КвалификаторыЧисла(15, 2)));

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

Порядок действий при пересоздании колонки
  1. 1
    Найдите колонку и запомните её индекс в коллекции
  2. 2
    Если данные нужны — выгрузите колонку в массив методом ВыгрузитьКолонку()
  3. 3
    Удалите колонку методом Колонки.Удалить()
  4. 4
    Добавьте колонку с тем же именем и новым ОписаниеТипов
  5. 5
    Верните колонку на прежнюю позицию методом Колонки.Сдвинуть()
  6. 6
    Заполните колонку преобразованными значениями и проверьте результат

Способ 2. Сохранить данные через временную колонку

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

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

Новый КвалификаторыЧисла(15, 3)));

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

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

КонецЦикла;

ТЗ.Колонки.Удалить("Количество");

ТЗ.Колонки.КоличествоНов.Имя = "Количество";

При переносе важно помнить об ограничениях функций приведения. Функция Число() вызовет ошибку, если строка содержит нечисловые символы, — пробелы-разделители разрядов, запятую вместо точки, буквы. Перед приведением такие значения стоит очистить функцией СтрЗаменить() или обернуть преобразование в попытку/исключение с записью проблемных строк в журнал.

Способ 3. Пересоздать таблицу через запрос

Элегантная альтернатива циклам — передать таблицу в запрос как параметр и на выходе получить новую таблицу с нужными типами. В языке запросов приведение выполняется функциями ВЫРАЗИТЬ(... КАК Число(15,2)) или ВЫРАЗИТЬ(... КАК Строка(50)). Этот способ особенно удобен, когда менять тип нужно сразу у нескольких колонок.

Запрос = Новый Запрос;

Запрос.УстановитьПараметр("ТЗ", ИсходнаяТаблица);

Запрос.Текст =

"ВЫБРАТЬ

| ВЫРАЗИТЬ(ТЗ.Код КАК Строка(20)) КАК Код,

| ВЫРАЗИТЬ(ТЗ.Сумма КАК Число(15, 2)) КАК Сумма

|ПОМЕСТИТЬ ВТ

|ИЗ &ТЗ КАК ТЗ

|;

|ВЫБРАТЬ * ИЗ ВТ";

НоваяТЗ = Запрос.Выполнить().Выгрузить();

У этого подхода два ограничения. Во-первых, при передаче таблицы в запрос платформа требует, чтобы типы колонок были определены однозначно — колонки с незаполненным или слишком широким составным типом могут вызвать ошибку. Во-вторых, запрос создаёт новую таблицу, поэтому ссылки на старую в других переменных и элементах формы придётся обновить вручную.

Сравнение способов смены типа

Удалить и добавить колонку

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

Временная колонка с переносом

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

Пересоздание через запрос

Удобен при смене типов сразу у нескольких колонок и для больших таблиц. Требует однозначных типов во входной таблице и возвращает новый объект.

Работа с составными типами и ссылками

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

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

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

Как проверить результат и типичные ошибки

После смены типа проверку лучше делать не «на глаз», а программно. Убедитесь, что описание типов новой колонки совпадает с ожидаемым: ТЗ.Колонки.Сумма.ТипЗначения должно содержать нужный тип и квалификаторы. Дополнительно пройдитесь по нескольким строкам и сравните значения с исходными — особенно там, где применялось приведение.

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

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

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

Тип колонки
Норма

ТипЗначения содержит нужный тип и квалификаторы

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

Тип остался прежним или стал неограниченным

Количество строк и итоги
Норма

Число строк и суммы совпадают с исходной таблицей

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

Итоги расходятся — часть значений не преобразовалась

Порядок колонок
Норма

Колонка стоит на прежней позиции

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

Колонка ушла в конец, поломался вывод в форму

Содержимое значений
Норма

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

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

Есть усечённые строки или округлённые числа

Типичные ошибки
01
Попытка присвоить ТипЗначения напрямую — свойство доступно только для чтения, код падает с ошибкой
02
Удаление колонки до сохранения данных — значения теряются безвозвратно
03
Приведение через Число() без очистки строки — ошибка на значениях с пробелами и запятыми
04
Забытый Сдвинуть() после добавления — колонка оказывается в конце и ломает макет вывода
05
Смена типа в таблице, привязанной к элементу формы, без обновления данных формы — на экране остаётся старая структура

Когда смена типа не нужна: альтернативы

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

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

Итог

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

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

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

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

Да, если использовать промежуточную колонку: добавить новую с нужным типом, перенести в неё преобразованные значения в цикле, удалить старую и переименовать новую. Альтернатива без цикла — пересоздать таблицу запросом с функцией ВЫРАЗИТЬ.

Почему возникает ошибка при присваивании ТипЗначения?

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

Как сохранить порядок колонок после пересоздания?

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

Что делать, если Число() выдаёт ошибку преобразования?

Значит, в строке есть символы, которые платформа не может интерпретировать как число: пробелы-разделители разрядов, запятая вместо точки, буквы. Очистите строку через СтрЗаменить() или оберните преобразование в Попытка/Исключение с протоколированием проблемных значений.

Как сменить тип у нескольких колонок сразу?

Удобнее всего через запрос: передать таблицу параметром, применить ВЫРАЗИТЬ к каждой колонке и выгрузить результат в новую таблицу. Это компактнее и быстрее, чем несколько циклов с временными колонками.

Обрезаются ли строки при смене типа на более короткий?

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