В практике разработчика 1С нередко возникает задача автоматизации определенных действий. Например, нужно запустить систему под определенным пользователем, выполнить обработку данных и сразу закрыть сеанс, чтобы он не занимал лицензию и не мешал другим процессам. Часто это реализуется через передачу ключа /C в строке запуска. Однако при использовании Библиотеки стандартных подсистем (БСП) или сложных кастомных конфигураций стандартные методы закрытия могут вести себя непредсказуемо. Разберем подробно, как правильно организовать выход из системы на этапе ее старта.
Рассмотрим ситуацию, когда разработчик прописывает логику в модуле управляемого приложения. Основная сложность заключается в том, что процедура ПриНачалеРаботыСистемы выполняется тогда, когда интерфейс уже практически инициализирован. Если в этот момент вызвать ЗавершитьРаботуСистемы(Ложь), платформа может проигнорировать этот вызов или вступить в конфликт с механизмами БСП, которые в это же время могут проверять наличие обновлений, легальность программы или выполнять другие регламентные операции.
Проанализируем типичный сценарий: вы запускаете систему, парсите ПараметрЗапуска, вызываете свою функцию и пытаетесь закрыть приложение. Но вместо закрытия окно программы «моргает» или остается открытым. Это происходит потому, что ЗавершитьРаботуСистемы() — это «мягкий» метод. Он инициирует штатное завершение, которое может быть прервано любым другим обработчиком, ожидающим взаимодействия с пользователем или выполняющим асинхронные вызовы.
Выясним причину, по которой стоит обратить внимание на событие ПередНачаломРаботыСистемы. Это самое первое клиентское событие при запуске. У него есть критически важный параметр — Отказ.
Рассмотрим пример кода, который позволяет завершить работу максимально корректно еще до отрисовки интерфейса:
Процедура ПередНачаломРаботыСистемы(Отказ)
Если СтрНайти(ПараметрЗапуска, "ВыполнитьЗадачуИВыйти") > 0 Тогда
// Выполняем действия, не требующие открытых форм
ОбработатьДанныеПоПараметру();
// Устанавливаем Отказ в Истина, чтобы система не продолжила запуск
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Преимущество этого метода: пользователь даже не увидит основного окна программы. Это самый «чистый» способ завершения. Однако у него есть минус: на этом этапе еще не все подсистемы БСП могут быть инициализированы. Если ваша обработка требует работы с экранными формами или сложными клиентскими механизмами, этот метод может не подойти.
Если логика требует выполнения именно в ПриНачалеРаботыСистемы, то вместо мягкого завершения стоит использовать метод ПрекратитьРаботуСистемы(). Посмотрим на разницу: в отличие от ЗавершитьРаботуСистемы(), данный метод закрывает приложение немедленно, не вызывая обработчики ПриЗавершенииРаботыСистемы и не задавая лишних вопросов.
Разберем пример реализации в модуле управляемого приложения:
Процедура ПриНачалеРаботыСистемы()
// Вызов стандартных обработчиков БСП (если используются)
СтандартныеПодсистемыКлиент.ПриНачалеРаботыСистемы();
Если ПараметрЗапуска = "НужныйНамПараметр" Тогда
// Выполняем регламентную логику
ЗапуститьСлужебнуюОбработку();
// Подавляем подтверждение выхода для БСП
СтандартныеПодсистемыКлиент.ПропуститьПредупреждениеПередЗавершениемРаботыСистемы();
// Жесткое прекращение работы
ПрекратитьРаботуСистемы();
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию с БСП подробнее. В современных конфигурациях Библиотека стандартных подсистем часто перехватывает управление. Если вы просто напишете ЗавершитьРаботуСистемы(), БСП может решить, что есть «незавершенные дела» (например, не показано окно новостей или не проверена почта) и заблокирует закрытие. Именно поэтому вызов ПрекратитьРаботуСистемы() в сочетании с методом ПропуститьПредупреждениеПередЗавершениемРаботыСистемы() является наиболее надежным решением.
Рассмотрим ситуацию с другой стороны. Если вам нужно просто выполнить код и закрыться, возможно, не стоит менять модуль управляемого приложения вовсе. В 1С есть штатный механизм запуска внешней обработки через ключ командной строки /Execute <Путь к файлу>.
Посмотрим, как это работает по шагам:
.epf).ПриОткрытии пишем необходимый код.ЗавершитьРаботуСистемы(Ложь);.1cv8.exe /C "параметры" /Execute "C:\Scripts\MyTask.epf".В этом случае платформа сама откроет обработку, выполнит код и закроется. Это позволяет избежать «замусоривания» основного кода конфигурации служебными проверками, которые нужны только для одного конкретного сценария автоматизации.
Проанализируем несколько технических моментов, которые помогут избежать ошибок:
ЗавершитьРаботуСистемы() и ПрекратитьРаботуСистемы() доступны только на клиенте. Попытка вызвать их в серверном коде приведет к ошибке компиляции.-Visible- (если позволяет тип клиента). Это предотвратит визуальную отрисовку интерфейса и ускорит работу.Подводя итог, можно сказать: если вам нужно «тихое» завершение до старта — используйте Отказ = Истина в ПередНачаломРаботыСистемы. Если же работа требует полной инициализации системы — используйте ПрекратитьРаботуСистемы() в ПриНачалеРаботыСистемы, предварительно отключив предупреждения БСП.