При разработке дополнительных форм для Рабочего Места Кассира (РМК) в 1С:Розница часто возникает необходимость подключить и обработать штрихкод со сканера. Стандартное подключение сканера к основной форме РМК может не работать корректно в новой, дополнительной форме, особенно если эта форма является модальной или блокирующей. Рассмотрим, как правильно настроить обработку штрихкодов в такой ситуации.
Основная проблема заключается в том, что события от подключенного оборудования, такого как сканер штрихкода, по умолчанию направляются в ту форму, которая была активна в момент подключения или имеет кэшированную привязку к оборудованию. Если вы открываете новую дополнительную форму, особенно поверх основной, система может продолжать отправлять события в основную форму, игнорируя новую. Чтобы решить эту задачу, нам потребуется явным образом управлять подключением сканера к конкретной форме.
Первоначально автор столкнулся с вопросом, в какой процедуре следует получать штрихкод после его сканирования. Многие разработчики, особенно начинающие, пытаются найти специфичные процедуры по типу ОповещениеПоискаПоШтрихкоду. Однако в современных конфигурациях 1С, использующих "Библиотеку подключаемого оборудования" (БПО), для получения данных от сканера штрихкода предназначен универсальный обработчик формы: ОбработкаОповещения.
Эта процедура должна присутствовать в модуле той формы, которая должна принимать данные со сканера. Она является универсальным механизмом для получения различных событий от подключенного оборудования. Разберем ее структуру:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ScanData" Тогда
// Событие "ScanData" указывает на то, что были получены данные со сканера штрихкода.
// Параметр[0] содержит сам штрихкод.
Штрихкод = Параметр[0];
// Далее следует ваш код для обработки полученного штрихкода.
// Например, вы можете вывести его или использовать для поиска товара.
Сообщить("Получен штрихкод в дополнительной форме: " + Штрихкод);
// Пример использования: Поиск товара по штрихкоду.
// Допустим, у нас есть функция на сервере для поиска.
// НачатьПоискТовараПоШтрихкодуНаСервере(Штрихкод);
КонецЕсли;
// Можно обрабатывать и другие события оборудования, если это необходимо.
// Например, события от фискального регистратора или весов.
// Если ИмяСобытия = "FiscalData" Тогда
// ...
// КонецЕсли;
КонецПроцедуры
Важно: Процедура ОбработкаОповещения должна быть размещена в модуле той формы, которая в данный момент должна быть "слушателем" событий от сканера. Если сканер подключен к форме, но в ее модуле нет этой процедуры, или она не обрабатывает ИмяСобытия = "ScanData", то штрихкод не будет перехвачен.
Как верно подметили в обсуждении, основная загвоздка при работе со сканером в дополнительных формах РМК заключается в том, что события от оборудования продолжают приходить в основную форму. Это происходит потому, что сканер был инициализирован и подключен к основной форме, и система "помнит" ее как основного получателя событий. Для корректной работы нам потребуется вручную "переключать" сканер между формами.
Рассмотрим пошаговый алгоритм действий для обеспечения бесперебойной работы со сканером в дополнительной форме:
Прежде чем открыть дополнительную форму, нам необходимо "освободить" сканер от привязки к основной форме РМК. Это гарантирует, что события не будут уходить в "никуда" (или в неактивную форму РМК) во время работы дополнительной формы. Отключение производится при помощи МенеджерОборудованияКлиент.ОтключитьОборудованиеОтФормы().
Этот код следует разместить в той процедуре основной формы РМК, которая отвечает за открытие дополнительной формы (например, в обработчике нажатия кнопки).
&НаКлиенте
Процедура ОткрытьДополнительнуюФормуИОтключитьСканер()
// Отключаем сканер от текущей формы, чтобы он не перехватывал события,
// пока активна дополнительная форма.
МенеджерОборудованияКлиент.ОтключитьОборудованиеОтФормы(ЭтотОбъект, "СканерШтрихкода");
// Определяем описание оповещения, которое будет вызвано после закрытия дополнительной формы.
// Это нужно, чтобы мы могли снова подключить сканер к РМК.
ОповещениеОЗакрытииФормы = Новый ОписаниеОповещения("ПослеЗакрытияДополнительнойФормы", ЭтотОбъект);
// Открываем дополнительную форму.
// Если форма модальная, можно использовать ОткрытьФормуМодально,
// но в управляемом приложении чаще используют ОткрытьФорму с оповещением.
ОткрытьФорму("Обработка.МояДополнительнаяФорма.Форма.Форма", , ЭтотОбъект, , , , ОповещениеОЗакрытииФормы);
КонецПроцедуры
Или, если вы используете модальный вызов (что не рекомендуется, но иногда бывает):
&НаКлиенте
Процедура ОткрытьДополнительнуюФормуМодально()
// Отключаем сканер перед модальным открытием
МенеджерОборудованияКлиент.ОтключитьОборудованиеОтФормы(ЭтотОбъект, "СканерШтрихкода");
// Модальное открытие формы
ОткрытьФормуМодально("Обработка.МояДополнительнаяФорма.Форма.Форма");
// После закрытия модальной формы, сразу подключаем сканер обратно.
// В случае модального открытия, оповещение не требуется, т.к. код ждет закрытия.
ПодключитьСканерКОсновнойФорме();
КонецПроцедуры
&НаКлиенте
Процедура ПодключитьСканерКОсновнойФорме()
ОповещенияПриПодключении = Новый ОписаниеОповещения("ПодключитьОборудованиеЗавершение", ЭтотОбъект);
МенеджерОборудованияКлиент.НачатьПодключениеОборудованиеПриОткрытииФормы(
ОповещенияПриПодключении,
ЭтотОбъект,
"СканерШтрихкода");
КонецПроцедуры
В процедуре ПриОткрытии или ПослеОткрытия дополнительной формы необходимо инициировать подключение сканера именно к этой форме. Это позволит ей стать активным получателем событий от сканера.
// Модуль дополнительной формы (например, Обработка.МояДополнительнаяФорма.Форма.Форма)
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Инициируем асинхронное подключение сканера к ЭТОЙ форме.
// "СканерШтрихкода" - это тип оборудования, который мы хотим подключить.
ОповещенияПриПодключении = Новый ОписаниеОповещения("ПодключитьОборудованиеЗавершениеДополнительнаяФорма", ЭтотОбъект);
МенеджерОборудованияКлиент.НачатьПодключениеОборудованиеПриОткрытииФормы(
ОповещенияПриПодключении,
ЭтотОбъект,
"СканерШтрихкода");
// Здесь же можно вызвать обновление команд, если в форме есть кнопки,
// связанные с подключаемым оборудованием.
ПодключаемыеКомандыКлиент.НачатьОбновлениеКоманд(ЭтотОбъект);
КонецПроцедуры
&НаКлиенте
Процедура ПодключитьОборудованиеЗавершениеДополнительнаяФорма(ПодключенныеОбъектыОборудования, ДополнительныеПараметры) Экспорт
// Это обработчик завершения асинхронного подключения.
// Здесь мы можем убедиться, что сканер действительно подключен.
Если ПодключенныеОбъектыОборудования.Количество() > 0 Тогда
Сообщить("Сканер успешно подключен к дополнительной форме.");
Иначе
Сообщить("Не удалось подключить сканер к дополнительной форме.");
КонецЕсли;
КонецПроцедуры
Важно: Убедитесь, что в этой же дополнительной форме присутствует процедура ОбработкаОповещения, как описано выше, для фактического получения штрихкода.
Как только сканер будет подключен к дополнительной форме, все события "ScanData" будут приходить в процедуру ОбработкаОповещения этой формы. Здесь вы можете реализовать необходимую логику: поиск товара, добавление его в табличную часть, изменение количества и т.д.
// Модуль дополнительной формы
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ScanData" Тогда
Штрихкод = Параметр[0];
Если НЕ ПустаяСтрока(Штрихкод) Тогда
Сообщить("Штрихкод '" + Штрихкод + "' получен в дополнительной форме. Начинаем обработку...");
// Пример: Вызов серверной функции для поиска и обработки штрихкода
// Например, если у вас есть табличная часть на форме, вы можете добавить туда товар
// ОбработатьШтрихкодНаСервере(Штрихкод);
// Или, если вся логика на клиенте
// НайтиИДобавитьТоварВТаблицу(Штрихкод);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Перед закрытием дополнительной формы крайне важно "освободить" сканер от ее привязки. Это позволит нам снова подключить его к основной форме РМК без конфликтов. Используем для этого процедуру ПриЗакрытии дополнительной формы.
// Модуль дополнительной формы
&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
// Отключаем сканер от этой формы, чтобы основная форма могла его использовать.
МенеджерОборудованияКлиент.ОтключитьОборудованиеОтФормы(ЭтотОбъект, "СканерШтрихкода");
Сообщить("Сканер отключен от дополнительной формы.");
КонецПроцедуры
После закрытия дополнительной формы (и, следовательно, после отключения от нее сканера), мы должны снова подключить сканер к основной форме РМК, чтобы продолжить работу в штатном режиме. Это делается в обработчике оповещения, который мы передали при открытии дополнительной формы.
// Модуль основной формы РМК
&НаКлиенте
Процедура ПослеЗакрытияДополнительнойФормы(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
// Вызывается после того, как дополнительная форма была закрыта.
// Теперь мы можем снова подключить сканер к основной форме.
ОповещенияПриПодключении = Новый ОписаниеОповещения("ПодключитьОборудованиеЗавершение", ЭтотОбъект);
МенеджерОборудованияКлиент.НачатьПодключениеОборудованиеПриОткрытииФормы(
ОповещенияПриПодключении,
ЭтотОбъект,
"СканерШтрихкода");
Сообщить("Сканер повторно подключен к основной форме РМК.");
// Это обработчик, который вызывается после завершения подключения к основной форме.
// Можно использовать его для проверки успешности.
КонецПроцедуры
&НаКлиенте
Процедура ПодключитьОборудованиеЗавершение(ПодключенныеОбъектыОборудования, ДополнительныеПараметры) Экспорт
Если ПодключенныеОбъектыОборудования.Количество() > 0 Тогда
Сообщить("Сканер успешно подключен к основной форме РМК.");
Иначе
Сообщить("Не удалось повторно подключить сканер к основной форме РМК.");
КонецЕсли;
КонецПроцедуры
НачатьПодключениеОборудованиеПриОткрытииФормы), так как работа с оборудованием может занимать время и блокировать интерфейс пользователя. Всегда используйте ОписаниеОповещения для обработки результатов."СканерШтрихкода"), соответствует типу оборудования, зарегистрированному в вашей системе через подсистему "Подключаемое оборудование".Сообщить()) для контроля хода выполнения и проверки, какие формы получают события и в какой момент происходит подключение/отключение.Таким образом, проблема обработки штрихкодов в дополнительных формах РМК решается не поиском "особой" процедуры для сканера, а правильным и явным управлением жизненным циклом подключения сканера к конкретной форме. Этот подход позволяет нам избежать конфликтов и обеспечивает стабильную работу с оборудованием в сложных пользовательских сценариях.