Как воспроизвести звук при ошибках в 1С 8.3 на управляемых формах

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейса управляемых форм в 1С:Предприятие 8.3 часто возникает необходимость привлечь внимание пользователя звуковым сигналом — например, при ошибке сканирования штрихкода, неверном вводе данных или сбое проведения документа. Разберем распространенную проблему, когда разработчики пытаются запустить воспроизведение звука прямо из серверного контекста, и проанализируем правильные архитектурные подходы к решению этой задачи.

Выясним причину ошибки: почему звук не работает на сервере

Рассмотрим ситуацию, с которой столкнулся автор темы. В коде управляемой формы выполняется процедура с директивой &НаСервере, внутри которой совершается попытка вызова COM-объекта ОС Windows для проигрывания аудиофайла:


файлз = "C:\Windows\Media\tada.wav";
oVoice = Новый COMObject("SAPI.SpVoice");
oSpFileStream = Новый COMObject("SAPI.SpFileStream");
oSpFileStream.Open(файлз);
oVoice.SpeakStream(oSpFileStream);
oSpFileStream.Close();

При попытке выполнить данный код на стороне сервера возникает исключительная ситуация (в частности, ошибка вида 0x8004503A). Это происходят по следующим причинам:

  1. Разделение контекстов: Серверный код 1С исполняется в отдельном процессе службы кластера 1С:Предприятия. На сервере отсутствуют интерактивный сеанс пользователя и инициализированное устройство вывода звука.
  2. Отсутствие оборудования: Физический сервер или виртуальная машина в серверной стойке не имеет звуковой карты, либо служба аудио отключена на уровне операционной системы.
  3. Безопасность и кроссплатформенность: Использование COM-объектов SAPI.SpVoice жестко привязано к ОС Windows и работает исключительно в клиентском контексте тонкого клиента на ОС Windows. На сервере Linux или в веб-клиенте такой код вызовет фатальную ошибку.

Решение проблемы: разделение серверной и клиентской логики

Для корректной работы звуковых оповещений перенесем момент воспроизведения на сторону клиента. Если обработка данных выполняется на сервере, процедуру следует переработать в функцию, которая возвращает результат на клиент.

Рассмотри пошаговый алгоритм реализации данного подхода:

Шаг 1. Перерабатываем серверную процедуру в функцию

Сформируем на сервере структуру, содержащую флаг успеха и текст сообщения об ошибке (если она возникла):


&НаСервере
Функция ОбработатьДанныеНаСервере(Знач ПараметрОбработки)
    Результат = Новый Структура;
    Результат.Вставить("Успех", Истина);
    Результат.Вставить("ТекстОшибки", "");

    Попытка
        // Выполняем бизнес-логику (например, проведение или проведение проверок)
        // ...
    Исключение
        Результат.Успех = Ложь;
        Результат.ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;

    Возврат Результат;
КонецФункции

Шаг 2. Обрабатываем результат на клиенте и воспроизводим звук

В клиентском обработчике проверяем полученный результат. В случае неудачи вызываем процедуру воспроизведения звукового сигнала:


&НаКлиенте
Процедура ВыполнитьОперацию(Команда)
    Результат = ОбработатьДанныеНаСервере(Элементы.ПолеВвода.Значение);
    
    Если Не Результат.Успех Тогда
        // Вызываем воспроизведение звука на клиенте
        ВоспроизвестиЗвукОшибки();
        ПоказатьОповещениеПользователю(Результат.ТекстОшибки);
    КонецЕсли;
КонецПроцедуры

Способы воспроизведения звука на стороне клиента

Рассмотрим основные варианты реализации функции ВоспроизвестиЗвукОшибки() на клиенте в зависимости от требований к системе.

Способ 1. Использование встроенной функции Сигнал()

Самый простой и стандартный способ, доступный на клиенте в платформе 1С:Предприятие. Функция выдает короткий системный звук операционной системы без необходимости подключать внешние файлы:


&НаКлиенте
Процедура ВоспроизвестиЗвукОшибки()
    Сигнал();
КонецПроцедуры

Способ 2. Кроссплатформенное воспроизведение через поле HTML-документа

Если требуется воспроизвести конкретный аудиофайл (WAV или MP3) и обеспечить работу как в Тонком клиенте, так и в Веб-клиенте на любых ОС (Windows, Linux, macOS), можно задействовать элемент формы «Поле HTML документа» или динамически проиграть звук с помощью JavaScript.

Аудиофайл сохраняется в макет двоичных данных, переводится в Base64 и передается в HTML-тег <audio> с атрибутом autoplay:


&НаКлиенте
Процедура ПроигратьЗвукИзМакета(Знач ДвоичныеДанныеЗвука)
    // Преобразуем двоичные данные в Base64 для передачи в HTML
    СтрокаBase64 = СтрокаBase64(ДвоичныеДанныеЗвука);
    HTMLТекст = "<html><body>
    |<audio autoplay src=""data:audio/wav;base64," + СтрокаBase64 + """/>
    |</body></html>";
    
    // Присваиваем сформированный текст полю HTML на форме
    Элементы.ПолеHTMLЗвук.Документ.write(HTMLТекст);
КонецПроцедуры

Способ 3. Запуск фонового скрипта через ЗапуститьПриложение() (для Windows)

В тонком клиенте Windows можно запустить фоновую команду PowerShell для проигрывания системного файла без появления сторонних окон:


&НаКлиенте
Процедура ВоспроизвестиЗвукЧерезPowerShell()
    Команда = "powershell -c ""(New-Object Media.SoundPlayer 'C:\Windows\Media\tada.wav').PlaySync()""";
    ЗапуститьПриложение(Команда, , Истина);
КонецПроцедуры

Способ 4. Воспроизведение на мобильных устройствах

Если приложение используется на мобильном клиенте или мобильной платформе, для работы со звуком применяют встроенный объект СредстваМультимедиа:


&НаКлиенте
Процедура ВоспроизвестиЗвукНаМобильном()
    #Если МобильныйКлиент Или МобильноеПриложениеКлиент Тогда
        СредстваМультимедиа.ВоспроизвестиЗвуковоеОповещение();
    #КонецЕсли
КонецПроцедуры

Оптимизация архитектуры при большом количестве проверок

Проанализируем ситуацию, когда в конфигурации присутствует множество мест, где могут возникать ошибки. Чтобы не дублировать код в каждой форме, рекомендуется соблюдать следующие правила:

  1. Создайте клиентский общий модуль: Вынесите логику проигрывания звука и вывода уведомлений об ошибках в отдельный общий модуль с установленным флагом «Клиент (управляемое приложение)», например ЗвукОповещенияКлиент.
  2. Используйте функции-обертки: Вызывайте серверные функции из единых клиентских процедур, которые централизованно проверяют результат выполнения и воспроизводят звук при ошибке.
  3. Обрабатывайте события торгового оборудования: В решениях для складов или магазинов воспроизводите звук ошибки непосредственно в клиентском обработчике ОбработкаВнешнегоСобытия сразу после получения негативного ответа от сервера.
← На главную