Почему не изменяется значение в колонке таблицы значений и как правильно записать данные в строку

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке обработок и документов в обычных формах 1С разработчики нередко сталкиваются с ситуацией: форма выбора открывается, пользователь выбирает элемент, в отладчике значение получено, но ячейка в табличном поле на форме упорно остается пустой. Проанализируем, почему возникает такая ошибка, разберем базовую логику работы с переменными в платформе 1С и рассмотрим надежные способы заполнения колонок таблицы значений.

Анализ типичной ошибки: переменная вместо свойства строки

Посмотрим на фрагмент кода, с которого часто начинаются подобные затруднения:


ФормаВыбора = Справочники.Сотрудники.ПолучитьФормуВыбора();
ВыбранноеЗначение = ФормаВыбора.ОткрытьМодально();

ТекущиеДанные = ЭлементыФормы.ДокументыКИмпорту.ТекущиеДанные.Контрагент;
ТекущиеДанные = ВыбранноеЗначение;
Сообщить(ТекущиеДанные);

Выясним причину, почему этот код не работает. В строке с обращением к свойству ТекущиеДанные.Контрагент платформа считывает текущее значение из ячейки и помещает его в локальную переменную ТекущиеДанные. На этом связь с таблицей значений полностью разрывается.

Когда далее выполняется присваивание ТекущиеДанные = ВыбранноеЗначение, разработчик просто перезаписывает содержимое локальной переменной, а не ячейки в строке таблицы. Сама таблица значений на форме остается нетронутой.

Правильный способ записи в текущую строку

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

Вариант 1. Прямое присваивание свойству строки:


ФормаВыбора = Справочники.Сотрудники.ПолучитьФормуВыбора();
ВыбранноеЗначение = ФормаВыбора.ОткрытьМодально();

Если ВыбранноеЗначение <> Неопределено Тогда
    ЭлементыФормы.ДокументыКИмпорту.ТекущиеДанные.Контрагент = ВыбранноеЗначение;
КонецЕсли;

Вариант 2. Получение ссылки на текущую строку:

Рассмотрим более читаемый и удобный подход, когда в отдельную переменную помещается не значение конкретной ячейки, а сама строка таблицы:


СтрокаТаблицы = ЭлементыФормы.ДокументыКИмпорту.ТекущиеДанные;
Если СтрокаТаблицы <> Неопределено Тогда
    СтрокаТаблицы.Контрагент = ВыбранноеЗначение;
КонецЕсли;

Здесь переменная СтрокаТаблицы содержит ссылку на объект строки (СтрокаТаблицыЗначений). Изменяя свойство этого объекта, мы напрямую модифицируем данные в строке таблицы.

Безопасная работа с текущими данными

Обратите внимание на обязательную проверку на Неопределено. Свойство ТекущиеДанные возвращает Неопределено в двух случаях:

  1. Таблица значений пуста, в ней нет ни одной строки.
  2. Ни одна строка таблицы в данный момент не выбрана или не активизирована курсором.

Если попытаться обратиться к свойству колонки напрямую без проверки при отсутствии активной строки, платформа выдаст критическую ошибку времени выполнения: «Поле агрегатного объекта не обнаружено» или «Попытка обращения к свойству значения типа "Неопределено"».

Проверка соответствия типов данных в колонке

Иногда даже при синтаксически корректном присваивании ячейка остается пустой. Проанализируем еще одну скрытую причину такого поведения — ограничение по типам данных.

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

Чтобы проверить состав типов, выполним проверку через свойство колонки:


ТипыКолонки = ТаблицаЗначений.Колонки.Контрагент.ТипЗначения;
Сообщить(ТипыКолонки);

Если колонка должна содержать ссылки разных справочников, необходимо объявить составной тип данных при создании или переопределить коллекцию допустимых типов в описании колонки.

Обновление отображения данных на форме

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


// Обновление конкретной измененной строки
ЭлементыФормы.ДокументыКИмпорту.ОбновитьСтроки(СтрокаТаблицы);

// Либо полное обновление всего табличного поля
ЭлементыФормы.ДокументыКИмпорту.Обновить();

Также обязательно проверим свойства самой колонки в дизайнере формы. В свойстве колонки Данные должно быть корректно указано имя реквизита строки таблицы. Если связь разорвана, данные в памяти будут меняться, но пользователь в ячейке ничего не увидит.

Использование штатного события «НачалоВыбора»

Вместо ручного написания процедур с открытием форм выбора через отдельные кнопки, правильнее использовать стандартный интерфейсный механизм платформы. Разберем, как это реализовать:

  1. В свойствах колонки табличного поля установим флажок КнопкаВыбора = Истина.
  2. Назначим для колонки обработчик события НачалоВыбора.
  3. Если требуется стандартный выбор из назначенного колонке типа, не отключаем параметр СтандартнаяОбработка — платформа откроет нужный справочник и запишет результат в строку автоматически без единой строчки кода.
  4. Если требуется переопределить тип выбираемого объекта или открыть нестандартную форму, отключаем стандартную обработку и открываем форму:

Процедура ДокументыКИмпортуКонтрагентНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    ФормаВыбора = Справочники.Сотрудники.ПолучитьФормуВыбора(, Элемент);
    ВыбранныйСотрудник = ФормаВыбора.ОткрытьМодально();
    
    Если ВыбранныйСотрудник <> Неопределено Тогда
        Элемент.Значение = ВыбранныйСотрудник;
    КонецЕсли;
КонецПроцедуры

Помним также, что метод ОткрытьМодально() считается устаревшим и блокируется в конфигурациях с включенным режимом запрета модальности. При разработке тиражируемых решений рекомендуется использовать немодальное открытие через описание оповещения или переопределять обработчик ОбработкаВыбора.

← На главную