При переходе на новые версии платформы 1С:Предприятие 8.3 (начиная с 8.3.15 и выше) разработчики часто сталкиваются с ситуацией, когда старый код, исправно работавший годами, внезапно начинает выдавать ошибку «Интерактивные операции недоступны». Особенно остро эта проблема проявляется в конфигурациях на обычных формах, таких как Управление торговлей 10.3, УПП 1.3 или Бухгалтерия 2.0. Рассмотрим ситуацию, когда регламентное задание пытается программно открыть форму документа через ПолучитьФорму и выполнить в ней какие-либо действия.
Проанализируем механику работы платформы. В старых версиях (например, 8.3.13) при работе в режиме обычного приложения платформа допускала определенные вольности. Даже если код выполнялся в фоновом задании на сервере, вызов метода ПолучитьФорму иногда мог «пройти» без ошибки, если в модуле формы не было явных обращений к графическому интерфейсу при инициализации. Однако, начиная с версии 8.3.15, компания 1С существенно ужесточила изоляцию серверных процессов.
Выясним главную причину: регламентные (фоновые) задания всегда выполняются на сервере в неинтерактивном сеансе. В таком сеансе графическая подсистема не инициализируется. У сервера нет «экрана», на котором можно было бы отрисовать форму, и нет «пользователя», который мог бы нажать на кнопки. Как только платформа встречает вызов ПолучитьФорму, ОткрытьФорму, Предупреждение или Вопрос в контексте серверного задания, она немедленно генерирует исключение, так как эти операции требуют интерактивного взаимодействия.
Посмотрим на типичное заблуждение, связанное с полем «Ключ» в свойствах регламентного задания. Попытка прописать там параметры запуска, такие как /RunModeOrdinaryApplication, технически ошибочна. Это поле предназначено исключительно для управления уникальностью выполнения заданий (чтобы не запускать два одинаковых процесса одновременно) и никак не влияет на режим работы приложения или доступность интерфейсных методов.
Это самый правильный и архитектурно верный путь. Если в регламентном задании требуется выполнить процедуру, которая сейчас находится в модуле формы (например, ЗаписатьВФорме), нам необходимо отвязать эту логику от интерфейса. Проанализируем, что именно делает эта процедура. Скорее всего, она заполняет какие-то реквизиты объекта и вызывает метод Записать.
Разберем по шагам, как перенести логику:
ЭлементыФормы, ЭтаФорма, ТекущийЭлемент).Рассмотрим пример кода до изменения (в регламентном задании):
// ТАК ДЕЛАТЬ НЕЛЬЗЯ НА НОВЫХ ПЛАТФОРМАХ
ДокСсылка = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("001");
Форма = ДокСсылка.ПолучитьФорму("ФормаДокумента"); // Здесь произойдет ошибка
Форма.ЗаписатьВФорме();
Проанализируем правильный вариант реализации. Сначала переносим код в модуль объекта документа:
// В модуле объекта документа
Процедура ВыполнитьРегламентнуюЗапись() Экспорт
// Логика, которая раньше была в форме
ЭтотОбъект.Комментарий = "Обновлено регламентным заданием " + ТекущаяДата();
// Выполняем запись без участия интерфейса
ЭтотОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецПроцедуры
Затем изменим код самого регламентного задания:
// В модуле, где выполняется регламентное задание
ДокСсылка = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("001");
ДокОбъект = ДокСсылка.ПолучитьОбъект();
// Вызываем метод объекта напрямую, без открытия форм
ДокОбъект.ВыполнитьРегламентнуюЗапись();
Если код в форме настолько сложен (так называемый «спагетти-код»), что его невозможно вынести без риска сломать логику, или если конфигурация находится на поддержке и изменения крайне нежелательны, можно прибегнуть к методу эмуляции интерактивного присутствия.
Суть метода заключается в отказе от стандартного механизма регламентных заданий 1С в пользу Планировщика задач Windows (Task Scheduler). Рассмотрим этот алгоритм подробнее:
AutoWork.epf).ПриОткрытии (или ПередОткрытием для обычных форм) пропишем вызов тех самых «запретных» методов получения формы и выполнения действий. В конце обязательно добавим ЗавершитьРаботуСистемы(Ложь).Пример строки запуска для планировщика:
"C:\Program Files\1cv8\8.3.16.1224\bin\1cv8.exe" ENTERPRISE /F "D:\Base1C" /N "RobotUser" /P "Password" /Execute "D:\Scripts\AutoWork.epf"
В этом случае платформа запустит полноценный сеанс Толстого клиента. В таком сеансе графическая оболочка инициализирована, поэтому вызовы ПолучитьФорму и любые интерактивные операции будут доступны без ограничений, так как система считает, что за компьютером сидит реальный пользователь.
Выясним причину нестабильности, которую описывают пользователи. В платформе 8.3.16 механизмы оптимизации компиляции модулей могут вести себя по-разному в зависимости от состояния кэша сервера приложений. Если форма простая и при ее создании не происходит обращения к свойствам окна Windows, защита может не сработать мгновенно. Однако, как только код обращается к любому объекту, требующему отрисовки или контекста рабочего стола, система пресекает выполнение.
Важный момент: использование режима Обычное приложение не делает серверный сеанс интерактивным. Это лишь способ интерпретации кода и метаданных. Поэтому единственный надежный способ работы в фоновых заданиях — это полное исключение работы с объектами метаданных типа Форма.
Мы проанализировали ситуацию и пришли к выводу, что поведение платформы 8.3.16 — это не баг, а приведение системы к задокументированным стандартам безопасности и производительности.
Подведем итоги по выбору решения:
Помните, что использование ПолучитьФорму на сервере всегда было плохой практикой (anti-pattern), и новые версии платформы просто заставляют разработчиков писать более качественный и разделенный код. Для поиска интерактивных вызовов и нарушений стандартов платформы в модулях можно использовать инструмент для проверки кода по стандартам БСП и платформы.