Содержание
В статье рассказали о возможностях платформы 1С и способах работы с асинхронностью.
На данный момент платформа 1С предлагает два способа работы с асинхронностью. Второй способ появился в версии платформы 8.3.18.1128. Если ранее было доступно использование определенных асинхронных методов для обработки результата, где требуется значение типа «ОписаниеОповещения» и написания дополнительной процедуры, то новый способ предлагает другие асинхронные методы, которые используются совместно с контейнером типа «Обещание», оператором «Ждать» и модификатором «Асинх».
Задача
При вводе (изменении) значения «Номенклатура» в таблице необходимо проверить нет ли этой номенклатуры в таблице. Если есть, сообщить об этом и спросить подтверждение повторного указания данной номенклатуры. Сохранить возможность автоматического заполнения поля «Ед. изм.» при изменении значения в поле «Номенклатура».
1. В обработчике ТоварНоменклатураПриИзменении() вызывается процедура ОбновитьЕдиницуИзмеренияВТекущейСтроке().
- ТоварНоменклатураПриИзменении() — здесь и далее, обработчик события ПриИзменении элемента «Номенклатура».
2. Добавим функцию НоменклатураУжеУказана(), которая будет возвращать:
- Истина, если в других строках таблицы есть эта же номенклатура;
- Ложь, в ином случае.
4. Асинхронный способ, появившийся в платформе 8.3.3.
&НаКлиенте
Процедура ТоварНоменклатураОбработкаВыбора(Элемент, ВыбранноеЗначение, ДополнительныеДанные, СтандартнаяОбработка)
Если НоменклатураУжеУказана(ВыбранноеЗначение) Тогда
СтандартнаяОбработка = Ложь;
ТекстВопроса = СтрШаблон(НСтр("ru = 'В таблице уже указана номенклатура %1. Указать повторно?'"),ВыбранноеЗначение);
ДополнительныеПараметры = Новый Структура("ВыбранноеЗначение",ВыбранноеЗначение);
ОписаниеОповещенияОЗавершении = Новый ОписаниеОповещения(
"ПослеВопросаПриПовтореНоменклатуры",ЭтотОбъект
,ДополнительныеПараметры);
ПоказатьВопрос(
ОписаниеОповещенияОЗавершении
,ТекстВопроса
,РежимДиалогаВопрос.ДаНет);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПослеВопросаПриПовтореНоменклатуры(Ответ,ДополнительныеПараметры) Экспорт
Если Ответ = КодВозвратаДиалога.Да Тогда
Элементы.Товар.ТекущиеДанные.Номенклатура = ДополнительныеПараметры.ВыбранноеЗначение;
ОбновитьЕдиницуИзмерения();
КонецЕсли;
КонецПроцедуры
Замечания для процедуры ТоварНоменклатураОбработкаВыбора():
- Процедура ТоварНоменклатураОбработкаВыбора() — здесь и далее, обработчик события ОбработкаВыбора элемента «Номенклатура».
- Если не указать СтандартнаяОбработка = Ложь, то после выполнения строки ПоказатьВопрос(), выводящей вопрос пользователю, продолжится выполнение процедуры ТоварНоменклатураОбработкаВыбора(), после будет выполнен и обработчик ТоварНоменклатураПриИзменении().
- Через ДополнительныеПараметры передаем ВыбранноеЗначение, чтобы иметь возможность заполнить поле Номенклатура в процедуре ПослеВопросаПриПовтореНоменклатуры().
5. Асинхронный способ, появившийся в платформе 8.3.18: рабочий вариант
Процедура ТоварНоменклатураОбработкаВыбора(Элемент, ВыбранноеЗначение, ДополнительныеДанные, СтандартнаяОбработка)
Если НоменклатураУжеУказана(ВыбранноеЗначение) Тогда
СтандартнаяОбработка = Ложь;
ТекстВопроса = СтрШаблон(НСтр("ru = 'В таблице уже указана номенклатура %1. Указать повторно?'"),ВыбранноеЗначение);
ЗадатьВопросОбработатьОтветАсинх(ВыбранноеЗначение);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Асинх Процедура ЗадатьВопросОбработатьОтветАсинх(ВыбранноеЗначение)
ТекстВопроса = СтрШаблон(НСтр("ru = 'В таблице уже указана номенклатура %1. Указать повторно?'"),ВыбранноеЗначение);
Обещание = ВопросАсинх(ТекстВопроса,РежимДиалогаВопрос.ДаНет);
Результат = Ждать Обещание;
Если Результат = КодВозвратаДиалога.Да Тогда
Элементы.Товар.ТекущиеДанные.Номенклатура = ВыбранноеЗначение;
ОбновитьЕдиницуИзмерения();
КонецЕсли;
КонецПроцедуры
Замечания для процедуры ТоварНоменклатураОбработкаВыбора():
- По сравнению с предыдущим способом заменили строки:
ДополнительныеПараметры = Новый Структура("ВыбранноеЗначение",ВыбранноеЗначение);
ОписаниеОповещенияОЗавершении = Новый ОписаниеОповещения(
"ПослеВопросаПриПовтореНоменклатуры",ЭтотОбъект
,ДополнительныеПараметры);
ПоказатьВопрос(
ОписаниеОповещенияОЗавершении
,ТекстВопроса
,РежимДиалогаВопрос.ДаНет);
- На одну строку:
ЗадатьВопросОбработатьОтветАсинх();
Замечания для процедуры ЗадатьВопросОбработатьОтветАсинх():
- Потому что в методе используется оператор «Ждать», перед ключевым словом Процедура необходимо указать модификатор «Асинх».
- Обратите внимание, что в процедуре ЗадатьВопросОбработатьОтветАсинх() блок с условием «Если» можно заменить вызовом процедуры ПослеВопросаПовторНоменклатуры() следующим образом:
ДополнительныеПараметры = Новый Структура("ВыбранноеЗначение",ВыбранноеЗначение);
ПослеВопросаПриПовтореНоменклатуры(Результат,ДополнительныеПараметры);
- В таком случае процедура ПослеВопросаПовторНоменклатуры() вызывается явно, а не в виде строки как параметр при сознании нового значения типа ОписаниеОповещения.
6. Асинхронный способ, появившийся в платформе 8.3.18: нерабочий вариант.
В предыдущих вариантах, кроме обработчика события ТоварНоменклатураОбработкаВыбора() нам требовалась еще одна процедура
ПослеВопросаПовторНоменклатуры() или ЗадатьВопросОбработатьОтветАсинх().
Попробуем использовать только одну процедуру, заменив в ТоварНоменклатураОбработкаВыбора() вызов ЗадатьВопросОбработатьОтветАсинх() на ее содержание. Для этого у процедуры ТоварНоменклатураОбработкаВыбора() добавим модификатор «Асинх», потому внутри нее будем использовать оператор «Ждать».
&НаКлиенте
Асинх Процедура ТоварНоменклатураОбработкаВыбора(Элемент, ВыбранноеЗначение, ДополнительныеДанные, СтандартнаяОбработка)
Если НоменклатураУжеУказана(ВыбранноеЗначение) Тогда
СтандартнаяОбработка = Ложь; //!!!
ТекстВопроса = СтрШаблон(НСтр("ru = 'В таблице уже указана номенклатура %1. Указать повторно?'"),ВыбранноеЗначение);
Обещание = ВопросАсинх(ТекстВопроса,РежимДиалогаВопрос.ДаНет);
Результат = Ждать Обещание;
Если Результат = КодВозвратаДиалога.Да Тогда
Элементы.Товар.ТекущиеДанные.Номенклатура = ВыбранноеЗначение;
ОбновитьЕдиницуИзмерения();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В данном варианте значения полей «Номенклатура» и «ЕдиницаИзмерений» будут заполняться до получения ответа от пользователя, что не соответствует задаче.
Замечания для процедуры ТоварНоменклатураОбработкаВыбора():
- Ожидая ответа пользователя на вопрос, процедура ТоварНоменклатураОбработкаВыбора() приостанавливается на строке
Обещание = Ждать ВопросАсинх(ТекстВопроса,РежимДиалогаВопрос.ДаНет)
до получения ответа.
- Но выполнение последовательности событий элемента продолжаются. И поэтому, хотя и было указано СтандартнаяОбработка = Ложь, что должно было прервать выполнение последовательности событий, событие ПриИзменении все равно выполняется.
- Это следствие того, что параметры в методе с модификатором «Асинх» передаются неявно по значению. И изменение копии параметра СтандартнаяОбработка на Ложь внутри ТоварНоменклатураОбработкаВыбора() не меняет значения параметра СтандартнаяОбработка, передаваемого по ссылке из обработчика в обработчик.
Выводы
Данные примеры показывают, что:
- Способ для платформы 8.3.18, более лаконичен в написании кода по сравнению со способом для платформы 8.3.3.
- При ожидании ответа пользователя выполнение приостанавливается только в асинхронном методе, в котором использован оператор «Ждать», а метод, в котором вызывался асинхронный метод, продолжит выполняться дальше.
- Параметры в методе с модификатором «Асинх» передаются неявно по значению.
Таким образом, разработчикам, желающим использовать новую возможность платформы, следует обратить внимание на ее особенности.
Остались вопросы?
Проконсультируйтесь с нашими специалистами