Распознавать учебные фразы с микрофона без сохранения аудио и остановить только свой поток

Учебные задачи

Собственная управляемая форма запускает интерактивный микрофонный поток с двумя реальными фразами своей сеансовой грамматики. Новые параметры включают промежуточные варианты, а privacy-проверка не допускает настроенной записи; текст не выполняет команды.

Где и как запускать

Полный клиентский модуль управляемой формы собственного окна УчебныйМикрофонРечи85.Пульт; толстый клиент8.5.1.1343 в режиме управляемого приложения, собственный микрофон и реальная заранее подготовленная модель.

Подготовка

  1. Создайте новую отдельную базу УчебныйМикрофонРечи85, платформа8.5.1.1343. Не переименовывайте рабочую базу, не запускайте пример в production и не включайте чужие грамматики ради прохождения опыта.

  2. Используйте толстый клиент в режиме Управляемое приложение. В конфигураторе: Обработки → УчебныйМикрофонРечи85 → Формы → Пульт, тип Управляемая. Код ниже — полный модуль этой формы с клиентскими директивами и защитой от других клиентов.

  3. Администратор заранее готовит реальное подключение к сервису и/или собственную доступную локальную модель. В фактическом каталоге должна быть модель с кодом языка, начинающимся на ru. Нет выдуманного URL, токена, модели или автоматической установки.

  4. Проверьте микрофон, разрешения ОС, условия тарифа и передачу аудио в сервис. Авто ищет подходящую локальную модель, затем может обратиться к внешнему распознаванию. Не обещайте пользователю полностью локальную обработку только по этому значению.

  5. Добавьте реквизиты Согласие типа Булево и Итог типа Строка неограниченной длины. Согласие выведите флажком, многострочный Итог сделайте только для просмотра. Ключи не вводятся пользователем и не являются реквизитами формы.

  6. Создайте команды НачатьСвойПоток и ОстановитьСвойОпыт. Назначьте одноимённые процедуры с параметром Команда и выведите кнопки команд. Назначьте события ПриОткрытии(Отказ) и ПередЗакрытием с четырьмя параметрами.

  7. Оставьте экспортными клиентские процедуры СвояГипотезаПолучена с тремя параметрами и СвояОшибкаПотока с тремя параметрами. Выходные Булево ПродолжитьРаспознавание и СтандартнаяОбработка не объявляйте через Знач.

  8. Нажмите F7 и обновите только собственный стенд. F7 не доказывает работу микрофона, доступность модели или сервиса; здесь runtimeVerifiedScenarios=0 и захват не запускался.

  9. Откройте только одно собственное окно. Установите согласие непосредственно перед интерактивным нажатием НачатьСвойПоток. Произнесите выбрать учебную книгу или завершить учебный опыт, затем вручную остановите свой опыт.

  10. Грамматика сеанса создаётся под новым собственным GUID-ключом. Она содержит обычный массив строк, а не SRGS/ABNF. Дополнительные грамматики базы внешнее потоковое распознавание не использует.

  11. Этот опыт намеренно не настраивает сохранение аудио. В установленной справке и поле обработчика записи, и поля ОписаниеОповещения readonly; способ их настройки через setter не выдумывается. Код читает настоящий свежий объект и запрещает старт, если у записи уже есть обработчик.

  12. Снять согласие можно в любое время. Следующий настоящий callback отклонит продолжение, но при тишине callback может не появиться: для немедленной адресной остановки нажмите ОстановитьСвойОпыт, даже со снятым согласием.

  13. После остановки проверяется отсутствие только своего ключа грамматики. Никаких файлов, резервных копий, архивов, выгрузки звука или запуска распознанных команд нет. Здесь 1С, микрофон и сервис не запускались.

