При разработке в 1С на обычных формах часто возникает задача программного (динамического) добавления колонок в табличное поле. Разберем ситуацию, когда при попытке установить свойство Данные для новой колонки платформа выдает ошибку: "Ошибка при установке значения атрибута контекста (Данные): Недопустимое значение".
Посмотрим на классический пример кода, который приводит к этой ошибке:
Для Каждого Склад ИЗ МассивСкладов Цикл
СтрокаБезСимв = УбратьЛишниеСимволы(Склад);
Колонка = ЭлементыФормы.Таблица.Колонки.Добавить(СтрокаБезСимв, Склад.Наименование);
Колонка.ТолькоПросмотр = Ложь;
Колонка.УстановитьЭлементУправления(Тип("Флажок"));
Колонка.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
// ТУТ ВОЗНИКАЕТ ОШИБКА
Колонка.Данные = СтрокаБезСимв;
КонецЦикла;
Чтобы понять, почему система выдает ошибку, выясним разницу между визуальным элементом управления (Табличным полем на форме) и источником данных (Табличной частью документа или Таблицей значений).
Когда вы вызываете метод ЭлементыФормы.Таблица.Колонки.Добавить(), вы добавляете колонку исключительно в визуальный интерфейс. Свойство Данные указывает табличному полю, из какого именно реквизита реального источника данных нужно брать информацию для отображения. Если в самом источнике (в табличной части или таблице значений) колонки с именем СтрокаБезСимв физически не существует, платформа закономерно сообщает, что указано "Недопустимое значение".
Если данные на форме хранятся в реквизите типа ТаблицаЗначений, то перед добавлением колонки в визуальный элемент управления, её необходимо добавить в саму структуру данных.
Разберем по шагам правильный алгоритм создания динамической колонки для таблицы значений:
Данные.Посмотрим на пример правильного кода:
Для Каждого Склад ИЗ МассивСкладов Цикл
СтрокаБезСимв = УбратьЛишниеСимволы(Склад);
// 1. Добавляем физическую колонку в саму Таблицу Значений (источник данных)
// Указываем тип данных, например, Булево для флажка
Таблица.Колонки.Добавить(СтрокаБезСимв, Новый ОписаниеТипов("Булево"));
// 2. Добавляем визуальную колонку в элементы формы
Колонка = ЭлементыФормы.Таблица.Колонки.Добавить(СтрокаБезСимв, Склад.Наименование);
Колонка.ТолькоПросмотр = Ложь;
Колонка.УстановитьЭлементУправления(Тип("Флажок"));
Колонка.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
// 3. Теперь привязка пройдет без ошибок, так как колонка есть в данных
Колонка.Данные = СтрокаБезСимв;
КонецЦикла;
Рассмотрим более сложную ситуацию. Если источником является Табличная часть объекта конфигурации (например, документа), мы не можем программно добавить туда новую колонку. Структура табличной части жестко задается в Конфигураторе.
В этом случае привязать динамическую колонку к данным через свойство Данные невозможно. Оставим это свойство пустым. Но если мы просто выведем элемент управления "Флажок", он не будет корректно работать: флажки будут сбрасываться или меняться во всех строках одновременно, так как у них нет физического места для хранения своего состояния (Истина или Ложь).
Разберем по шагам, как реализовать независимые флажки для строк табличной части:
Данные и ДанныеФлажка пустыми.Соответствие), где будем хранить состояния флажков. Ключом будет выступать строка ТЧ, а значением — состояние флажка.ПриВыводеСтроки для визуальной отрисовки сохраненного состояния флажка.ПриИзмененииФлажка, чтобы записывать новые клики пользователя в наше хранилище.Посмотрим на пример реализации данного подхода:
// В модуле формы объявим переменную для хранения состояний
Перем СостоянияФлажковСкладов;
// Процедура инициализации (например, ПриОткрытии)
Процедура ИнициализацияКолонок()
СостоянияФлажковСкладов = Новый Соответствие;
Для Каждого Склад ИЗ МассивСкладов Цикл
СтрокаБезСимв = УбратьЛишниеСимволы(Склад);
Колонка = ЭлементыФормы.Таблица.Колонки.Добавить(СтрокаБезСимв, Склад.Наименование);
Колонка.ТолькоПросмотр = Ложь;
Колонка.УстановитьЭлементУправления(Тип("Флажок"));
Колонка.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
// Оставляем свойства пустыми!
Колонка.Данные = "";
Колонка.ДанныеФлажка = "";
КонецЦикла;
КонецПроцедуры
// Обработчик события ПриВыводеСтроки для табличного поля
Процедура ТаблицаПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
Для Каждого Склад ИЗ МассивСкладов Цикл
ИмяКол = УбратьЛишниеСимволы(Склад);
// Получаем структуру состояний для конкретной строки
СтруктураФлажковСтроки = СостоянияФлажковСкладов.Получить(ДанныеСтроки);
Если СтруктураФлажковСтроки = Неопределено Тогда
ЗначениеФлажка = Ложь;
Иначе
ЗначениеФлажка = СтруктураФлажковСтроки.Получить(ИмяКол);
Если ЗначениеФлажка = Неопределено Тогда
ЗначениеФлажка = Ложь;
КонецЕсли;
КонецЕсли;
// Отрисовываем флажок в ячейке
ОформлениеСтроки.Ячейки[ИмяКол].ОтображатьФлажок = Истина;
ОформлениеСтроки.Ячейки[ИмяКол].Флажок = ЗначениеФлажка;
КонецЦикла;
КонецПроцедуры
// Обработчик события ПриИзмененииФлажка для табличного поля
Процедура ТаблицаПриИзмененииФлажка(Элемент, Колонка)
ТекущаяСтрока = ЭлементыФормы.Таблица.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда Возврат; КонецЕсли;
ИмяКол = Колонка.Имя;
СтруктураФлажковСтроки = СостоянияФлажковСкладов.Получить(ТекущаяСтрока);
Если СтруктураФлажковСтроки = Неопределено Тогда
СтруктураФлажковСтроки = Новый Структура;
СостоянияФлажковСкладов.Вставить(ТекущаяСтрока, СтруктураФлажковСтроки);
КонецЕсли;
ТекущееЗначение = СтруктураФлажковСтроки.Получить(ИмяКол);
Если ТекущееЗначение = Неопределено Тогда ТекущееЗначение = Ложь; КонецЕсли;
// Инвертируем значение по клику
СтруктураФлажковСтроки.Вставить(ИмяКол, Не ТекущееЗначение);
КонецПроцедуры
Таким образом, мы детально рассмотрели два варианта работы с программно создаваемыми колонками. Запомните главное правило: ошибка "Недопустимое значение" означает рассинхронизацию интерфейса и данных. Применяйте описанные методики в зависимости от того, какой именно источник данных (ТЗ или ТЧ) используется в вашей задаче.