При переходе на управляемые формы и режим работы «Не использовать модальность» в 1С 8.3 разработчики часто сталкиваются с проблемой адаптации линейных алгоритмов. Типичный пример — загрузка прайс-листа поставщика, когда при обходе строк в цикле необходимо запрашивать у пользователя выбор номенклатуры из списка найденных вариантов. Использование модального метода ВыбратьЗначение() или модального открытия форм в таком цикле теперь заблокировано на уровне платформы.
Рассмотрим подробно несколько архитектурно правильных подходов к решению этой задачи без модальных окон.
Попытка вызывать интерактивный диалог на каждой строке файла при открытии нескольких диалоговых окон подряд создает плохой пользовательский опыт и может приводить к блокировкам в веб-клиенте. Наиболее удобное и правильное решение с точки зрения интерфейса — предоставить пользователю единую табличную часть на форме для контроля и исправления данных.
Разберем реализацию этого подхода по шагам:
ТаблицаЗначений), содержащую колонки загружаемого файла (например, НаименованиеКонтрагента, Цена) и дополнительную колонку Номенклатура (с типом СправочникСсылка.Номенклатура).Номенклатура заполняется автоматически. Если найдено несколько вариантов или не найдено ничего — колонка остается пустой или помечается флагом ошибки.ТаблицаФормы. Пользователь видит всю картину целиком, может с помощью стандартного поля ввода или формы выбора уточнить несовпавшие позиции, изменить ошибочно найденные элементы или вернуться к любой строке в произвольном порядке.Если специфика бизнес-процесса требует обязательно обработать строки в последовательном режиме прямо внутри цикла, в современных версиях платформы 1С 8.3 (начиная с 8.3.18) доступен механизм обещаний и асинхронных процедур. Это позволяет сохранять привычную линейную структуру кода с циклом Для каждого, не блокируя при этом поток выполнения платформы.
Проанализируем пример кода с использованием ключевых слов Асинх и Ждать:
&НаКлиенте
Асинх Процедура ОбработатьЗагруженныеСтрокиАсинх()
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
// Если номенклатура не сопоставлена однозначно
Если Не ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
// Получаем массив совпадений с сервера
СписокВариантов = ПолучитьСписокКандидатовНаСервере(СтрокаТЧ.НаименованиеПоставщика);
Если СписокВариантов.Количество() > 1 Тогда
// Вызываем немодальный выбор из списка с асинхронным ожиданием ответа
ВыбранныйЭлемент = Ждать ПоказатьВыборИзСпискаАсинх(СписокВариантов, "Выберите номенклатуру для: " + СтрокаТЧ.НаименованиеПоставщика);
Если ВыбранныйЭлемент <> Неопределено Тогда
СтрокаТЧ.Номенклатура = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В данном случае при вызове Ждать ПоказатьВыборИзСпискаАсинх выполнение процедуры «замирает» на текущей итерации цикла до тех пор, пока пользователь не сделает выбор в выпадающем меню или не закроет его, после чего цикл продолжается со следующей строки.
В версиях платформы ниже 8.3.18 ключевые слова Асинх и Ждать отсутствуют. Для пошаговой интерактивной обработки без использования табличной части применяется рекурсивный вызов процедуры-обработчика с передачей индекса текущей строки.
Рассмотрим схему работы данного метода:
0).ОписаниеОповещения, указывающий на процедуру-обработчик завершения выбора, и вызывается асинхронный метод (например, ПоказатьВыборИзСписка или ОткрытьФорму). В параметры оповещения передается текущий индекс строки.Индекс + 1), после чего процедура вызывает сам метод обработки для следующей строки.Из описанных вариантов наиболее предпочтительным с точки зрения архитектуры 1С является первый вариант (с выводом всех данных в табличную часть формы), так как он дает пользователю наибольшую гибкость при работе с файлами большого объема.