#Если ТолстыйКлиентУправляемоеПриложение Тогда
Перем СвояГотовность;
Перем СвойКлючПотока;
Перем СвойКлючГрамматики;
Перем СвояПопыткаПотока;
Перем СвояПопыткаГрамматики;
Перем СвойЗапросОстановки;
Перем СвоиУведомления;

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    СвояГотовность = Ложь;
    Согласие = Ложь;
    СвойКлючПотока = "";
    СвойКлючГрамматики = "";
    СвояПопыткаПотока = Ложь;
    СвояПопыткаГрамматики = Ложь;
    СвойЗапросОстановки = Ложь;
    СвоиУведомления = 0;
    Итог = "Подготовьте собственный микрофон и модель; запись аудио этим окном не настраивается";
    Попытка
        ПроверитьСвойСтенд();
        СвояГотовность = Истина;
    Исключение
        Отказ = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСвойСтенд()
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Не запускайте захват звука внутри чужой транзакции";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСвоеОкно()
    ПроверитьСвойСтенд();
    Если Не СвояГотовность Тогда
        ВызватьИсключение "Нужно собственное открытое учебное окно";
    КонецЕсли;
КонецПроцедуры

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

&НаКлиенте
Процедура ПроверитьОтсутствиеЗаписи(Параметры)
    Если ТипЗнч(Параметры) <> Тип("ПараметрыПотоковогоРаспознаванияРечи") Тогда
        ВызватьИсключение "Нужны только собственные новые параметры потока";
    КонецЕсли;
    ОбработчикЗаписи = Параметры.ОбработчикОстановкиАудиозаписи;
    Если ОбработчикЗаписи = Неопределено Тогда
        Возврат;
    КонецЕсли;
    Если ТипЗнч(ОбработчикЗаписи) <> Тип("ОписаниеОповещения") Тогда
        ВызватьИсключение "Неизвестная настройка записи аудио; захват запрещён";
    КонецЕсли;
    Если ЗначениеЗаполнено(ОбработчикЗаписи.ИмяПроцедуры)
        Или ОбработчикЗаписи.Модуль <> Неопределено
        Или ЗначениеЗаполнено(ОбработчикЗаписи.ИмяПроцедурыОбработкиОшибки)
        Или ОбработчикЗаписи.МодульОбработкиОшибки <> Неопределено Тогда
        ВызватьИсключение "В собственных новых параметрах уже задана обработка записи; этот опыт её не разрешает";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СвояГипотезаПолучена(РезультатРаспознавания, ПродолжитьРаспознавание, ДополнительныеПараметры) Экспорт
    ПродолжитьРаспознавание = Ложь;
    Если Не СвояГотовность Или Не СвояПопыткаПотока
        Или ДополнительныеПараметры <> СвойКлючПотока Тогда
        Возврат;
    КонецЕсли;
    Если Не Согласие Или СвойЗапросОстановки Тогда
        СвойЗапросОстановки = Истина;
        Итог = "Продолжение собственного потока отклонено; нажмите ОстановитьСвойОпыт для адресного завершения и удаления своей грамматики";
        Возврат;
    КонецЕсли;
    Если ТипЗнч(РезультатРаспознавания) <> Тип("РезультатРаспознаванияРечи") Тогда
        СвойЗапросОстановки = Истина;
        Итог = "Получен не настоящий результат потока; продолжение отклонено";
        Возврат;
    КонецЕсли;
    СвоиУведомления = СвоиУведомления + 1;
    Если СвоиУведомления >= 20 Тогда
        СвойЗапросОстановки = Истина;
        Итог = "Достигнут учебный предел20уведомлений; дальнейшее продолжение отклонено. Явно остановите свой опыт";
        Возврат;
    КонецЕсли;
    Варианты = РезультатРаспознавания.ДанныеФраз;
    Если ТипЗнч(Варианты) <> Тип("Массив") Или Варианты.Количество() > 100 Тогда
        СвойЗапросОстановки = Истина;
        Итог = "Неожиданный массив гипотез; продолжение отклонено";
        Возврат;
    КонецЕсли;
    Если Варианты.Количество() = 0 Тогда
        Итог = "Пришло настоящее уведомление без гипотез: " + Строка(СвоиУведомления);
    Иначе
        Гипотеза = Варианты[0];
        Если ТипЗнч(Гипотеза) <> Тип("ДанныеФразыРаспознаванияРечи") Тогда
            СвойЗапросОстановки = Истина;
            Итог = "В вариантах найден не объект фразы; продолжение отклонено";
            Возврат;
        КонецЕсли;
        Итог = ?(РезультатРаспознавания.РаспознаваниеФразыЗавершено, "Окончательная фраза: ", "Промежуточная гипотеза: ")
            + Гипотеза.Фраза + "; исходная уверенность: " + Строка(Гипотеза.Уверенность)
            + "; вариантов: " + Строка(Варианты.Количество())
            + "; уведомлений: " + Строка(СвоиУведомления);
    КонецЕсли;
    ПродолжитьРаспознавание = Истина;
