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