Разработка и Конфигурация · 12 мин
Как изменить тип колонки таблицы значений в 1С 8
Как изменить тип колонки таблицы значений в 1С 8: способы для обычных и управляемых форм, работа с ОписаниеТипов, пересоздание колонок, типичные ошибки и проверка результата.
Таблица значений в 1С 8 — один из самых используемых объектов встроенного языка: в ней собирают данные для отчётов, обработок, загрузки из файлов и промежуточных расчётов. Тип колонки задаётся при создании таблицы через метод Колонки.Добавить(), но в реальной работе часто возникает ситуация, когда тип уже созданной колонки нужно изменить — например, строка оказалась короче нужного, или вместо строки требуется число для сортировки и итогов.
Главное, что нужно понимать сразу: у объекта «ТаблицаЗначений» нет метода «изменить тип колонки». Коллекция колонок позволяет добавлять, удалять, перемещать колонки и менять их свойства вроде заголовка и ширины, но свойство ТипЗначения у существующей колонки доступно только для чтения. Поэтому изменение типа всегда выполняется обходными путями: пересозданием колонки, пересозданием всей таблицы или преобразованием значений при заполнении.
Ниже разобраны рабочие способы для серверного кода и управляемых форм, ограничения каждого подхода, а также ошибки, которые чаще всего приводят к потере данных или падению обработки.
Почему тип колонки нельзя изменить напрямую
Колонка таблицы значений описывается объектом КолонкаТаблицыЗначений, у которого есть свойства Имя, Заголовок, Ширина и ТипЗначения. Первые три можно менять в любой момент, а вот ТипЗначения платформа фиксирует при добавлении колонки. Попытка присвоить этому свойству новое значение вызовет ошибку выполнения.
Такое ограничение связано с внутренним устройством таблицы: значения строк хранятся с учётом описания типов колонки, и смена типа «на лету» потребовала бы перестроения всех данных. Платформа перекладывает эту задачу на разработчика, чтобы преобразование было явным и контролируемым.
Из этого следует практическое правило: если таблица ещё не заполнена данными — просто удалите колонку и добавьте заново с нужным типом. Если данные уже есть — сначала сохраните их, потом пересоздавайте колонку и переносите значения с преобразованием.
Способ 1: удалить колонку и добавить заново
Самый простой вариант, когда таблица пустая или данные колонки не нужны. Сначала удаляете старую колонку, затем добавляете новую с тем же именем и другим описанием типов:
ТЗ.Колонки.Удалить("Сумма");
ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число",
Новый КвалификаторыЧисла(15, 2)));
Обратите внимание на позицию колонки: метод Добавить() вставляет колонку в конец. Если порядок колонок важен (например, таблица выводится на форму или в макет), используйте метод Вставить() с указанием индекса или запомните индекс до удаления:
ИндексКолонки = ТЗ.Колонки.Индекс(ТЗ.Колонки.Найти("Сумма"));
ТЗ.Колонки.Удалить("Сумма");
ТЗ.Колонки.Вставить(ИндексКолонки, "Сумма",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
Если в таблице уже есть строки, удаление колонки безвозвратно уничтожит её значения во всех строках. Перед удалением сохраните данные во временную структуру, если они понадобятся.
Способ 2: пересоздать колонку с переносом значений
Когда таблица заполнена, типичный приём — создать новую колонку с нужным типом, перенести в неё преобразованные значения, а старую удалить. Это безопаснее, чем удалять колонку сразу: при ошибке преобразования исходные данные останутся нетронутыми.
- 1Добавьте временную колонку с новым типом, например СуммаНов
- 2В цикле по строкам заполните её преобразованными значениями из старой колонки
- 3Проверьте, что перенос прошёл без потерь (сравните итоги или количество заполненных значений)
- 4Удалите старую колонку и переименуйте новую при необходимости
- 5Проверьте позицию колонки и порядок сортировки, если они использовались
Пример переноса строковых значений в числовую колонку:
ТЗ.Колонки.Добавить("СуммаНов", Новый ОписаниеТипов("Число",
Новый КвалификаторыЧисла(15, 2)));
Для Каждого СтрокаТЗ Из ТЗ Цикл
Попытка
СтрокаТЗ.СуммаНов = Число(СтрЗаменить(СтрокаТЗ.Сумма, " ", ""));
Исключение
СтрокаТЗ.СуммаНов = 0;
КонецПопытки;
КонецЦикла;
ТЗ.Колонки.Удалить("Сумма");
ТЗ.Колонки.СуммаНов.Имя = "Сумма";
Ключевой момент — явное преобразование значений. Присвоение строки числовой колонке не вызовет автоматического приведения: платформа запишет Неопределено или значение по умолчанию, если тип не совместим. Поэтому используйте функции Число(), Дата(), Строка() и обработку исключений для «грязных» данных.
Способ 3: пересоздать таблицу целиком
Если менять нужно типы нескольких колонок сразу, часто проще построить новую таблицу с правильной структурой и скопировать в неё данные. Это особенно удобно, когда типы меняются у трёх и более колонок — код остаётся линейным и читаемым.
НоваяТЗ = Новый ТаблицаЗначений;
НоваяТЗ.Колонки.Добавить("Номенклатура",
Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
НоваяТЗ.Колонки.Добавить("Количество",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
Для Каждого СтрокаТЗ Из СтараяТЗ Цикл
НоваяСтрока = НоваяТЗ.Добавить();
НоваяСтрока.Номенклатура = СтрокаТЗ.Номенклатура;
НоваяСтрока.Количество = Число(СтрокаТЗ.Количество);
КонецЦикла;
Альтернатива ручному циклу — метод ЗагрузитьКолонку() с предварительной выгрузкой через ВыгрузитьКолонку(), но он не выполняет преобразование типов, поэтому подходит только когда типы совместимы. Для преобразования надёжнее явный цикл.
Ещё один вариант — получить структуру через запрос: выгрузить таблицу во временную таблицу запроса и применить функции ВЫРАЗИТЬ() для приведения типов. Это удобно для больших таблиц, так как обработка идёт на уровне СУБД.
Сравнение вариантов
Подходит для пустой таблицы. Быстро, но уничтожает данные и сбрасывает позицию колонки.
Универсальный способ для заполненной таблицы. Требует кода преобразования, но сохраняет остальные данные и порядок строк.
Удобно при смене типов нескольких колонок. Требует больше памяти на время копирования.
Эффективен для больших таблиц и сложных приведений, но требует помещения таблицы в запрос и навыков языка запросов.
Изменение типа колонки реквизита формы
Отдельный сценарий — таблица значений, которая является динамическим реквизитом управляемой формы. Здесь недостаточно поменять объект таблицы: тип задан в описании реквизита, и менять его нужно через метод формы ИзменитьРеквизиты().
МассивДобавляемых = Новый Массив;
МассивДобавляемых.Добавить(Новый РеквизитФормы("Сумма",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)),
"ТаблицаДанных"));
МассивУдаляемых = Новый Массив;
МассивУдаляемых.Добавить("ТаблицаДанных.Сумма");
ИзменитьРеквизиты(МассивДобавляемых, МассивУдаляемых);
После вызова ИзменитьРеквизиты() данные удалённого реквизита теряются, а элементы формы, связанные со старой колонкой, нужно пересоздать или перепривязать — иначе получите ошибку «Поле не найдено» при открытии или обновлении формы.
Учтите, что ИзменитьРеквизиты() — ресурсоёмкая операция: форма фактически пересоздаётся. Не вызывайте её в цикле; собирайте все изменения в массивы и применяйте одним вызовом.
Составной тип и тип NULL как альтернатива
Иногда вместо смены типа правильнее расширить его. Если в колонке могут встречаться и строки, и числа, задайте составной тип: Новый ОписаниеТипов("Строка,Число", ...). Это избавляет от переноса данных, но усложняет сортировку, итоги и сравнения — платформа сравнивает значения разных типов по особым правилам, которые не всегда совпадают с ожиданиями.
Если колонка создаётся без указания типа, она получает произвольный тип и принимает любые значения. Это удобно на этапе прототипирования, но в прикладном коде лучше избегать: итоги по таким колонкам не считаются корректно, а выгрузка в макет или СКД может вести себя непредсказуемо.
Проверка результата и отладка
После изменения типа убедитесь, что структура и данные соответствуют ожиданиям. Минимальная проверка — пройти по колонкам и строкам и вывести типы значений:
Для Каждого Колонка Из ТЗ.Колонки Цикл
Сообщить(Колонка.Имя + ": " + Колонка.ТипЗначения);
КонецЦикла;
Для Каждого СтрокаТЗ Из ТЗ Цикл
Если ТипЗнч(СтрокаТЗ.Сумма) <> Тип("Число") Тогда
Сообщить("Некорректное значение в строке " + ТЗ.Индекс(СтрокаТЗ));
КонецЕсли;
КонецЦикла;
Дополнительно сверьте контрольные итоги до и после преобразования: сумму числовой колонки, количество заполненных строк, количество строк всей таблицы. Расхождение итогов — верный признак того, что часть значений не преобразовалась.
Как проверить результат
ТипЗначения содержит нужный тип и квалификаторы
Тип старый или составной без необходимости
Все значения нужного типа, итоги совпадают с контрольными
Встречаются Неопределено или значения по умолчанию
Индекс колонки соответствует исходному
Колонка оказалась в конце таблицы
Элементы отображают данные без ошибок
Ошибка привязки поля или пустая колонка на форме
Частые вопросы
Можно ли изменить тип колонки без удаления, через свойство ТипЗначения?
Нет. Свойство ТипЗначения у колонки таблицы значений доступно только для чтения, попытка присвоения вызовет ошибку. Единственные рабочие пути — пересоздание колонки или всей таблицы с переносом данных.
Что произойдёт со значениями строк при удалении колонки?
Значения этой колонки будут безвозвратно удалены во всех строках таблицы. Остальные колонки и порядок строк не пострадают. Если данные нужны, скопируйте их заранее через ВыгрузитьКолонку() или вручную в массив.
Как изменить длину строковой колонки, например с 50 на 200 символов?
Так же, как и смену типа: удалите колонку и добавьте заново с новым описанием — Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(200)). При переносе данных учтите, что строки длиннее старого ограничения в исходной таблице уже быть не могли, поэтому потерь не будет.
Почему после переноса в числовую колонку значения стали нулями?
Скорее всего, присваивалась строка без явного преобразования, и платформа подставила значение по умолчанию. Используйте функцию Число() с предварительной очисткой строки от пробелов и неразрывных пробелов, а неконвертируемые значения обрабатывайте через Попытка/Исключение.
Как изменить тип колонки таблицы на управляемой форме?
Через метод ИзменитьРеквизиты(): сформируйте массив добавляемых реквизитов с новым типом и массив удаляемых с полным путём вида «ИмяТаблицы.ИмяКолонки». После вызова перепривяжите элементы формы, так как старые связи с удалённым реквизитом перестанут работать.
Можно ли сменить тип колонки запросом?
Да, если поместить таблицу во временную таблицу запроса и применить ВЫРАЗИТЬ к нужным полям — результат будет новой таблицей с приведёнными типами. Способ эффективен для больших объёмов, но требует аккуратности: ВЫРАЗИТЬ не всегда справляется с «грязными» строками, и такие значения могут отбрасываться.
Что важно запомнить
Тип колонки таблицы значений меняется только пересозданием: удалите колонку и добавьте с новым ОписаниеТипов, предварительно сохранив данные. Значения переносите с явным преобразованием через Число(), Дату() или Строку(). На управляемой форме используйте ИзменитьРеквизиты() одним вызовом. После изменения проверьте типы, контрольные итоги и позицию колонки.