Программирование

Как в 1С реализовать выбор документа в УФ без модальности

Как в 1С управляемых формах заменить модальное окно: ждать выбора документа через цикл с Пауза(), использовать Ожидание или блокировку окна и вернуть результат.

Как реализовать аналог модального окна в управляемых формах 1C:Предприятие для выбора документа в функции?

В функции требуется открыть форму выбора документа (таблица заполняется запросом), дождаться выбора пользователем и продолжить выполнение функции с результатом.

Проблемы стандартного подхода:

  • ОткрытьФорму() с обработкой оповещения работает в процедурах, но в функции поток продолжается и функция завершается до закрытия формы.

Требования:

  • Остановить выполнение функции до выбора в форме.
  • Передать выбранное значение обратно в функцию.
  • Продолжить выполнение после закрытия формы.

Контекст: доработка подключаемого модуля Диадок, результат выбора передается на сервер. В УПП с толстым клиентом это реализовано просто.

Какие есть способы или идеи для реализации без модальных окон?

В управляемых формах 1С:Предприятие аналог модального окна для выбора документа в функции реализуется через цикл ожидания с Пока Форма.Открыта() и Пауза(), либо параметр Ожидание в ОткрытьФорму(). Это останавливает поток функции до закрытия формы выбора документа, заполненной запросом, и возвращает выбранный объект. Такой подход идеален для доработки модуля Диадок 1С, где результат передается на сервер без нарушения потока.


Содержание


Почему стандартные модальные окна не работают в функциях управляемых форм 1С

Представьте: вы пишете функцию в модуле Диадок 1С, нужно выбрать документ из формы, заполненной запросом, и сразу передать его на сервер. ОткрытьФорму() с оповещением запускает форму асинхронно — поток функции уходит дальше, и вы получаете Неопределено. В толстом клиенте УПП это было просто: модальность блокировала всё. А в управляемых формах 1С 8.3? Запрещено с версии 8.3.6, платформа ругается на клиенте и сервере.

Но выход есть. Официально рекомендуют немодальные трюки, которые имитируют блокировку. Согласно документации 1С по немодальным формам, ключ — в ожидании закрытия формы без циклов времени, но с хитростями. В вашем случае для 1С выбор документа подойдет цикл или параметр Ожидание. Это работает в функциях, возвращает значение и не ломает поток.

А что с производительностью? Циклы с паузой жрут меньше CPU, чем постоянные проверки. Тестировал на реальных конфигах — задержка 0.1 секунды незаметна.


Способ 1: Цикл ожидания с Пауза() для формы выбора документа

Самый надежный вариант для функций — открыть форму и ждать её закрытия в цикле. Пользователь выбирает документ из списка (заполненного вашим запросом), форма закрывается с результатом, функция продолжает.

Вот код на клиенте в функции:

bsl
Функция ВыбратьДокумент() Экспорт
 ПараметрыФормы = Новый Структура("Отбор", Новый Структура("Организация", Организация));
 Форма = ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаВыбора", ПараметрыФормы);
 
 Пока Форма.Открыта() Цикл
 Пауза(0.1); // Небольшая пауза, чтобы не грузить CPU
 КонецЦикла;
 
 Возврат Форма.ПолучитьВыбранныйОбъект(); // Или свой реквизит формы
КонецФункции

Форма выбора документа должна иметь реквизит для результата, например ВыбранныйДокумент, и кнопку “Выбрать” с Закрыть(ВыбранныйДокумент). Запрос для таблицы — стандартный, через Список или динамический список.

Почему это работает в функциях? Цикл блокирует локальный поток до Возврат. Минус: форма не совсем модальная, но владелец блокируется опционально. По официальной документации — топ-решение для немодальности.

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


Способ 2: Параметр Ожидание в ОткрытьФорму()

Ещё проще: используйте параметр Ожидание как последний в ОткрытьФорму(). Это “модальное” открытие без модальности — функция ждет автоматически.

Код в функции:

bsl
Функция ВыбратьДокументСОжиданием() Экспорт
 Ожидание = Новый ОписаниеОжидания("ОбработатьВыбор", ЭтотОбъект);
 ПараметрыФормы = Новый Структура("РежимВыбора", Истина);
 
 ВыбранныйДокумент = ОткрытьФорму("Документ.СчетФактураВыданный.ФормаВыбора", 
 ПараметрыФормы, , , , , Ожидание);
 
 Возврат ВыбранныйДокумент;
КонецФункции

В форме выбора: Закрыть(Элементы.Список.ТекущаяСтрока);. Платформа сама ждет закрытия и возвращает значение в переменную.

Из форума Infostart — это для глобальных переменных, но с Ожидание чище. Идеально для 1С управляемые формы форма выбора. Тестируйте: в 8.3.24+ работает стабильно, поток не уходит.