КонецПроцедуры

&НаКлиенте
Процедура СвояОшибкаПотока(Ошибка, СтандартнаяОбработка, ДополнительныеПараметры) Экспорт
    СтандартнаяОбработка = Истина;
    Если Не СвояГотовность Или ДополнительныеПараметры <> СвойКлючПотока Тогда
        СтандартнаяОбработка = Ложь;
        Возврат;
    КонецЕсли;
    Если ТипЗнч(Ошибка) <> Тип("ИнформацияОбОшибке") Тогда
        Итог = "Обработчик получил неожиданный объект ошибки";
    Иначе
        Итог = "Ошибка собственного уведомления; стандартная диагностика остаётся включённой. Остановите только собственный опыт";
    КонецЕсли;
    СвойЗапросОстановки = Истина;
КонецПроцедуры

&НаКлиенте
Процедура ОстановитьСвойОпыт(Команда)
    ПроверитьСвоеОкно();
    Итог = "Адресное завершение только своего опыта; результат ещё не подтверждён";
    Если СвояПопыткаПотока Тогда
        Если СвойКлючПотока = "" Тогда
            ВызватьИсключение "Без собственного ключа нельзя останавливать поток";
        КонецЕсли;
        РаботаСРечью.ОстановитьПотоковоеРаспознавание(СвойКлючПотока);
        СвояПопыткаПотока = Ложь;
        СвойКлючПотока = "";
    КонецЕсли;
    Если СвояПопыткаГрамматики Тогда
        Если СвойКлючГрамматики = "" Тогда
            ВызватьИсключение "Без собственного ключа нельзя удалять грамматику";
        КонецЕсли;
        Если ПолучитьНастоящиеКлючиГрамматик().Найти(СвойКлючГрамматики) <> Неопределено Тогда
            РаботаСРечью.УдалитьДополнительнуюГрамматикуСеанса(СвойКлючГрамматики);
        КонецЕсли;
        Если ПолучитьНастоящиеКлючиГрамматик().Найти(СвойКлючГрамматики) <> Неопределено Тогда
            ВызватьИсключение "Удаление своей грамматики ещё не подтверждено";
        КонецЕсли;
        СвояПопыткаГрамматики = Ложь;
        СвойКлючГрамматики = "";
    КонецЕсли;
    СвойЗапросОстановки = Ложь;
    Итог = "Вызов остановки только своего потока завершён, собственная сеансовая грамматика отсутствует. Запись аудио и файл этим окном не создавались";
КонецПроцедуры

&НаКлиенте
Функция ПолучитьНастоящиеКлючиГрамматик()
    Ключи = РаботаСРечью.ПолучитьДополнительныеГрамматикиСеанса();
    Если ТипЗнч(Ключи) <> Тип("Массив") Тогда
        ВызватьИсключение "Нужен настоящий массив ключей сеансовых грамматик";
    КонецЕсли;
    Для Каждого Ключ Из Ключи Цикл
        Если ТипЗнч(Ключ) <> Тип("Строка") Тогда
            ВызватьИсключение "Ключ грамматики должен быть строкой";
        КонецЕсли;
    КонецЦикла;
    Возврат Ключи;
КонецФункции

