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