Переход с обычных форм (ОФ) на управляемые (УФ) — это не просто смена интерфейса, а полная смена парадигмы разработки. В управляемом приложении 1С реализовано четкое разделение на клиентскую и серверную части, что часто вызывает трудности у разработчиков, привыкших к "толстому" клиенту. Проанализируем основные ошибки и разберем по шагам, как правильно адаптировать код при миграции.
Рассмотрим первую типичную ошибку: обращение к реквизиту формы напрямую по имени. В обычных формах мы могли написать Сортировка.Очистить(), и система понимала, что речь идет об элементе управления. В управляемых формах есть четкое различие между Данными (реквизитами) и Элементами (визуальным представлением).
Если вам нужно изменить свойства визуального элемента (например, наполнить список выбора), необходимо обращаться к коллекции Элементы. Проанализируем правильный код:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Ошибка: Сортировка.СписокВыбора.Очистить();
// Правильно:
Элементы.Сортировка.СписокВыбора.Очистить();
Элементы.Сортировка.СписокВыбора.Добавить(1, "по периоду за");
КонецПроцедуры
Важно понимать, что Элементы — это программные объекты, описывающие поведение контролов на экране. Если вы просто напишете имя реквизита, система будет искать его в контексте модуля или данных формы, но не найдет методов управления списком выбора.
Вторая критическая ошибка новичков — попытка обратиться к объектам метаданных или базе данных (например, к планам счетов или справочникам) непосредственно в клиентских процедурах. Выясним причину ошибки: на клиенте (директива &НаКлиенте) база данных недоступна. Все запросы к данным должны выполняться на сервере.
Рассмотрим ситуацию с поиском счета в плане счетов. Если вы напишете ПланыСчетов.Хозрасчетный.НайтиПоКоду("90.01") внутри клиентской процедуры ПриОткрытии, система выдаст ошибку "Переменная не определена". Правильный подход заключается в выносе этой логики в серверный контекст:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Здесь обращение к базе данных разрешено
Если Не ЗначениеЗаполнено(Объект.СчетКт) Тогда
Объект.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("90.01");
КонецЕсли;
КонецПроцедуры
Совет: старайтесь выполнять инициализацию формы в событии ПриСозданииНаСервере, а не ПриОткрытии. Это позволяет сократить количество клиент-серверных вызовов (round-trips), так как форма создается на сервере и передается на клиент уже в полностью подготовленном виде.
Часто в старых обработках основная логика (например, формирование запроса) была описана в модуле объекта. В управляемых формах модуль формы и модуль объекта — это разные программные пространства. Чтобы вызвать экспортную процедуру из модуля объекта, находясь в модуле формы, нам нужно "материализовать" объект из данных формы.
Рассмотрим использование функции РеквизитФормыВЗначение. Посмотрим на пример вызова процедуры СформироватьЗапрос, находящейся в модуле объекта:
&НаСервере
Процедура ВыполнитьДействиеНаСервере()
// Преобразуем данные формы (Объект) в реальный объект обработки
ОбъектОбработка = РеквизитФормыВЗначение("Объект");
// Теперь нам доступны экспортные методы модуля объекта
ОбъектОбработка.СформироватьЗапрос();
// Если метод изменил данные объекта, их нужно вернуть обратно на форму
ЗначениеВРеквизитФормы(ОбъектОбработка, "Объект");
КонецПроцедуры
Аналогичный подход применяется при работе с макетами. На управляемой форме нет метода ПолучитьМакет. Чтобы получить макет внешней обработки, мы должны действовать через объект:
&НаСервере
Функция ПолучитьПечатнуюФорму()
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
Макет = ОбработкаОбъект.ПолучитьМакет("Макет");
// Дальнейшая работа с макетом...
КонецФункции
Разберем еще одну распространенную ошибку: сравнение элементов формы вместо их значений. Когда вы пишете Если Элементы.ДатаНачала < Элементы.ДатаКонца Тогда, система пытается сравнить два программных объекта (кнопки или поля ввода), а не даты, которые в них введены. Это приводит к ошибке сравнения.
Проанализируем правильный вариант. Сравнивать нужно именно Реквизиты, которые обычно привязаны к основному реквизиту формы Объект:
&НаКлиенте
Процедура КнопкаВыполнитьНажатие(Команда)
// Обращаемся к данным через Объект.ИмяРеквизита
Если Объект.ДатаНачала > Объект.ДатаКонца Тогда
Сообщить("Дата начала не может быть больше даты окончания!");
Возврат;
КонецЕсли;
СформироватьНаСервере();
КонецПроцедуры
Подводя итог, при переделке обработки с ОФ на УФ следует придерживаться следующих правил:
Элементы для визуальных настроек и Объект для работы с данными.Справочники, Документы, ПланыСчетов) и макетов, должно выполняться под директивой &НаСервере.ПриСозданииНаСервере.РеквизитФормыВЗначение.СписокВыбора элемента формы, убедитесь, что у элемента установлено свойство РежимВыбораИзСписка, иначе пользователь может не увидеть ваш список.Соблюдение этих принципов позволит вам создавать стабильные и быстрые управляемые формы, соответствующие стандартам разработки фирмы "1С".