Как переделать внешнюю обработку с обычных на управляемые формы в 1С:Предприятии 8.3

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

Переход с обычных форм (ОФ) на управляемые (УФ) — это не просто смена интерфейса, а полная смена парадигмы разработки. В управляемом приложении 1С реализовано четкое разделение на клиентскую и серверную части, что часто вызывает трудности у разработчиков, привыкших к "толстому" клиенту. Проанализируем основные ошибки и разберем по шагам, как правильно адаптировать код при миграции.

Различие между данными и элементами формы

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

Если вам нужно изменить свойства визуального элемента (например, наполнить список выбора), необходимо обращаться к коллекции Элементы. Проанализируем правильный код:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Ошибка: Сортировка.СписокВыбора.Очистить();
    // Правильно:
    Элементы.Сортировка.СписокВыбора.Очистить();
    Элементы.Сортировка.СписокВыбора.Добавить(1, "по периоду за");
КонецПроцедуры

Важно понимать, что Элементы — это программные объекты, описывающие поведение контролов на экране. Если вы просто напишете имя реквизита, система будет искать его в контексте модуля или данных формы, но не найдет методов управления списком выбора.

Клиент-серверное взаимодействие и обращение к базе данных

Вторая критическая ошибка новичков — попытка обратиться к объектам метаданных или базе данных (например, к планам счетов или справочникам) непосредственно в клиентских процедурах. Выясним причину ошибки: на клиенте (директива &НаКлиенте) база данных недоступна. Все запросы к данным должны выполняться на сервере.

Рассмотрим ситуацию с поиском счета в плане счетов. Если вы напишете ПланыСчетов.Хозрасчетный.НайтиПоКоду("90.01") внутри клиентской процедуры ПриОткрытии, система выдаст ошибку "Переменная не определена". Правильный подход заключается в выносе этой логики в серверный контекст:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Здесь обращение к базе данных разрешено
    Если Не ЗначениеЗаполнено(Объект.СчетКт) Тогда
        Объект.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("90.01");
    КонецЕсли;
КонецПроцедуры

Совет: старайтесь выполнять инициализацию формы в событии ПриСозданииНаСервере, а не ПриОткрытии. Это позволяет сократить количество клиент-серверных вызовов (round-trips), так как форма создается на сервере и передается на клиент уже в полностью подготовленном виде.

Работа с процедурами модуля объекта и макетами

Часто в старых обработках основная логика (например, формирование запроса) была описана в модуле объекта. В управляемых формах модуль формы и модуль объекта — это разные программные пространства. Чтобы вызвать экспортную процедуру из модуля объекта, находясь в модуле формы, нам нужно "материализовать" объект из данных формы.

Рассмотрим использование функции РеквизитФормыВЗначение. Посмотрим на пример вызова процедуры СформироватьЗапрос, находящейся в модуле объекта:


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

Аналогичный подход применяется при работе с макетами. На управляемой форме нет метода ПолучитьМакет. Чтобы получить макет внешней обработки, мы должны действовать через объект:


&НаСервере
Функция ПолучитьПечатнуюФорму()
    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    Макет = ОбработкаОбъект.ПолучитьМакет("Макет");
    // Дальнейшая работа с макетом...
КонецФункции

Сравнение значений реквизитов

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

Проанализируем правильный вариант. Сравнивать нужно именно Реквизиты, которые обычно привязаны к основному реквизиту формы Объект:


&НаКлиенте
Процедура КнопкаВыполнитьНажатие(Команда)
    // Обращаемся к данным через Объект.ИмяРеквизита
    Если Объект.ДатаНачала > Объект.ДатаКонца Тогда
        Сообщить("Дата начала не может быть больше даты окончания!");
        Возврат;
    КонецЕсли;
    
    СформироватьНаСервере();
КонецПроцедуры

Итоги и рекомендации по миграции

Подводя итог, при переделке обработки с ОФ на УФ следует придерживаться следующих правил:

  1. Разделяйте интерфейс и данные: используйте Элементы для визуальных настроек и Объект для работы с данными.
  2. Следите за контекстом: всё, что касается запросов, метаданных (Справочники, Документы, ПланыСчетов) и макетов, должно выполняться под директивой &НаСервере.
  3. Используйте правильные события: заполнение списков выбора и установку начальных значений лучше делать в ПриСозданииНаСервере.
  4. Переносите тяжелую логику в модуль объекта: это позволит вызывать функции обработки без привязки к форме (например, в фоновых заданиях), а в форме использовать РеквизитФормыВЗначение.
  5. Работа со списками выбора: если вы программно добавили значения в СписокВыбора элемента формы, убедитесь, что у элемента установлено свойство РежимВыбораИзСписка, иначе пользователь может не увидеть ваш список.

Соблюдение этих принципов позволит вам создавать стабильные и быстрые управляемые формы, соответствующие стандартам разработки фирмы "1С".

← На главную