В процессе разработки на платформе 1С:Предприятие одной из самых часто встречающихся задач является манипуляция данными в объекте ТаблицаЗначений. Однако начинающие разработчики часто сталкиваются с проблемой: при попытке записать значение в колонку вместо ожидаемых данных система подставляет Неопределено. Разберем подробно, почему это происходит и как правильно управлять типами данных в таблицах.
Проанализируем ситуацию: у нас есть колонка, которая изначально была инициализирована с типом ДокументСсылка (например, ссылка на «Реализацию товаров и услуг»). Когда мы пытаемся выполнить код:
Для каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
СтрокаТаблицы.Колонка1 = "123";
КонецЦикла;
Система 1С видит, что мы пытаемся записать объект типа Строка в поле, предназначенное исключительно для типа ДокументСсылка. Поскольку 1С — это система со строгой типизацией в рамках объектов метаданных, она выполняет автоматическое приведение типов. Так как строку "123" невозможно преобразовать в ссылку на документ, значение сбрасывается в Неопределено (или в пустую ссылку, если тип не составной).
Если мы создаем таблицу значений программно «с нуля», крайне важно сразу определить правильный тип данных. Для этого используется объект ОписаниеТипов. Рассмотрим пример, где мы создаем колонку, которая должна принимать строковые значения:
ТЗ = Новый ТаблицаЗначений;
ОписаниеТипаСтрока = Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(150));
ТЗ.Колонки.Добавить("Колонка1", ОписаниеТипаСтрока);
В данном случае мы четко указали системе, что Колонка1 будет содержать строки длиной до 150 символов. Теперь любая попытка записать туда строку будет успешной.
Часто возникают задачи, когда в одной и той же колонке могут храниться разные типы данных: и ссылки на документы, и ссылки на справочники, и даже простые числа или строки. Именно такая ситуация была описана в обсуждении, когда тип должен меняться с ДокументСсылка на СправочникСсылка.
Рассмотрим, как программно создать колонку с составным типом. Разберем этот процесс по шагам:
ОписаниеТипов на основании этого массива.
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Контрагенты"));
МассивТипов.Добавить(Тип("ДокументСсылка.РеализацияТоваровУслуг"));
МассивТипов.Добавить(Тип("Строка"));
ОписаниеСоставногоТипа = Новый ОписаниеТипов(МассивТипов, , Новый КвалификаторыСтроки(100));
ТЗ.Колонки.Добавить("СубконтоЗначение", ОписаниеСоставногоТипа);
Теперь в ячейку СубконтоЗначение можно записывать как ссылку на контрагента, так и ссылку на реализацию или обычный текст. Система не будет очищать значение, так как оно соответствует одному из разрешенных типов.
Выясним важный технический нюанс: у уже созданной колонки свойство ТипЗначения доступно только для чтения. Мы не можем просто написать ТЗ.Колонки.Колонка1.ТипЗначения = Новый ОписаниеТипов(...). Если таблица уже заполнена данными и нам нужно изменить тип колонки, не потеряв информацию, следует использовать следующий алгоритм:
Колонка_Буфер и нужным нам новым типом данных.ТЗ.Колонки.Удалить("Колонка1").Колонка1 и уже новым, правильным типом.В контексте задачи пользователя с форума, проблема заключалась в заполнении движений по счету 98.01 («Доходы будущих периодов»). При проведении документа «Реализация товаров и услуг» важно помнить, что субконто в регистре бухгалтерии имеют тип Характеристика.ВидыСубконтоХозрасчетные.
Проанализируем ситуацию: если вы пытаетесь программно подсунуть в таблицу движений строку там, где План Счетов ожидает ссылку на конкретный справочник (например, «Доходы будущих периодов»), система выдаст Неопределено не из-за ошибки в таблице, а из-за несоответствия типа характеристики.
Рекомендация: Для корректного заполнения Субконто2 и Субконто3 используйте следующий подход в модуле проведения:
// Пример заполнения субконто для бухгалтерской проводки
НоваяПроводка = Движения.Хозрасчетный.Добавить();
НоваяПроводка.СчетКт = ПланыСчетов.Хозрасчетный.ДоходыБудущихПериодов;
// Установка субконто по виду субконто
ВидСубк = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ДоходыБудущихПериодов;
НоваяПроводка.СубконтоКт[ВидСубк] = СсылкаНаОбъектДоходов;
Здесь СсылкаНаОбъектДоходов должна быть именно ссылкой (объектом типа СправочникСсылка), а не строкой. Если ваши данные приходят из внешней системы в виде строк, обязательно выполните поиск ссылки перед записью в таблицу значений или движения:
НайденнаяСсылка = Справочники.ДоходыБудущихПериодов.НайтиПоНаименованию(ЗначениеИзТЗ);
Если Не НайденнаяСсылка.Пустая() Тогда
СтрокаДвижений.СубконтоКт2 = НайденнаяСсылка;
КонецЕсли;
Для успешной работы с типами в таблицах значений придерживайтесь следующих правил:
ОписаниеТипов при добавлении колонок, если планируете записывать туда что-то, кроме строк.Произвольный (пустое описание типов) удобен, но может приводить к ошибкам при выводе данных в интерфейс или при передаче в запросы.