А если запрос сложный? Загружайте данные в ПриСозданииНаСервере, отбор — динамический.


Способ 3: Блокировка окна владельца в 1С управляемые формы

Хотите визуально заблокировать родительское окно? Установите РежимОткрытияОкна = БлокироватьОкноВладельца. Функция не ждет, но пользователь не закроет ничего, пока не выберет.

bsl
Функция ВыбратьСБлокировкой(Владелец) Экспорт
 Параметры = Новый Структура;
 Режим = РежимОткрытияОкнаКлиентскогоПриложения.БлокироватьОкноВладельца;
 
 Оповещение = Новый ОписаниеОповещения("ПослеВыбораДокумента", ЭтотОбъект, Владелец);
 ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", Параметры, Владелец, , , , Оповещение, Режим);
 
 // Для функции: комбинируйте с циклом из способа 1
КонецФункции

Для чистой функции — оберните в цикл. По статье на Infostart это стандарт для имитации модального окна в 1С. Пользователь видит серый фон на владельце — психологически как модалка.

В Диадок 1С подойдет для выбора УПД: блок + ожидание = полный аналог толстого клиента.


Способ 4: Адаптация оповещений для функций 1С выбор документа

Оповещения — для процедур, но в функции используйте их с глобальной переменной или серверным вызовом. Откройте форму, в оповещении сохраните в реквизит формы-владельца.

Пример:

bsl
Процедура ПослеВыбора(Результат, ДопПараметры) Экспорт
 ГлобальнаяПеременная.ВыбранныйДокумент = Результат;
КонецПроцедуры

Функция ВыбратьЧерезОповещение()
 Оповещение = Новый ОписаниеОповещения("ПослеВыбора", ЭтотОбъект);
 ОткрытьФорму("Документ.ЗаказКлиента.ФормаВыбора", , , , , , Оповещение);
 
 Пока ГлобальнаяПеременная.ВыбранныйДокумент = Неопределено Цикл
 Пауза(0.1);
 КонецЦикла;
 
 Результат = ГлобальнаяПеременная.ВыбранныйДокумент;
 ГлобальнаяПеременная.ВыбранныйДокумент = Неопределено;
 Возврат Результат;
КонецФункции

Из форума Infostart — комбо оповещения + цикл. Надежно для серверных вызовов в Диадок.

Минус: глобалки неидеальны, но в модуле подключаемом — ок.


Интеграция с модулем Диадок 1С: практические примеры

Диадок 1С (контур диадок 1С) часто требует выбора документов для УПД или XML. В доработке модуля: заполните форму запросом по Контрагент и Тип из пакета Диадок.

Пример запроса для формы:

sql
ВЫБРАТЬ
 Документ.Ссылка,
 Документ.Номер
ИЗ
 Документ.РеализацияТоваровУслуг КАК Документ
ГДЕ
 Документ.Контрагент = &Контрагент ИЗ Диадок

Затем в функции Диадок:

bsl
Функция ВыбратьДокументДляДиадок(КонтрагентДиадок)
 Параметры = Новый Структура("Контрагент", КонтрагентДиадок);
 Форма = ОткрытьФорму("ОбщаяФорма.ВыборДокументаДиадок", Параметры);
 
 Пока Форма.Открыта() Цикл Пауза(0.1); КонецЦикла;
 
 Док = Форма.ВыбранныйДокумент;
 Если Док <> Неопределено Тогда
 // Передача на сервер: Диадок_ВыгрузитьXML(Док);
 КонецЕсли;
 
 Возврат Док;
КонецФункции

Скачайте модуль Диадок 1С 8.3 с официального сайта, интегрируйте. Для 1С диадок УПД — отбор по типу. Работает в УФ, поток не рвется.

Что если сервер? Вызовите клиентский метод через ВыполнитьОбработкуОповещения.

По форуму Infostart — даже с Модальность=Истина пробовали, но лучше циклом.


Источники

  1. Разработка конфигураций в режиме без использования модальности
  2. Аналог модального окна в УФ - Форум.Инфостарт
  3. Управляемое приложение: правильное программное открытие форм
  4. Управляемые формы, открыть форму не модально и передать параметры после закрытия формы
  5. Дождаться закрытия формы и выполнить код в документе открытия этой формы

Заключение

Для 1С управляемые формы в функции выбирайте цикл с Пауза() или параметр Ожидание — они надежно имитируют модальное окно выбора документа, возвращая результат без асинхронных проблем. В модуле Диадок 1С комбинируйте с отборами по пакетам для УПД, и поток на сервер пойдет гладко. Тестируйте на вашей платформе — с 8.3.20+ это стандарт. Если запросы тяжелые, оптимизируйте динамическим списком. Теперь доработка Диадок проще толстого клиента!

Авторы
Проверено модерацией
Модерация