В современной розничной торговле вывод информации для покупателя на второй монитор (чека, текущих позиций, скидок, рекламных баннеров и видеороликов) стал стандартом де-факто. Но как реализовать этот функционал на «классической» платформе 1С:Предприятие 7.7, интерфейс которой изначально не проектировался под многомониторные конфигурации? В этой статье мы подробно разберем пять проверенных практических методов решения этой задачи: от самых простых и легковесных до профессиональных отказоустойчивых решений.
Это классический и самый простой в реализации способ, не требующий использования внешних компонент. Суть метода заключается в том, что 1С при любом изменении состава чека генерирует физический HTML-файл на жестком диске. На втором мониторе открывается обычный браузер (например, Internet Explorer в полноэкранном режиме), который настроен на периодическое перечитывание этого файла.
Рассмотрим пошагово, как это реализовать. В заголовке генерируемого HTML-документа мы используем специальный мета-тег, который заставляет браузер обновлять страницу каждые 1-2 секунды.
Пример кода на стороне 1С 7.7 для выгрузки файла чека:
Процедура ОбновитьМониторПокупателя(ТаблицаТоваров)
ТекстHTML = СоздатьОбъект("Текст");
ТекстHTML.ДобавитьСтроку("<html>");
ТекстHTML.ДобавитьСтроку("<head>");
// Указываем автообновление страницы каждую секунду
ТекстHTML.ДобавитьСтроку("<meta http-equiv=""refresh"" content=""1"" />");
ТекстHTML.ДобавитьСтроку("<style>");
ТекстHTML.ДобавитьСтроку("body { font-family: Arial; background-color: #f0f0f0; margin: 20px; }");
ТекстHTML.ДобавитьСтроку(".title { font-size: 24px; color: #333; text-align: center; }");
ТекстHTML.ДобавитьСтроку(".item-table { width: 100%; border-collapse: collapse; margin-top: 20px; }");
ТекстHTML.ДобавитьСтроку(".item-table th { background-color: #ff9900; color: white; padding: 10px; }");
ТекстHTML.ДобавитьСтроку(".item-table td { padding: 10px; border-bottom: 1px solid #ccc; font-size: 18px; }");
ТекстHTML.ДобавитьСтроку(".total { font-size: 32px; font-weight: bold; color: red; text-align: right; margin-top: 20px; }");
ТекстHTML.ДобавитьСтроку("</style>");
ТекстHTML.ДобавитьСтроку("</head>");
ТекстHTML.ДобавитьСтроку("<body>");
ТекстHTML.ДобавитьСтроку("<div class=""title"">Ваша покупка</div>");
ТекстHTML.ДобавитьСтроку("<table class=""item-table"">");
ТекстHTML.ДобавитьСтроку("<tr><th>Наименование</th><th>Кол-во</th><th>Сумма</th></tr>");
ИтогСумма = 0;
ТаблицаТоваров.ВыбратьСтроки();
Пока ТаблицаТоваров.ПолучитьСтроку() = 1 Цикл
ТекстHTML.ДобавитьСтроку("<tr>");
ТекстHTML.ДобавитьСтроку("<td>" + СокрЛП(ТаблицаТоваров.Товар) + "</td>");
ТекстHTML.ДобавитьСтроку("<td>" + ТаблицаТоваров.Количество + "</td>");
ТекстHTML.ДобавитьСтроку("<td>" + Формат(ТаблицаТоваров.Сумма, "Ч015.2") + "</td>");
ТекстHTML.ДобавитьСтроку("</tr>");
ИтогСумма = ИтогСумма + ТаблицаТоваров.Сумма;
КонецЦикла;
ТекстHTML.ДобавитьСтроку("</table>");
ТекстHTML.ДобавитьСтроку("<div class=""total"">ИТОГО: " + Формат(ИтогСумма, "Ч015.2") + " руб.</div>");
ТекстHTML.ДобавитьСтроку("</body></html>");
// Записываем во временную папку
ТекстHTML.Записать(КаталогИБ() + "ExtFiles\customer_display.html");
КонецПроцедуры
Преимущества: предельная простота реализации, отсутствие внешних DLL-библиотек.
Недостатки: неприятное мерцание экрана в момент перезагрузки страницы браузером, повышенный износ твердотельного накопителя (SSD) из-за постоянной перезаписи файлов при быстром сканировании товаров на кассе.
Чтобы избавиться от мерцания экрана и постоянных дисковых операций записи/чтения, проанализируем профессиональный подход — управление запущенным экземпляром Internet Explorer непосредственно из памяти 1С через COM-соединение.
При этом методе мы один раз создаем OLE-объект браузера, позиционируем его окно на координаты второго монитора и далее точечно обновляем HTML-код в памяти процесса, не используя жесткий диск.
Рассмотрим пример реализации:
Перем мБраузер;
Процедура ИнициализироватьВторойМонитор()
Попытка
мБраузер = СоздатьОбъект("InternetExplorer.Application");
// Позиционируем окно на второй монитор (координата X начинается за пределами первого)
мБраузер.Left = 1920; // Предположим, разрешение первого монитора 1920x1080
мБраузер.Top = 0;
мБраузер.Width = 1024;
мБраузер.Height = 768;
мБраузер.MenuBar = 0;
мБраузер.ToolBar = 0;
мБраузер.StatusBar = 0;
мБраузер.AddressBar = 0;
мБраузер.Visible = 1;
// Открываем пустую страницу
мБраузер.Navigate("about:blank");
// Ожидаем завершения инициализации документа
Пока мБраузер.ReadyState <> 4 Цикл
// В 1С 7.7 нет штатной функции сна, используем пустой цикл или внешнюю компоненту
КонецЦикла;
Исключение
Предупреждение("Не удалось запустить дисплей покупателя: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ОбновитьДанныеНаМониторе(ТекстСообщения, СуммаЧека)
Если ПустоеЗначение(мБраузер) = 1 Тогда
Возврат;
КонецЕсли;
// Формируем чистый HTML-код для записи в DOM
HTMLКод = "<html><body style='background:black; color:lime; font-family:monospace; font-size:24px; text-align:center;'>"
+ "<h1>" + ТекстСообщения + "</h1>"
+ "<div style='font-size:48px; font-weight:bold;'>К ОПЛАТЕ: " + СуммаЧека + " руб.</div>"
+ "</body></html>";
// Пишем напрямую в открытый документ браузера в памяти
мБраузер.Document.open();
мБраузер.Document.write(HTMLКод);
мБраузер.Document.close();
КонецПроцедуры
Преимущества: отсутствие работы с жестким диском, мгновенное обновление информации, гибкое позиционирование окна браузера.
В практике автоматизации торговых точек часто применяются специализированные утилиты, предназначенные для создания полноэкранного дисплея покупателя. Одной из наиболее популярных программ этого класса является CashDisplay (или ее аналоги с Инфостарта).
Данные программы работают по следующей схеме:
CashDisplay.Application) или отслеживает появление определенного текстового/XML/JSON файла в локальном каталоге обмена.Пример интеграции через COM-объект утилиты в 1С 7.7:
Попытка
Дисплей = СоздатьОбъект("CashDisplay.Application");
Дисплей.Очистить();
Дисплей.ДобавитьСтрокуТовара("Шоколад Аленка", 2, 85.50);
Дисплей.ДобавитьСтрокуТовара("Кока-Кола 0.5л", 1, 90.00);
Дисплей.ПоказатьИтого(261.00);
Исключение
Сообщить("Специализированная программа дисплея покупателя не запущена!");
КонецПопытки;
Интерфейс 1С 7.7 построен по архитектуре MDI (Multiple Document Interface), где все открытые окна (документы, справочники, отчеты) жестко ограничены рамками главного окна программы. Просто перетащить форму «ЭкранПокупателя» за пределы главного окна на второй монитор штатными средствами невозможно.
Для преодоления этого ограничения продвинутые разработчики используют вызовы функций Windows API с помощью известных внешних компонент FormEx или 1С++. С помощью WinAPI мы можем принудительно изменить стиль любого окна 1С, сделав его «свободным» (всплывающим) окном операционной системы, а затем переместить его по координатам второго монитора.
Разберем этот алгоритм работы:
SetWindowLong удаляем у окна стиль WS_CHILD (дочернее окно) и устанавливаем стиль WS_POPUP (всплывающее окно).SetParent, отвязываем окно от главного окна 1С (делаем его родителем рабочий стол Desktop).MoveWindow или SetWindowPos перемещаем форму на второй монитор.В результате на втором мониторе будет отображаться стандартная, родная форма 1С 7.7, данные на которой кассир может обновлять простым переопределением реквизитов формы и вызовом метода Форма.Обновить().
Если на кассовом узле используется высоконагруженная база данных и критически важно, чтобы процессы обновления второго экрана не тормозили работу кассира (что часто бывает при COM-соединениях или тяжелых дисковых операциях), применяется наиболее современная и стабильная схема взаимодействия.
Архитектура решения состоит из трех звеньев:
Для отправки запросов из 1С 7.7 используется системный объект Windows MSXML2.XMLHTTP или библиотека WinHttp.WinHttpRequest:
Процедура ОтправитьДанныеНаСервер(СтрокаJSON)
Попытка
Http = СоздатьОбъект("MSXML2.XMLHTTP");
Http.open("POST", "http://localhost:8080/update_screen", 0); // 0 - асинхронный режим, чтобы не вешать 1С
Http.setRequestHeader("Content-Type", "application/json");
Http.send(СтрокаJSON);
Исключение
Сообщить("Ошибка отправки данных на дисплей покупателя: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Локальный сервер мгновенно принимает этот JSON и транслирует его в открытый веб-интерфейс на втором мониторе по протоколу WebSockets. Страница на втором мониторе плавно, красиво, с использованием современных CSS-анимаций отображает позиции чека и крутит рекламные баннеры без малейших задержек интерфейса самой 1С.
Выбор конкретного метода зависит от технических условий проекта и квалификации разработчика:
InternetExplorer.Application через COM-соединение (Вариант 2).