Начиная с версии 8.3 в платформе 1С 'не-можно' использовать модальные вызовы: Вопрос, ВвестиЗначение, ВвестиЧисло, ОткрытьФормуМодально и проч. Читать здесь. Кажется, это связано с разработкой на iPad-ах. Но вот ещё какая незадача - и в веб-клиенте Google Chrome начиная с какой-то версии (?36, ?37 - не вспомню никак) эти модальные вызовы также прекратили свою работу.
Трудностей по переделке этих вызовов на не-модальные (или 'псевдомодальные') 'выше крыши'. Всё просто, если вызовы в процедуре последовательно - разделил её на 2 или более и порядок. А если вызов в процедуре в цикле?
Например, возьмём код:
[Вариант кода №0, включает только модальные вызовы]
#Область ОбработчикиСобытийФормы
#КонецОбласти
#Область ОбработчикиСобытийЭлементовШапкиФормы
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицыФормы
#КонецОбласти
#Область ОбработчикиКомандФормы
// По кн.Запуска
// Параметры:
// Команда - КомандаФормы
&НаКлиенте
Процедура комЗапускВыбора(Команда)
ЗапускВыбора();
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
// Возвращает случайное число
// Параметры:
// низ - Число
// верх - Число
&НаКлиенте
Функция ПолучитьСлучайноеЧисло(низ, верх)
Генератор = Новый ГенераторСлучайныхЧисел;
Возврат Генератор.СлучайноеЧисло(низ, верх);
КонецФункции
// Запускает выбор
// Параметры: нет
&НаКлиенте
Процедура ЗапускВыбора()
ВведеннаяСтрока = "";
Если Не ВвестиСтроку(ВведеннаяСтрока, НСтр("ru='Введите строку'")) Тогда
Возврат;
КонецЕсли;
Если Не Вопрос(
НСтр("ru='Продолжить?'"),
РежимДиалогаВопрос.ДаНет,
10,
КодВозвратаДиалога.Да,
НСтр("ru='Вопрос о продолжении'"),
КодВозвратаДиалога.Нет
) = КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
РезультатЗапросаПользователя = ОткрытьФормуМодально(
"ВнешняяОбработка.ПробаПсевдомодальныхВызовов.Форма.ЗапроснаяФорма");
Если РезультатЗапросаПользователя = Неопределено Тогда
Возврат;
КонецЕсли;
ТекстПредупреждения = НСтр("ru='%ВведеннаяСтрока%%ПодставляемыеЗначения%'");
ПодставляемыеЗначения = "";
ЧислоСтрок = ПолучитьСлучайноеЧисло(2, 4);
ТекстЗаголовка = НСтр("ru='Укажите %Что% для строки %Сч% (из %ЧислоСтрок%)'");
ТекстЗаголовка = СтрЗаменить(ТекстЗаголовка, "%ЧислоСтрок%", Строка(ЧислоСтрок));
Для Сч = 1 По ЧислоСтрок Цикл
ПодставляемыеЗначенияСтроки = "%СимволыПС%";
ТекстЗаголовкаСтроки = ТекстЗаголовка;
ТекстЗаголовкаСтроки = СтрЗаменить(ТекстЗаголовкаСтроки, "%Сч%", Строка(Сч));
Если РезультатЗапросаПользователя.ВвестиЧисло Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "число");
ВведенноеЧисло = 0;
Если ВвестиЧисло(ВведенноеЧисло, ТекстЗаголовкаВвода, 6, 0) Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки + Строка(ВведенноеЧисло) + ", ";
КонецЕсли;
КонецЕсли;
Если РезультатЗапросаПользователя.ВвестиДату Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "дату");
ВведеннаяДата = Дата(1,1,1);
Если ВвестиДату(ВведеннаяДата, ТекстЗаголовкаВвода) Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки + Строка(ВведеннаяДата) + ", ";
КонецЕсли;
КонецЕсли;
Если РезультатЗапросаПользователя.ВвестиБулево Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "булево");
ВведенноеБулево = Ложь;
Если ВвестиЗначение(
ВведенноеБулево, ТекстЗаголовкаВвода, Новый ОписаниеТипов("Булево")) Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки + Строка(ВведенноеБулево);
КонецЕсли;
КонецЕсли;
ПодставляемыеЗначения = ПодставляемыеЗначения + ПодставляемыеЗначенияСтроки;
КонецЦикла;
ТекстПредупреждения = СтрЗаменить(ТекстПредупреждения,
"%ВведеннаяСтрока%", ВведеннаяСтрока);
ТекстПредупреждения = СтрЗаменить(ТекстПредупреждения,
"%ПодставляемыеЗначения%", ПодставляемыеЗначения);
ТекстПредупреждения = СтрЗаменить(ТекстПредупреждения,
"%СимволыПС%", Символы.ПС);
Предупреждение(ТекстПредупреждения);
КонецПроцедуры
#КонецОбласти
Как, наверное, из кода ясно, обработка запрашивает строку, затем разрешение продолжения, открывает модально форму, в которой нужно указать, следует ли далее вводить число, дату и булево значения. Затем рандомно задаётся целое число, в каждом цикле до заданного числа запрашивается (если выбрано, что нужно вводить) число, дата и булево. И, наконец-то, формируется показ предупреждения.
Да, пример притянут за уши. Да, в работе будут другие примеры. Более сложные.
Делаем рефакторинг средствами 1С
Если мы сделаем рефакторинг средствами 1С: ставим курсор на любом модальном вызове, щёлкаем правую кнопку мыши, выбираем Рефакторинг - Модальные вызовы - Преобразовать модальные вызовы модулей.
И наступает пичалька:
А когда мы поймём, где не получилось хорошо - в блоке цикла - становится совсем грустно.
И ещё рефакторинг разбил нашу процедуру на 4 разные процедуры.
Рука-лицо...
А есть ли другая возможность? Если ли возможность эмулировать функции, как у нас было при модальных вызовах? Нет?
Конечно же есть!!!
Рефакторинг через структуру данных
Идея заключается в том, что все данные последовательно писать, а затем проверять имеющееся значение. Если его нет - вызывать ввод этого значения и завершать процедуру. После ввода проверять есть это значение или нет. Если есть, то идти к следующей проверке.
Алгоритм нашего примера будет таков:
1.Проверяем, есть ли структура для записи данных. Её нет - создаём.
2.Проверяем, есть ли в этой структуре введённая строка. Нет - уходим на вызов ввода (передав туда структуру), а эту процедуру завершаем. После ввода строки вновь вызываем нашу процедуру.
3.Проверяем, что введённая строка в структуре наших данных есть. И если значение строковое, идём далее. (Ну а если Неопределено - пользователь отказался от ввода строки - завершаем).
4.Проверяем, что нет в структуре ответа на вопрос. Вызываем ПоказатьВопрос, передав туда нашу структуру. А нашу процедуру завершаем.
5.По ответу проверяем, что пользователь нажал кнопку Да. Иначе уходим.
6.Открываем форму (передав туда структуру и завершив текущую процедуру).
7.После закрытия формы вновь вызываем процедуру.
8.Если нет в структуре числа строк цикла перебора - генерируем рандом и получаем число строк.
9.И вот теперь самое интересное - приходим на цикл: в нашу структуру пишем массив. Который будет содержать [ЧислоСтрок] структур 'табличных' данных.
10.Добавляем структуру - строку массива.
11.Если нужно вводить число (это мы выбрали в открытой форме п.6) и это число в данную структуру не введено - посылаем структуру (завершив эту процедуру) во ввод числа.
12.Если нужно вводить дату - повторяем как в пункте 11.
13.Если нужно вводить булево, опять повторяем как в п.11.
Не забываем после каждого ввода завершить нашу процедуру! Таким образом вызов вноь идёт с начала процедуры проверяя уже введённые данные.
nn.Для каждого из [ЧислоСтрок] повторяем пп.10-13.
Шаг 1. Создаём структуру:
[варинат кода №1. Есть структура для хранения данных]
&НаКлиенте
Процедура ЗапускВыбора()
СтруктураДанных = Новый Структура; //!!!
ВведеннаяСтрока = "";
Если Не ВвестиСтроку(ВведеннаяСтрока, НСтр("ru='Введите строку'")) Тогда
Возврат;
КонецЕсли;
СтруктураДанных.Вставить("ВведеннаяСтрока", ВведеннаяСтрока); //!!!
Ответ = Вопрос( //!!!
НСтр("ru='Продолжить?'"),
РежимДиалогаВопрос.ДаНет,
10,
КодВозвратаДиалога.Да,
НСтр("ru='Вопрос о продолжении'"),
КодВозвратаДиалога.Нет
); //!!!
Если Не Ответ = КодВозвратаДиалога.Да Тогда //!!!
Возврат;
КонецЕсли;
СтруктураДанных.Вставить("Ответ", Ответ); //!!!
РезультатЗапросаПользователя =
ОткрытьФормуМодально(
"ВнешняяОбработка.ПробаПсевдомодальныхВызовов.Форма.ЗапроснаяФорма");
Если РезультатЗапросаПользователя = Неопределено Тогда
Возврат;
КонецЕсли;
СтруктураДанных.Вставить( //!!!
"РезультатЗапросаПользователя",
РезультатЗапросаПользователя);
ЧислоСтрок = ПолучитьСлучайноеЧисло(2, 4);
СтруктураДанных.Вставить("ЧислоСтрок", ЧислоСтрок); //!!!
ТекстПредупреждения = НСтр("ru='%ВведеннаяСтрока%%ПодставляемыеЗначения%'");
ПодставляемыеЗначения = "";
ТекстЗаголовка = НСтр("ru='Укажите %Что% для строки %Сч% (из %ЧислоСтрок%)'");
ТекстЗаголовка = СтрЗаменить(ТекстЗаголовка, "%ЧислоСтрок%", Строка(ЧислоСтрок));
МассивДанныхСтрок = Новый Массив; //!!!
Для Сч = 1 По ЧислоСтрок Цикл
СтруктураДанныхСтрок = Новый Структура; //!!!
ПодставляемыеЗначенияСтроки = "%СимволыПС%";
ТекстЗаголовкаСтроки = ТекстЗаголовка;
ТекстЗаголовкаСтроки = СтрЗаменить(ТекстЗаголовкаСтроки, "%Сч%", Строка(Сч));
Если РезультатЗапросаПользователя.ВвестиЧисло Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "число");
ВведенноеЧисло = 0;
Если ВвестиЧисло(ВведенноеЧисло, ТекстЗаголовкаВвода, 6, 0) Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки + Строка(ВведенноеЧисло) + ", ";
СтруктураДанныхСтрок.Вставить( //!!!
"ВведенноеЧисло",
ВведенноеЧисло);
КонецЕсли;
КонецЕсли;
Если РезультатЗапросаПользователя.ВвестиДату Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "дату");
ВведеннаяДата = Дата(1,1,1);
Если ВвестиДату(ВведеннаяДата, ТекстЗаголовкаВвода) Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки + Строка(ВведеннаяДата) + ", ";
СтруктураДанныхСтрок.Вставить( //!!!
"ВведеннаяДата",
ВведеннаяДата);
КонецЕсли;
КонецЕсли;
Если РезультатЗапросаПользователя.ВвестиБулево Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "булево");
ВведенноеБулево = Ложь;
Если ВвестиЗначение(
ВведенноеБулево,
ТекстЗаголовкаВвода,
Новый ОписаниеТипов("Булево")) Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки + Строка(ВведенноеБулево);
СтруктураДанныхСтрок.Вставить( //!!!
"ВведенноеБулево",
ВведенноеБулево);
КонецЕсли;
КонецЕсли;
ПодставляемыеЗначения = ПодставляемыеЗначения + ПодставляемыеЗначенияСтроки;
МассивДанныхСтрок.Добавить(СтруктураДанныхСтрок); //!!!
КонецЦикла;
СтруктураДанных.Вставить( //!!!
"МассивДанныхСтрок",
МассивДанныхСтрок);
ТекстПредупреждения =
СтрЗаменить(ТекстПредупреждения,
"%ВведеннаяСтрока%",
ВведеннаяСтрока);
ТекстПредупреждения =
СтрЗаменить(ТекстПредупреждения,
"%ПодставляемыеЗначения%",
ПодставляемыеЗначения);
ТекстПредупреждения =
СтрЗаменить(ТекстПредупреждения,
"%СимволыПС%",
Символы.ПС);
Предупреждение(ТекстПредупреждения);
КонецПроцедуры
Шаг 2.Необходимость ввода чисел, дат и булево пишем в структуру. И выделяем показ предупреждения
//СтруктураДанных.Вставить(
// "РезультатЗапросаПользователя",
// РезультатЗапросаПользователя);
СтруктураДанных.Вставить("ВвестиЧисло", РезультатЗапросаПользователя.ВвестиЧисло); //!!!
СтруктураДанных.Вставить("ВвестиДату", РезультатЗапросаПользователя.ВвестиДату); //!!!
СтруктураДанных.Вставить("ВвестиБулево", РезультатЗапросаПользователя.ВвестиБулево); //!!!
ЧислоСтрок = ПолучитьСлучайноеЧисло(2, 4);
СтруктураДанных.Вставить("ЧислоСтрок", ЧислоСтрок);
ТекстЗаголовка = НСтр("ru='Укажите %Что% для строки %Сч% (из %ЧислоСтрок%)'");
ТекстЗаголовка = СтрЗаменить(ТекстЗаголовка, "%ЧислоСтрок%", Строка(ЧислоСтрок));
МассивДанныхСтрок = Новый Массив;
Для Сч = 1 По ЧислоСтрок Цикл
СтруктураДанныхСтрок = Новый Структура;
ТекстЗаголовкаСтроки = ТекстЗаголовка;
ТекстЗаголовкаСтроки = СтрЗаменить(ТекстЗаголовкаСтроки, "%Сч%", Строка(Сч));
Если СтруктураДанных.ВвестиЧисло Тогда //!!!
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "число");
ВведенноеЧисло = 0;
Если ВвестиЧисло(ВведенноеЧисло, ТекстЗаголовкаВвода, 6, 0) Тогда
СтруктураДанныхСтрок.Вставить("ВведенноеЧисло", ВведенноеЧисло);
КонецЕсли;
КонецЕсли;
Если СтруктураДанных.ВвестиДату Тогда //!!!
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "дату");
ВведеннаяДата = Дата(1,1,1);
Если ВвестиДату(ВведеннаяДата, ТекстЗаголовкаВвода) Тогда
СтруктураДанныхСтрок.Вставить("ВведеннаяДата", ВведеннаяДата);
КонецЕсли;
КонецЕсли;
Если СтруктураДанных.ВвестиБулево Тогда //!!!
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "булево");
ВведенноеБулево = Ложь;
Если ВвестиЗначение(
ВведенноеБулево,
ТекстЗаголовкаВвода,
Новый ОписаниеТипов("Булево")) Тогда
СтруктураДанныхСтрок.Вставить("ВведенноеБулево", ВведенноеБулево);
КонецЕсли;
КонецЕсли;
МассивДанныхСтрок.Добавить(СтруктураДанныхСтрок);
КонецЦикла;
СтруктураДанных.Вставить("МассивДанныхСтрок", МассивДанныхСтрок);
ВывестиПредупреждение(СтруктураДанных);
КонецПроцедуры
//!!!
// Выводит предупреждение по введённым данным
// Параметры:
// СтруктураДанных - Структура
&НаКлиенте
Процедура ВывестиПредупреждение(СтруктураДанных)
ТекстПредупреждения = НСтр("ru='%ВведеннаяСтрока%%ПодставляемыеЗначения%'");
ТекстПредупреждения =
СтрЗаменить(
ТекстПредупреждения,
"%ВведеннаяСтрока%",
СтруктураДанных.ВведеннаяСтрока);
ПодставляемыеЗначения = "";
МассивДанныхСтрок = СтруктураДанных.МассивДанныхСтрок;
Для Каждого СтруктураДанныхСтрок Из МассивДанныхСтрок Цикл
ПодставляемыеЗначенияСтроки = "";
Если СтруктураДанныхСтрок.Свойство("ВведенноеЧисло") И
Не СтруктураДанныхСтрок.ВведенноеЧисло = Неопределено Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки +
Строка(СтруктураДанныхСтрок.ВведенноеЧисло) + ", ";
КонецЕсли;
Если СтруктураДанныхСтрок.Свойство("ВведеннаяДата") И
Не СтруктураДанныхСтрок.ВведеннаяДата = Неопределено Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки +
Строка(СтруктураДанныхСтрок.ВведеннаяДата) + ", ";
КонецЕсли;
Если СтруктураДанныхСтрок.Свойство("ВведенноеБулево") И
Не СтруктураДанныхСтрок.ВведенноеБулево = Неопределено Тогда
ПодставляемыеЗначенияСтроки =
ПодставляемыеЗначенияСтроки +
Строка(СтруктураДанныхСтрок.ВведенноеБулево) + ", ";
КонецЕсли;
Если СтрДлина(ПодставляемыеЗначенияСтроки) Тогда
ПодставляемыеЗначенияСтроки =
Лев(ПодставляемыеЗначенияСтроки,
СтрДлина(ПодставляемыеЗначенияСтроки) - 2);
КонецЕсли;
ПодставляемыеЗначения =
ПодставляемыеЗначения +
"%СимволыПС%" +
ПодставляемыеЗначенияСтроки;
КонецЦикла;
ТекстПредупреждения = СтрЗаменить(
ТекстПредупреждения,
"%ПодставляемыеЗначения%",
ПодставляемыеЗначения);
ТекстПредупреждения = СтрЗаменить(
ТекстПредупреждения,
"%СимволыПС%",
Символы.ПС);
ПоказатьПредупреждение(, ТекстПредупреждения);
КонецПроцедуры
Предупреждение ничего не решает. Хотя это наш 1-ый псевдомодальный вызов. Поздравляю!!!
Шаг 3. Создаём вызовы пока для тех, кто не в цикле
// Завершает ввод строки
// Параметры:
// ВведеннаяСтрока - Строка, Неопределено
// ДопПараметры - Структура
&НаКлиенте
Процедура ЗавершениеВводаСтроки(ВведеннаяСтрока, ДопПараметры) Экспорт
ДопПараметры.СтруктураДанных.Вставить(ДопПараметры.КлючВставки, ВведеннаяСтрока);
ЗапускВыбора(ДопПараметры.СтруктураДанных);
КонецПроцедуры
// Завершает ответ на вопрос
// Параметры:
// Ответ - КодВозвратаДиалога, Неопределено
// ДопПараметры - Структура
&НаКлиенте
Процедура ЗавершениеВопроса(Ответ, ДопПараметры) Экспорт
ДопПараметры.СтруктураДанных.Вставить(ДопПараметры.КлючВставки, Ответ);
ЗапускВыбора(ДопПараметры.СтруктураДанных);
КонецПроцедуры
// Завершает открытиеформы
// Параметры:
// РезультатОткрытияФормы - Структура, Произвольное, Неопределено
// ДопПараметры - Структура
&НаКлиенте
Процедура ЗавершениеОткрытияФормы(РезультатОткрытияФормы, ДопПараметры) Экспорт
Если ТипЗнч(РезультатОткрытияФормы) = Тип("Структура") Тогда
ЗаполнитьЗначенияСвойств(
ДопПараметры.СтруктураДанных,
РезультатОткрытияФормы,
ДопПараметры.КлючВставки);
ИначеЕсли Не ТипЗнч(РезультатОткрытияФормы) = Тип("Неопределено") Тогда
ДопПараметры.СтруктураДанных.Вставить(
ДопПараметры.КлючВставки,
РезультатОткрытияФормы);
КонецЕсли;
ЗапускВыбора(ДопПараметры.СтруктураДанных);
КонецПроцедуры
#КонецОбласти //ПсевдоМодальныеПроцедуры
// Запускает выбор
// Параметры: нет
&НаКлиенте
Процедура ЗапускВыбора(СтруктураДанных = Неопределено)
Если СтруктураДанных = Неопределено Тогда
СтруктураДанных = Новый Структура;
КонецЕсли;
Если Не СтруктураДанных.Свойство("ВведеннаяСтрока") Тогда
ВведеннаяСтрока = "";
ПоказатьВводСтроки(
Новый ОписаниеОповещения(
"ЗавершениеВводаСтроки",
ЭтотОбъект,
Новый Структура(
"СтруктураДанных, КлючВставки",
СтруктураДанных, "ВведеннаяСтрока")),
ВведеннаяСтрока,
НСтр("ru='Введите строку'")
);
Возврат;
ИначеЕсли СтруктураДанных.ВведеннаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не СтруктураДанных.Свойство("ОтветНаВопросОПродолжении") Тогда
ПоказатьВопрос(
Новый ОписаниеОповещения(
"ЗавершениеВопроса",
ЭтотОбъект,
Новый Структура(
"СтруктураДанных, КлючВставки",
СтруктураДанных, "ОтветНаВопросОПродолжении")
),
НСтр("ru='Продолжить?'"),
РежимДиалогаВопрос.ДаНет,
10,
КодВозвратаДиалога.Да,
НСтр("ru='Вопрос о продолжении'"),
КодВозвратаДиалога.Нет
);
Возврат;
ИначеЕсли СтруктураДанных.ОтветНаВопросОПродолжении = Неопределено Или
Не СтруктураДанных.ОтветНаВопросОПродолжении = КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
Если Не СтруктураДанных.Свойство("ВвестиЧисло") И
Не СтруктураДанных.Свойство("ВвестиДату") И
Не СтруктураДанных.Свойство("ВвестиБулево") Тогда
СтруктураДанных.Вставить("ВвестиЧисло");
СтруктураДанных.Вставить("ВвестиДату");
СтруктураДанных.Вставить("ВвестиБулево");
ОткрытьФорму(
"ВнешняяОбработка.ПробаПсевдомодальныхВызовов.Форма.ЗапроснаяФорма",,,,,,
Новый ОписаниеОповещения("ЗавершениеОткрытияФормы", ЭтотОбъект,
Новый Структура(
"СтруктураДанных, КлючВставки",
СтруктураДанных, "ВвестиЧисло, ВвестиДату, ВвестиБулево")),
РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
Возврат;
КонецЕсли;
ЧислоСтрок = ПолучитьСлучайноеЧисло(2, 4);
СтруктураДанных.Вставить("ЧислоСтрок", ЧислоСтрок);
ТекстЗаголовка = НСтр("ru='Укажите %Что% для строки %Сч% (из %ЧислоСтрок%)'");
ТекстЗаголовка = СтрЗаменить(ТекстЗаголовка, "%ЧислоСтрок%", Строка(ЧислоСтрок));
МассивДанныхСтрок = Новый Массив;
Для Сч = 1 По ЧислоСтрок Цикл
СтруктураДанныхСтрок = Новый Структура;
ТекстЗаголовкаСтроки = ТекстЗаголовка;
ТекстЗаголовкаСтроки = СтрЗаменить(ТекстЗаголовкаСтроки, "%Сч%", Строка(Сч));
Если СтруктураДанных.ВвестиЧисло Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "число");
ВведенноеЧисло = 0;
Если ВвестиЧисло(ВведенноеЧисло, ТекстЗаголовкаВвода, 6, 0) Тогда
СтруктураДанныхСтрок.Вставить("ВведенноеЧисло", ВведенноеЧисло);
КонецЕсли;
КонецЕсли;
Если СтруктураДанных.ВвестиДату Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "дату");
ВведеннаяДата = Дата(1,1,1);
Если ВвестиДату(ВведеннаяДата, ТекстЗаголовкаВвода) Тогда
СтруктураДанныхСтрок.Вставить("ВведеннаяДата", ВведеннаяДата);
КонецЕсли;
КонецЕсли;
Если СтруктураДанных.ВвестиБулево Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "булево");
ВведенноеБулево = Ложь;
Если ВвестиЗначение(
ВведенноеБулево,
ТекстЗаголовкаВвода,
Новый ОписаниеТипов("Булево")) Тогда
СтруктураДанныхСтрок.Вставить("ВведенноеБулево", ВведенноеБулево);
КонецЕсли;
КонецЕсли;
МассивДанныхСтрок.Добавить(СтруктураДанныхСтрок);
КонецЦикла;
СтруктураДанных.Вставить("МассивДанныхСтрок", МассивДанныхСтрок);
ВывестиПредупреждение(СтруктураДанных);
КонецПроцедуры
Обратите внимание: здесь мы перевели ВвестиСтроку на ПоказатьВводСтроки, Вопрос на ПоказатьВопрос и ОткрытьФормуМодально на ОткрытьФорму и после каждого этого вызова завершаем нашу процедуру:
Возврат;
а после каждого завершения - запускаем нашу процедуру.
а если строку 'возвращаем' в Неопределено или Ответ в 'Нет', то выходим совсем.
Возврат;
ИначеЕсли СтруктураДанных.ОтветНаВопросОПродолжении = Неопределено Или
Не СтруктураДанных.ОтветНаВопросОПродолжении = КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
Шаг 4. Теперь для тех кто в цикле
// Завершает ввод числа
// Параметры:
// ВведенноеЧисло - Число, Неопределено
// ДопПараметры - Структура
&НаКлиенте
Процедура ЗавершениеВводаЧисла(ВведенноеЧисло, ДопПараметры) Экспорт
Если Не ДопПараметры.Свойство("ПодСтруктураДанных") Тогда
ДопПараметры.СтруктураДанных.Вставить(
ДопПараметры.КлючВставки, ВведенноеЧисло);
Иначе
ДопПараметры.ПодСтруктураДанных.Вставить(
ДопПараметры.КлючВставки, ВведенноеЧисло);
КонецЕсли;
ЗапускВыбора(ДопПараметры.СтруктураДанных);
КонецПроцедуры
// Завершает ввод даты
// Параметры:
// ВведеннаяДата - Дата, Неопределено
// ДопПараметры - Структура
&НаКлиенте
Процедура ЗавершениеВводаДаты(ВведеннаяДата, ДопПараметры) Экспорт
Если Не ДопПараметры.Свойство("ПодСтруктураДанных") Тогда
ДопПараметры.СтруктураДанных.Вставить(
ДопПараметры.КлючВставки, ВведеннаяДата);
Иначе
ДопПараметры.ПодСтруктураДанных.Вставить(
ДопПараметры.КлючВставки, ВведеннаяДата);
КонецЕсли;
ЗапускВыбора(ДопПараметры.СтруктураДанных);
КонецПроцедуры
// Завершает ввод значения
// Параметры:
// ВведенноеЗначение - Произвольное, Неопределено
// ДопПараметры - Структура
&НаКлиенте
Процедура ЗавершениеВводаЗначения(ВведенноеЗначение, ДопПараметры) Экспорт
Если Не ДопПараметры.Свойство("ПодСтруктураДанных") Тогда
ДопПараметры.СтруктураДанных.Вставить(
ДопПараметры.КлючВставки, ВведенноеЗначение);
Иначе
ДопПараметры.ПодСтруктураДанных.Вставить(
ДопПараметры.КлючВставки, ВведенноеЗначение);
КонецЕсли;
ЗапускВыбора(ДопПараметры.СтруктураДанных);
КонецПроцедуры
...
ТекстЗаголовка = НСтр("ru='Укажите %Что% для строки %Сч% (из %ЧислоСтрок%)'");
ТекстЗаголовка = СтрЗаменить(ТекстЗаголовка, "%ЧислоСтрок%", Строка(ЧислоСтрок));
Если Не СтруктураДанных.Свойство("МассивДанныхСтрок") Тогда
СтруктураДанных.Вставить("МассивДанныхСтрок", Новый Массив);
КонецЕсли;
Для Сч = 1 По ЧислоСтрок Цикл
Если СтруктураДанных.МассивДанныхСтрок.Количество() < Сч Тогда
СтруктураДанных.МассивДанныхСтрок.Добавить(Новый Структура);
КонецЕсли;
СтруктураДанныхСтрок = СтруктураДанных.МассивДанныхСтрок[Сч - 1];
ТекстЗаголовкаСтроки = ТекстЗаголовка;
ТекстЗаголовкаСтроки = СтрЗаменить(ТекстЗаголовкаСтроки, "%Сч%", Строка(Сч));
Если СтруктураДанных.ВвестиЧисло И
Не СтруктураДанныхСтрок.Свойство("ВведенноеЧисло") Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "число");
ВведенноеЧисло = 0;
ПоказатьВводЧисла(
Новый ОписаниеОповещения(
"ЗавершениеВводаЧисла",
ЭтотОбъект,
Новый Структура(
"СтруктураДанных, ПодСтруктураДанных, КлючВставки",
СтруктураДанных, СтруктураДанныхСтрок, "ВведенноеЧисло")
),
ВведенноеЧисло, ТекстЗаголовкаВвода);
Возврат;
ИначеЕсли СтруктураДанных.ВвестиЧисло И
СтруктураДанныхСтрок.ВведенноеЧисло = Неопределено Тогда
СтруктураДанныхСтрок.Вставить("ВведенноеЧисло", 0);
КонецЕсли;
Если СтруктураДанных.ВвестиДату И
Не СтруктураДанныхСтрок.Свойство("ВведеннаяДата") Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "дату");
ВведеннаяДата = Дата(1,1,1);
ПоказатьВводДаты(
Новый ОписаниеОповещения(
"ЗавершениеВводаДаты",
ЭтотОбъект,
Новый Структура(
"СтруктураДанных, ПодСтруктураДанных, КлючВставки",
СтруктураДанных, СтруктураДанныхСтрок, "ВведеннаяДата")
),
ВведеннаяДата, ТекстЗаголовкаВвода);
Возврат;
ИначеЕсли СтруктураДанных.ВвестиДату И
СтруктураДанныхСтрок.ВведеннаяДата = Неопределено Тогда
СтруктураДанныхСтрок.Вставить("ВведеннаяДата", Дата(1,1,1));
КонецЕсли;
Если СтруктураДанных.ВвестиБулево И
Не СтруктураДанныхСтрок.Свойство("ВведенноеБулево") Тогда
ТекстЗаголовкаВвода = ТекстЗаголовкаСтроки;
ТекстЗаголовкаВвода = СтрЗаменить(ТекстЗаголовкаВвода, "%Что%", "булево");
ВведенноеБулево = Ложь;
ПоказатьВводЗначения(
Новый ОписаниеОповещения(
"ЗавершениеВводаЗначения",
ЭтотОбъект,
Новый Структура(
"СтруктураДанных, ПодСтруктураДанных, КлючВставки",
СтруктураДанных, СтруктураДанныхСтрок, "ВведенноеБулево")
),
ВведенноеБулево, ТекстЗаголовкаВвода);
Возврат;
ИначеЕсли СтруктураДанных.ВвестиБулево И
СтруктураДанныхСтрок.ВведеннаяДата = Неопределено Тогда
СтруктураДанныхСтрок.Вставить("ВведенноеБулево", Ложь);
КонецЕсли;
КонецЦикла;
ВывестиПредупреждение(СтруктураДанных);
КонецПроцедуры
Точно также проверяем, что число / дату / булево требуется вводить и они не введены. Посылаем программу на ввод данных и завершаем процедуру. Она получает ввод и вновь запускает нашу процедуру. Вновь проверяет все введённые данные и приходит к невведённым.
Вот и всё! Работает! Можно смело идти в свойства конфигурации и ставить 'Режим использования модальности' - 'Не использовать'. Если это единственная обработка с модальными вызовами, конечно...
'Русская весна. А что дальше?!'
Процедур всё равно много. И сидят они в одной единственной обработке. А как сделать, чтобы модальные в псевдомодальные м.б.переделать во всей конфигурации?
Но мы не были бы мы, русскими программистами, если бы не сделали отдельный модуль для псевдомодальных вызовов.
Пересяем все эти вызовы в общий клиентский модуль, например, 'АсинхронныеВызовы'. А чтобы узнавать, куда потом 'стучаться', передавайте также в дополнительные параметры текущий модуль и имя процедуры:
в обработке:
Если Не СтруктураДанных.Свойство("ВведеннаяСтрока") Тогда
ВведеннаяСтрока = "";
ПоказатьВводСтроки(
Новый ОписаниеОповещения(
"ЗавершениеВводаСтроки",
АсинхронныеВызовы,
Новый Структура("СтруктураДанных, КлючВставки, модуль, ИмяПроцедуры",
СтруктураДанных, "ВведеннаяСтрока", ЭтотОбъект, "ЗапускВыбора")),
ВведеннаяСтрока,
НСтр("ru='Введите строку'")
);
в общем модуле для каждого вызова сделаем завершение. По переданному имени процедуры узнаём какую процедуру нужно вызвать. Другого [универсального] способа я не нашёл (оператор выполнить не поддерживается на веб-клиенте):
Процедура ЗавершениеВводаСтроки(ВведеннаяСтрока, ДопПараметры) Экспорт
Если Не ДопПараметры.Свойство("ПодСтруктураДанных") Тогда
ДопПараметры.СтруктураДанных.Вставить(
ДопПараметры.КлючВставки,
ВведеннаяСтрока);
Иначе
ДопПараметры.ПодСтруктураДанных.Вставить(
ДопПараметры.КлючВставки,
ВведеннаяСтрока);
КонецЕсли;
ЗавершениеАсинхронногоВызова(
ДопПараметры.СтруктураДанных,
ДопПараметры.модуль,
ДопПараметры.ИмяПроцедуры);
КонецПроцедуры
// Завершает ввод данных и запускает вызываемую процедуру
// Параметры:
// СтруктураДанных - Структура
// модуль - УправляемаяФорма, ОбщийМодуль, Команда
// ИмяПроцедуры - Строка
Процедура ЗавершениеАсинхронногоВызова(СтруктураДанных, модуль, ИмяПроцедуры)
Если ИмяПроцедуры = "ЗапускВыбора" Тогда
модуль.ЗапускВыбора(СтруктураДанных);
КонецЕсли;
КонецПроцедуры
По прилагаемой обработке:
её можно не закачивать. Весь код с избытком здесь.
Спасибо за внимание. Надеюсь, кому-нибудь моя идея поможет!
PS.А как же замена модальных вызовов в функциях. Хм, тут надо подумать...