&НаКлиенте
Функция ПолучитьНастоящуюРусскуюМодель()
    Модели = РаботаСРечью.ПолучитьОписаниеМоделейРаспознавания();
    Если ТипЗнч(Модели) <> Тип("Массив") Тогда
        ВызватьИсключение "Нужен настоящий каталог моделей";
    КонецЕсли;
    Для Каждого Описание Из Модели Цикл
        Если ТипЗнч(Описание) <> Тип("ОписаниеМоделиРаспознаванияРечи") Тогда
            ВызватьИсключение "В каталоге найден не дескриптор модели";
        КонецЕсли;
        Если Описание.ДоступнаВЛокальномВарианте Или Описание.ДоступнаВоВнешнемВарианте Тогда
            Параметры = Описание.ПолучитьПараметры();
            Если ТипЗнч(Параметры) <> Тип("ПараметрыМоделиРаспознаванияРечи") Тогда
                ВызватьИсключение "Нужны реальные параметры выбранной модели";
            КонецЕсли;
            Если НРег(Лев(Параметры.КодЯзыка, 2)) = "ru" Тогда
                Возврат Параметры;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    ВызватьИсключение "Нет доступной модели с настоящим кодом языка, начинающимся на ru";
КонецФункции

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    СтандартнаяОбработка = Истина;
    Если СвояПопыткаПотока Или СвояПопыткаГрамматики Тогда
        Отказ = Истина;
        ТекстПредупреждения = "Сначала остановите только свой поток и удалите свою грамматику кнопкой ОстановитьСвойОпыт";
        Если Не ЗавершениеРаботы Тогда
            Сообщить(ТекстПредупреждения);
        КонецЕсли;
        Возврат;
    КонецЕсли;
    СвояГотовность = Ложь;
КонецПроцедуры
#Иначе
&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Отказ = Истина;
    ВызватьИсключение "Нужен толстый клиент в режиме управляемого приложения";
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    СтандартнаяОбработка = Истина;
КонецПроцедуры

&НаКлиенте
Процедура НачатьСвойПоток(Команда)
    ВызватьИсключение "Этот урок требует толстый клиент управляемого приложения";
КонецПроцедуры

&НаКлиенте
Процедура ОстановитьСвойОпыт(Команда)
    ВызватьИсключение "Этот урок требует толстый клиент управляемого приложения";
КонецПроцедуры
#КонецЕсли

Разбор по шагам

  1. ПоддерживаетсяПотоковоеРаспознавание проверяет возможность клиента. Истина не означает разрешение микрофона, готовую модель, сеть или действительность аккаунта; все эти условия проверяются отдельно.

  2. Параметры модели получаем от настоящего дескриптора каталога. ПараметрыПотоковогоРаспознаванияРечи создаются своим no-argument конструктором, а не приходят неизвестным входным объектом.

  3. Privacy-проверка читает ОбработчикОстановкиАудиозаписи. Если он отсутствует или в настоящем описании нет настроенных процедур и модулей, запись не настраивается. Ссылка и все readonly-поля уведомления никогда не заменяются и не изменяются.

  4. Три изменяемых Булево включают использование только дополнительных грамматик, промежуточные результаты и варианты промежуточных гипотез. Это действующие параметры, реально передаваемые в НачатьПотоковоеРаспознавание.

  5. Своя грамматика создаётся для сеанса под новым ключом и проверяется через настоящий массив ключей. ДополнительныеГрамматики — readonly-ссылка на собственный массив: добавляется элемент существующей коллекции, новое значение самого свойства не присваивается.

  6. ОписаниеОповещения создаётся конструктором с собственными обработчиком, модулем ЭтотОбъект и ключом потока. Обработчик ошибки задаётся также через конструктор; два readonly-поля проверяют его реальные имя и модуль, не заполняются setter-ом.

  7. Флаги попытки выставляются до соответствующего изменения или старта. При потере ответа свои ключи не забываются и новый поток не запускается. ОстановитьСвойОпыт разрешён после снятия согласия и работает только с этими закрытыми переменными.

  8. Callback по умолчанию выставляет ПродолжитьРаспознавание=Ложь, затем принимает только своё открытое окно и текущий ключ. Действительный результат и безопасные ограничения позволяют вернуть Истина; старые callback не оживляют новый поток.

  9. Флаг РаспознаваниеФразыЗавершено отличает промежуточную гипотезу от окончательной фразы, а не завершает всю сессию. Выводится первая настоящая альтернатива и исходная уверенность; текст никогда не исполняется как команда.

  10. Учебный предел20уведомлений отклоняет дальнейшее продолжение, но не является таймером или доказательством закрытия аудиоустройства. Собственный ключ удерживается до отдельного адресного стопа; при тишине нужен ручной стоп.

  11. Остановка сначала вызывает native stop со своим ключом. Лишь после его успешного возврата очищается владение потоком; затем удаляется только собственная грамматика и реальный getter подтверждает её отсутствие.

