При разработке управляемых форм в платформе 1С:Предприятие 8.3 разработчики часто сталкиваются с необходимостью передавать данные между клиентом и сервером, а также преобразовывать реквизиты формы в прикладные объекты. Однако попытка применить универсальные методы трансформации данных к реквизитам типа ТабличныйДокумент приводит к ошибке выполнения:
«Ошибка при вызове метода контекста (ДанныеФормыВЗначение): Несоответствие типов (параметр номер 1)»
Разберем причины возникновения этой ошибки, выясним, почему реквизит табличного документа не требует преобразования, и рассмотрим правильные подходы к заполнению и обновлению табличного документа на клиенте и сервере.
Проанализируем назначение функции ДанныеФормыВЗначение. Данная функция предназначена исключительно для преобразования специальных промежуточных структур данных управляемой формы в реальные прикладные объекты платформы. Первый параметр функции принимает строго определенные типы-обертки:
ДанныеФормыСтруктура (например, реквизит Объект типа ДокументОбъект или СправочникОбъект);ДанныеФормыКоллекция (табличные части, списки значений, таблицы значений формы);ДанныеФормыДерево (деревья значений на форме);ДанныеФормыСтруктураСКоллекцией.Реквизит управляемой формы с типом ТабличныйДокумент не оборачивается платформой в структуры ДанныеФормы.... И на клиенте, и на сервере он изначально является полноценным экземпляром объекта ТабличныйДокумент. Поскольку тип значения уже соответствует прикладному объекту, вызов ДанныеФормыВЗначение завершается исключением из-за несовместимости типа первого параметра.
Аналогично, к реквизитам типа ТабличныйДокумент не нужно применять методы ЗначениеВДанныеФормы и КопироватьДанныеФормы.
Объект ТабличныйДокумент сериализуется и может свободно передаваться между клиентом и сервером как возвращаемое значение функции или параметр процедуры. Рассмотрим два основных способа работы в зависимости от контекста выполнения.
Когда требуется сформировать печатную форму или шахматку без передачи контекста всей формы (например, из событий динамических списков), оптимально создавать новый табличный документ на сервере и возвращать его в клиентскую процедуру.
Посмотрим на пример правильной организации кода:
&НаСервереБезКонтекста
Функция СформироватьШахматкуНаСервере(СтроительныйОбъект, Подъезд)
ТабДок = Новый ТабличныйДокумент;
// Выполняем запрос к данным и формируем макет
// Например:
// Макет = Обработки.Шахматка.ПолучитьМакет("Макет");
// Область = Макет.ПолучитьОбласть("Строка");
// ТабДок.Вывести(Область);
Возврат ТабДок;
КонецФункции
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
СтрокаДанных = Элемент.ТекущиеДанные;
Если СтрокаДанных = Неопределено Тогда
Возврат;
КонецЕсли;
Если ЗначениеЗаполнено(СтрокаДанных.Подъезд) Тогда
// Напрямую присваиваем результат серверной функции реквизиту формы
ШахматныйТабличныйРеквизит = СформироватьШахматкуНаСервере(
СтрокаДанных.СтроительныйОбъект,
СтрокаДанных.Подъезд
);
Иначе
ШахматныйТабличныйРеквизит.Очистить();
КонецЕсли;
КонецПроцедуры
Если серверный метод имеет доступ к контексту формы (директива &НаСервере), табличный документ формы доступен напрямую по имени реквизита. Никаких промежуточных переменных и преобразований использовать не нужно.
Рассмотрим пример контекстного вызова:
&НаСервере
Процедура ЗаполнитьШахматкуНаСервере()
// Очищаем текущий табличный документ на форме
ШахматныйТабличныйРеквизит.Очистить();
// Заполняем реквизит напрямую
// ШахматныйТабличныйРеквизит.Вывести(...);
КонецПроцедуры
При вызове серверных методов из события ПриАктивизацииСтроки важно учитывать особенности поведения платформы:
Неопределено: При открытии формы или позиционировании на пустом списке свойство Элемент.ТекущиеДанные возвращает Неопределено. Обращение к его полям напрямую (например, Элемент.ТекущиеДанные.Подъезд) вызовет ошибку. Всегда выполняйте предварительную проверку.&НаСервере из обработчика смены строки может приводить к повторному срабатыванию событий формы. Использование процедур &НаСервереБезКонтекста полностью решает эту проблему.ПодключитьОбработчикОжидания с задержкой 0.2–0.3 секунды.