Многие разработчики при сопровождении решений для розничной торговли (РМК в Комплексной автоматизации 2.2, УТ 11 или Рознице) сталкиваются со странным поведением интерфейса. Ситуация выглядит следующим образом: после нажатия кнопки пробития чека и автоматической отправки печатных форм на принтер, основное окно программы перестает реагировать на любые действия пользователя. Кнопки не нажимаются, поля ввода недоступны, перейти в другой раздел невозможно. При этом 1С не «висит» в привычном понимании: внешние события (например, сканирование штрихкода) продолжают обрабатываться, и товары добавляются в чек. Если же попытаться закрыть программу через «крестик» и нажать «Отмена» в системном диалоге, интерфейс внезапно «оживает».
В этой статье мы подробно разберем, почему возникает этот эффект «невидимой блокировки», проанализируем технические причины и рассмотрим проверенные способы решения проблемы.
Основная причина такого поведения кроется не в ошибках программного кода конфигурации, а в особенностях работы определенных релизов платформы 1С:Предприятие 8.3.12 (в частности, 8.3.12.1412, 8.3.12.1469) и ранних сборок 8.3.13. Проблема связана с некорректной передачей фокуса между окнами при вызове метода Напечатать().
Выясним, что происходит на системном уровне. Когда мы вызываем печать из формы, открытой в режиме блокирования всего интерфейса (что типично для рабочего места кассира), платформа создает системный диалог или скрытое окно для взаимодействия с драйвером принтера. В проблемных версиях платформы после завершения задания на печать это окно не уничтожается полностью. Оно остается в стеке графических сообщений Windows как прозрачный слой поверх формы 1С. Именно этот слой перехватывает все клики мышкой, создавая ощущение, что программа «ушла в несознанку». Внешние же события, такие как сигналы от сканера штрихкодов, поступают напрямую в объект формы, минуя очередь графических сообщений мыши, поэтому они продолжают работать.
Первым делом проанализируем версию платформы, установленную у клиента. Если вы видите релизы 8.3.12.1412–1469, то самым правильным и стабильным решением будет обновление. Ошибка была официально признана вендором и исправлена в более поздних сборках.
Рекомендуется переход на следующие ветки (или выше):
Если оперативно обновить платформу невозможно (например, из-за требований совместимости с другими системами), рассмотрим программные способы «расклинивания» формы. Нам нужно заставить платформу принудительно перерисовать окна и сбросить ошибочный фокус. Рассмотрим несколько вариантов кода.
Использование обработчика ожидания
Это один из самых эффективных методов. Мы выносим действие, следующее за печатью, в отдельную процедуру, которая вызывается с минимальной задержкой. Это разрывает поток выполнения и заставляет систему корректно обработать очередь сообщений.
&НаКлиенте
Процедура ПослеПечатиИПробития()
// Основной код печати
ТабличныйДокумент.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
// Вместо немедленного открытия нового чека, подключаем обработчик
ПодключитьОбработчикОжидания("ПринудительнаяАктивацияФормы", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ПринудительнаяАктивацияФормы()
// Это действие заставит платформу вернуть фокус на форму РМК
ЭтаФорма.Активизировать();
КонецПроцедуры
Вызов метода Оповестить
Иногда помогает отправка глобального оповещения сразу после метода печати. Это инициирует обновление связанных форм и может «пробить» зависший слой.
Если ТабличныйДокумент <> Неопределено Тогда
ТабличныйДокумент.Напечатать(РежимИспользованияДиалогаПечати.Использовать);
// Принудительное уведомление системы
Оповестить("ЗавершениеПечатиЧека", ПараметрКоманды);
КонецЕсли;
Разберем ситуацию с выбором принтера. Практика показывает, что баг проявляется значительно чаще, если используется параметр РежимИспользованияДиалогаПечати.Использовать. Когда кассиру выводится стандартное окно выбора принтера Windows, вероятность «зависания» интерфейса 1С после его закрытия возрастает в разы.
Посмотрим, как можно оптимизировать этот процесс. Рекомендуется программно устанавливать имя принтера в настройках табличного документа и печатать напрямую, без вывода лишних окон:
ТабДок = Новый ТабличныйДокумент;
// ... заполнение табдока ...
ТабДок.ИмяПринтера = "ИмяВашегоПринтераЧеков";
ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
Если имя принтера заранее неизвестно, лучше реализовать собственную мини-форму выбора принтера в 1С или сохранять выбор пользователя в настройках (хранилище настроек), чем вызывать системный диалог платформы.
Проанализируем влияние внешних факторов. Иногда 1С ждет ответа от графической подсистемы Windows, которая, в свою очередь, ждет ответа от принтера. Если принтер чеков настроен на «двусторонний обмен данными», это может затягивать процесс закрытия сессии печати.
Попробуем выполнить следующие действия:
Мы выяснили, что эффект «несознанки» формы РМК — это специфический баг управления фокусом в платформе 8.3.12. Если вы столкнулись с этим:
Эти шаги позволят восстановить стабильную работу кассового узла и избавят пользователей от необходимости перезагружать 1С после каждого пробитого чека.