Почему возникает ошибка «Несоответствие типов» при вызове ДанныеФормыВЗначение для ТабличногоДокумента и как её исправить?

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

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

«Ошибка при вызове метода контекста (ДанныеФормыВЗначение): Несоответствие типов (параметр номер 1)»

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

Причина ошибки: ограничения метода ДанныеФормыВЗначение

Проанализируем назначение функции ДанныеФормыВЗначение. Данная функция предназначена исключительно для преобразования специальных промежуточных структур данных управляемой формы в реальные прикладные объекты платформы. Первый параметр функции принимает строго определенные типы-обертки:

  1. ДанныеФормыСтруктура (например, реквизит Объект типа ДокументОбъект или СправочникОбъект);
  2. ДанныеФормыКоллекция (табличные части, списки значений, таблицы значений формы);
  3. ДанныеФормыДерево (деревья значений на форме);
  4. ДанныеФормыСтруктураСКоллекцией.

Реквизит управляемой формы с типом ТабличныйДокумент не оборачивается платформой в структуры ДанныеФормы.... И на клиенте, и на сервере он изначально является полноценным экземпляром объекта ТабличныйДокумент. Поскольку тип значения уже соответствует прикладному объекту, вызов ДанныеФормыВЗначение завершается исключением из-за несовместимости типа первого параметра.

Аналогично, к реквизитам типа ТабличныйДокумент не нужно применять методы ЗначениеВДанныеФормы и КопироватьДанныеФормы.

Как правильно передавать и формировать ТабличныйДокумент

Объект ТабличныйДокумент сериализуется и может свободно передаваться между клиентом и сервером как возвращаемое значение функции или параметр процедуры. Рассмотрим два основных способа работы в зависимости от контекста выполнения.

Способ 1. Формирование в функции &НаСервереБезКонтекста (рекомендуемый)

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

Посмотрим на пример правильной организации кода:


&НаСервереБезКонтекста
Функция СформироватьШахматкуНаСервере(СтроительныйОбъект, Подъезд)
    
    ТабДок = Новый ТабличныйДокумент;
    
    // Выполняем запрос к данным и формируем макет
    // Например:
    // Макет = Обработки.Шахматка.ПолучитьМакет("Макет");
    // Область = Макет.ПолучитьОбласть("Строка");
    // ТабДок.Вывести(Область);
    
    Возврат ТабДок;
    
КонецФункции

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

Способ 2. Заполнение в контекстной серверной процедуре &НаСервере

Если серверный метод имеет доступ к контексту формы (директива &НаСервере), табличный документ формы доступен напрямую по имени реквизита. Никаких промежуточных переменных и преобразований использовать не нужно.

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


&НаСервере
Процедура ЗаполнитьШахматкуНаСервере()
    
    // Очищаем текущий табличный документ на форме
    ШахматныйТабличныйРеквизит.Очистить();
    
    // Заполняем реквизит напрямую
    // ШахматныйТабличныйРеквизит.Вывести(...);
    
КонецПроцедуры

Оптимизация события ПриАктивизацииСтроки

При вызове серверных методов из события ПриАктивизацииСтроки важно учитывать особенности поведения платформы:

  1. Проверка на Неопределено: При открытии формы или позиционировании на пустом списке свойство Элемент.ТекущиеДанные возвращает Неопределено. Обращение к его полям напрямую (например, Элемент.ТекущиеДанные.Подъезд) вызовет ошибку. Всегда выполняйте предварительную проверку.
  2. Избегание циклических вызовов: Использование контекстных серверных вызовов &НаСервере из обработчика смены строки может приводить к повторному срабатыванию событий формы. Использование процедур &НаСервереБезКонтекста полностью решает эту проблему.
  3. Подключение обработчика ожидания: Быстрое перемещение по строкам списка с помощью клавиатуры или мыши провоцирует множество частых вызовов сервера подряд. Для оптимизации нагрузки рекомендуется вызывать серверное формирование через ПодключитьОбработчикОжидания с задержкой 0.2–0.3 секунды.
← На главную