Как правильно обновить отображение табличной части в управляемой форме и исправить ошибку «Недопустимое значение параметра»

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

При разработке в среде 1С:Предприятие 8.3 на управляемых формах программисты часто сталкиваются с необходимостью программного изменения данных в табличных частях. Одной из типичных ошибок является попытка использовать механизмы преобразования объекта там, где это не требуется. Рассмотрим ситуацию, когда при использовании метода ЗначениеВРеквизитФормы возникает ошибка «Недопустимое значение параметра (параметр номер 2)», и выясним, как правильно организовать работу с данными формы.

Разберем причину возникновения ошибки

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


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

В данном примере ошибка «Недопустимое значение параметра (параметр номер 2)» в методе ЗначениеВРеквизитФормы возникает потому, что система ожидает в качестве второго параметра путь к основному реквизиту (целому объекту), а не к его части. Кроме того, табличные части как самостоятельные сущности не подлежат такому преобразованию отдельно от владельца. Когда мы передаем в метод путь "Объект.НаОбработку", платформа не может корректно сопоставить типы данных, так как на форме табличная часть представлена типом ДанныеФормыКоллекция, а после преобразования мы пытаемся вернуть управление через механизмы, предназначенные для целых объектов (например, СправочникОбъект или ДокументОбъект).

Почему не стоит использовать преобразование РеквизитФормыВЗначение для простых задач

Проанализируем архитектуру управляемых форм. Метод РеквизитФормыВЗначение — это крайне «тяжелая» операция. При его вызове система выполняет десериализацию данных из формы, создает полноценный прикладной объект в памяти сервера, инициализирует его модули и обработчики. Если ваша задача заключается в простой установке флажка или изменении значения в строке, такие затраты ресурсов избыточны.

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

Правильное решение: прямая работа с реквизитами формы

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

Рассмотрим исправленный программный код:


&НаСервере
Процедура ОбновитьОтображениеПечатиТЧ(МассивЗаявок)
    // Мы работаем напрямую с данными формы, которые доступны в контексте сервера
    Для Каждого ТекСтр Из Объект.НаОбработку Цикл
        Если МассивЗаявок.Найти(ТекСтр.ДокументСсылка) <> Неопределено Тогда
            ТекСтр.СтатусПечати = Истина;
        КонецЕсли;    
    КонецЦикла;
    // Никаких дополнительных ЗначениеВРеквизитФормы не требуется!
КонецПроцедуры

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

Что делать, если визуально данные на форме не обновляются?

Иногда разработчики сталкиваются с ситуацией, когда данные в памяти сервера изменены, но пользователь на экране видит старые значения. Если вы столкнулись с подобным эффектом в управляемом приложении, проанализируйте следующие моменты:

  1. Контекст вызова: Убедитесь, что процедура вызывается с передачей контекста формы (директива &НаСервере). Если вы используете &НаСервереБезКонтекста, то изменения в Объект внутри процедуры не повлияют на форму, так как копия данных формы на сервер не передавалась.
  2. Принудительное обновление: Если изменения сложны или затрагивают условное оформление, после возврата с сервера на клиент можно вызвать метод ЭтаФорма.ОбновитьОтображениеДанных().

Посмотрим, как это выглядит в связке клиент-сервер:


&НаКлиенте
Процедура ВыполнитьОбновление()
    МассивЗаявок = ПолучитьМассивДляОбработки();
    ОбновитьОтображениеПечатиТЧ(МассивЗаявок);
    // Принудительно перерисовываем форму, если это необходимо
    ЭтаФорма.ОбновитьОтображениеДанных();
КонецПроцедуры

&НаСервере
Процедура ОбновитьОтображениеПечатиТЧ(МассивЗаявок)
    // Логика изменения данных в Объект.НаОбработку
КонецПроцедуры

Альтернативный метод: Использование КопироватьДанныеФормы

В некоторых случаях данные для табличной части подготавливаются в виде отдельной ТаблицыЗначений (например, в результате сложного запроса). Чтобы не перебирать строки вручную, мы можем использовать специализированный метод КопироватьДанныеФормы. Это гораздо эффективнее, чем попытки использовать ЗначениеВРеквизитФормы для вложенных структур.

Пример использования метода:


&НаСервере
Процедура ЗаполнитьТЧИзЗапроса()
    Запрос = Новый Запрос("ВЫБРАТЬ ... "); // Ваш запрос
    ТЗРезультат = Запрос.Выполнить().Выгрузить();
    
    // Копируем данные из таблицы значений напрямую в коллекцию формы
    КопироватьДанныеФормы(ТЗРезультат, Объект.НаОбработку);
КонецПроцедуры

Подведем итоги

Для эффективной работы с табличными частями в управляемых формах 1С придерживайтесь следующих правил:

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

← На главную