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