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