При разработке интерфейса управляемых форм в 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). Это происходят по следующим причинам:
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. Воспроизведение на мобильных устройствах
Если приложение используется на мобильном клиенте или мобильной платформе, для работы со звуком применяют встроенный объект СредстваМультимедиа:
&НаКлиенте
Процедура ВоспроизвестиЗвукНаМобильном()
#Если МобильныйКлиент Или МобильноеПриложениеКлиент Тогда
СредстваМультимедиа.ВоспроизвестиЗвуковоеОповещение();
#КонецЕсли
КонецПроцедуры
Проанализируем ситуацию, когда в конфигурации присутствует множество мест, где могут возникать ошибки. Чтобы не дублировать код в каждой форме, рекомендуется соблюдать следующие правила:
ЗвукОповещенияКлиент.ОбработкаВнешнегоСобытия сразу после получения негативного ответа от сервера.