Как проверить результат

  1. Без согласия НачатьСвойПоток должен отказаться. ОстановитьСвойОпыт остаётся доступным после снятия согласия и не вызывает stop без ключа.

  2. При неподдерживаемом клиенте, другой версии, чужой базе или отсутствии подходящей фактической модели захват не должен начинаться. Если новый объект неожиданно содержит обработчик записи, privacy-проверка должна запретить старт.

  3. В собственных параметрах коллекция ДополнительныеГрамматики должна содержать один фактически созданный ключ; прямого присваивания readonly-свойства нет. Чужая ранее существовавшая грамматика не заменяется.

  4. При реальном распознавании текст и варианты должны приходить из ответа платформы. Промежуточная строка может меняться; окончательная фраза не должна объявляться завершением всего потока.

  5. Повторное начало до адресной остановки и очистки запрещено. После успешной остановки запоздалый callback со старым ключом отклоняет продолжение и не перезаписывает состояние нового опыта.

  6. После отзыва согласия следующий callback отклоняет продолжение. Для гарантированного намерения немедленно остановить захват пользователь нажимает адресную команду, а не ждёт новой гипотезы.

  7. Проверяйте удаление только собственной грамматики по её фактическому ключу. Не удаляйте весь набор, если сервис или другой пользователь изменил свои записи параллельно.

  8. Ошибка синхронного старта сохраняет владение попыткой для адресной очистки. Наличие настроенного error-handler у уведомления не выдаётся за гарантию доставки всех ошибок потока.

Ожидаемый результат

В собственном ручном опыте интерактивный поток показывает реальные промежуточные и окончательные фразы из своей грамматики; затем адресно остановлен и своя грамматика удалена. Сохранение аудио этим окном не настроено и не выполняется.

На что обратить внимание

  1. Справка разрешает запуск только интерактивно с осведомлённостью пользователя о захвате звука. ПриОткрытии не запускает поток, а Согласие каждый раз сбрасывается в Ложь.

  2. Readonly-ссылка на коллекцию не равна разрешению заменить свойство. Здесь меняется только массив собственной новой конфигурации потока; readonly-обработчик записи и поля уведомлений не мутируются.

  3. Справка не предоставляет документированного setter-а ОбработчикОстановкиАудиозаписи и не показывает соответствующего аргумента конструктора параметров. Этот урок осмысленно проверяет отсутствие записи, а не обещает несуществующий способ её включения.

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

  5. Распознанная фраза не является авторизованной командой пользователя. Код ничего не удаляет, не проводит документы и не исполняет текст; уверенность не трактуется как гарантированный процент.

  6. ПолучатьВариантыПромежуточныхГипотез может увеличить объём результатов. Пределы100вариантов и20уведомлений — собственные учебные ограничения после получения объектов, не лимиты аллокаций платформы и не ограничение длительности тишины.

  7. Оповещение содержит корректно сконструированный обработчик ошибок, но для StartStreaming не обещается, что абсолютно все ошибки будут доставлены по этому пути. Синхронные ошибки остаются исключениями; после любой неопределённости выполняется только адресный стоп собственного ключа.

  8. Управляемое завершение приложения не допускает серверных вызовов и открытие своих окон. ПередЗакрытием здесь лишь сообщает о незавершённом опыте; принудительное завершение ОС может потерять память и ключи.

  9. Локальное отсутствие записи в настройках этого окна не является обещанием о политике хранения аудио стороннего сервиса. Тариф, обработка и хранение облаком должны быть согласованы отдельно до передачи звука.

  10. Этот код не запускался, runtimeVerifiedScenarios=0. Файлы, резервные копии и архивы не создавались; исходники и рабочие базы не изменялись.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.