Как правильно изменить тип колонки в таблице значений 1С и избежать значения «Неопределено»?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

В процессе разработки на платформе 1С:Предприятие одной из самых часто встречающихся задач является манипуляция данными в объекте ТаблицаЗначений. Однако начинающие разработчики часто сталкиваются с проблемой: при попытке записать значение в колонку вместо ожидаемых данных система подставляет Неопределено. Разберем подробно, почему это происходит и как правильно управлять типами данных в таблицах.

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

Проанализируем ситуацию: у нас есть колонка, которая изначально была инициализирована с типом ДокументСсылка (например, ссылка на «Реализацию товаров и услуг»). Когда мы пытаемся выполнить код:


Для каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
    СтрокаТаблицы.Колонка1 = "123";
КонецЦикла;

Система 1С видит, что мы пытаемся записать объект типа Строка в поле, предназначенное исключительно для типа ДокументСсылка. Поскольку 1С — это система со строгой типизацией в рамках объектов метаданных, она выполняет автоматическое приведение типов. Так как строку "123" невозможно преобразовать в ссылку на документ, значение сбрасывается в Неопределено (или в пустую ссылку, если тип не составной).

Способ 1. Программное создание колонки с нужным типом

Если мы создаем таблицу значений программно «с нуля», крайне важно сразу определить правильный тип данных. Для этого используется объект ОписаниеТипов. Рассмотрим пример, где мы создаем колонку, которая должна принимать строковые значения:


ТЗ = Новый ТаблицаЗначений;
ОписаниеТипаСтрока = Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(150));
ТЗ.Колонки.Добавить("Колонка1", ОписаниеТипаСтрока);

В данном случае мы четко указали системе, что Колонка1 будет содержать строки длиной до 150 символов. Теперь любая попытка записать туда строку будет успешной.

Способ 2. Использование составных типов данных

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

Рассмотрим, как программно создать колонку с составным типом. Разберем этот процесс по шагам:

  1. Создадим массив, в который добавим все необходимые типы.
  2. Инициализируем ОписаниеТипов на основании этого массива.
  3. Добавим колонку в таблицу значений.

МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Контрагенты"));
МассивТипов.Добавить(Тип("ДокументСсылка.РеализацияТоваровУслуг"));
МассивТипов.Добавить(Тип("Строка"));

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

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

Способ 3. Изменение типа в существующей и заполненной таблице (Алгоритм «Буфер»)

Выясним важный технический нюанс: у уже созданной колонки свойство ТипЗначения доступно только для чтения. Мы не можем просто написать ТЗ.Колонки.Колонка1.ТипЗначения = Новый ОписаниеТипов(...). Если таблица уже заполнена данными и нам нужно изменить тип колонки, не потеряв информацию, следует использовать следующий алгоритм:

  1. Добавление временной колонки: Создаем колонку с именем Колонка_Буфер и нужным нам новым типом данных.
  2. Перенос данных: В цикле проходим по таблице и копируем значения из старой колонки в новую, при необходимости выполняя преобразование типов.
  3. Удаление старой колонки: Используем метод ТЗ.Колонки.Удалить("Колонка1").
  4. Создание новой колонки: Добавляем колонку с исходным именем Колонка1 и уже новым, правильным типом.
  5. Возврат данных: Переносим данные из буфера обратно и удаляем временную колонку.

Особенности работы с субконто (Счет 98.01)

В контексте задачи пользователя с форума, проблема заключалась в заполнении движений по счету 98.01 («Доходы будущих периодов»). При проведении документа «Реализация товаров и услуг» важно помнить, что субконто в регистре бухгалтерии имеют тип Характеристика.ВидыСубконтоХозрасчетные.

Проанализируем ситуацию: если вы пытаетесь программно подсунуть в таблицу движений строку там, где План Счетов ожидает ссылку на конкретный справочник (например, «Доходы будущих периодов»), система выдаст Неопределено не из-за ошибки в таблице, а из-за несоответствия типа характеристики.

Рекомендация: Для корректного заполнения Субконто2 и Субконто3 используйте следующий подход в модуле проведения:


// Пример заполнения субконто для бухгалтерской проводки
НоваяПроводка = Движения.Хозрасчетный.Добавить();
НоваяПроводка.СчетКт = ПланыСчетов.Хозрасчетный.ДоходыБудущихПериодов;

// Установка субконто по виду субконто
ВидСубк = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ДоходыБудущихПериодов;
НоваяПроводка.СубконтоКт[ВидСубк] = СсылкаНаОбъектДоходов; 

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


НайденнаяСсылка = Справочники.ДоходыБудущихПериодов.НайтиПоНаименованию(ЗначениеИзТЗ);
Если Не НайденнаяСсылка.Пустая() Тогда
    СтрокаДвижений.СубконтоКт2 = НайденнаяСсылка;
КонецЕсли;

Резюме

Для успешной работы с типами в таблицах значений придерживайтесь следующих правил:

← На главную