Введение
Иногда требуется от пользователя интерактивно ввести несколько значений при выполнении какой-либо операции, обычно для этого создается специальная форма ввода как альтернатива последовательного вызова ПоказатьВводЗначения подобных функций. Если это требуется сделать из общей команды - то создается общая форма. Раньше с этим мирился, хотя идея создать универсальную форму ввода периодически посещала. При разработке самописной конфигурации столкнулся с необходимостью заполнения структур в разных местах программы, причем состав структур и типы значений заранее неизвестны. Ну вот и пришло время для осуществления идеи.
Функционал
Форма отображает переданные ей значения в виде полей ввода. Так же дополнительно форме можно передать свойства элементов формы, признак проверки заполнения определенных элементов, детально указать тип значений (составные типы, с квалификаторами). Можно указать заголовок формы, при этом для каждого заголовка сохраняется положение и размер формы. Поддерживаются простые и ссылочные типы, коллекции типа Структура, Соответствие или Массив. Коллекции группируются для удобства пользователя.
Инструкция
Использование формы
Форма поставляется во внешней обработке. Для ее использования можно включить обработку в конфигурацию/расширение или копированием/вставкой перенести форму из внешней обработки в нужный объект конфигурации или в общие формы. Для вызова формы нужно передать ей коллекцию со значениями и определить обработчик закрытия формы - в него будет возвращен результат и при необходимости определенные разработчиком дополнительные параметры. В самом простом варианте заголовок элемента формы соответствует ключу элемента коллекции (для массива будет использован индекс), а тип берется из значения. В примере имена ключей названы так для наглядности и с типом значения никак не связанны.
&НаКлиенте
Процедура Протестировать(Команда)
Данные = Новый Структура;
Данные.Вставить("Строка", "");
Данные.Вставить("Число", 0);
Данные.Вставить("Булево", Ложь);
Данные.Вставить("Дата", '20250101');
Данные.Вставить("Период", Новый СтандартныйПериод(ВариантСтандартногоПериода.ЭтотМесяц));
Данные.Вставить("Произвольный", Неопределено);// Произвольный тип
ПараметрыОткрытия = Новый Структура("Заголовок, Данные", "Тестовое заполнение", Данные);
ОписаниеОповещения = Новый ОписаниеОповещения("ПолучитьРезультат", ЭтотОбъект);
// vvvvvvvvvv Зависит от расположения формы
ОткрытьФорму("ОбщаяФорма.ВводЗначений", ПараметрыОткрытия,,,,, ОписаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ПолучитьРезультат(РезультатЗакрытия, ДопПараметры) Экспорт
Если РезультатЗакрытия <> Неопределено Тогда
Результат = "";
ОбработатьРезультат(РезультатЗакрытия);
Иначе
Результат = "Пользователь отменил ввод";
КонецЕсли;
КонецПроцедуры
Если передали заполненное значение - то оно используется как значение по умолчанию.
Для использования ссылочного типа нужно передать пустую или рабочую ссылку. Естественно, в этом случае значение должно быть возвращено с сервера или передаваемая структура должна быть заполнена на сервере.
Если нужен заголовок элемента "не в стиле переменных 1С", то передавать форме можно и соответствие или дополнительно указать заголовок.
Указание описания типов и свойств элементов
Свойства элементов формы задаются дополнительной коллекцией с одноименными ключами.
Свойства = Новый Соответствие;
Свойства.Вставить("Строка", Новый Структура("Заголовок, ПроверкаЗаполнения, Подсказка, ТипЗначения",
"ФИО", Истина, "В формате 'Фамилия И.О.'",
Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(35))));
Свойства.Вставить("Число", Новый Структура("Заголовок, ПроверкаЗаполнения", "Табельный №", Истина));
Свойства.Вставить("Булево", Новый Структура("Заголовок", "Вахта"));
Свойства.Вставить("Дата", Новый Структура("Заголовок, ТипЗначения", "Дата рождения",
Новый ОписаниеТипов("Дата",,, Новый КвалификаторыДаты(ЧастиДаты.Дата))));
Свойства.Вставить("Произвольный", Новый Структура("Заголовок, ТипЗначения, МногострочныйРежим",
"Комментарий", Новый ОписаниеТипов("Строка"), Истина));
ПараметрыОткрытия = Новый Структура("Заголовок, Данные, Свойства",
"Тестовое заполнение", Данные, Свойства);
В приведенном примере мы ограничили количество вводимых символов через квалификатор, установили обязательность заполнения и изменили некоторые свойства элементов.
Передавать свойства можно и в структуре, но тогда в передаваемых данных не должно быть соответствий с ключами "не в стиле переменных 1С" и массивов.
Так же имеется некоторое ограничение на свойства элементов: указать можно только свойства, значения которых соответствуют простым типам. Иначе получаем исключение по отсутствию отображения типа, несмотря на то что он доступен и на клиенте и на сервере. Обойти ограничение можно если заполнить такие свойства на сервере и поместить полученное соответствие во временное хранилище, а форме передать его адрес.
Группировка и прочие украшательства
Форма поддерживает вложенные друг в друга коллекции и автоматически их группирует для удобства. Есть ограничение: ключи должны быть уникальными, даже если находятся на разных уровнях вложенности. При задании свойств вложенность повторять не нужно. Для изменения свойств основной группы используется ключ "__root_group__". Для обхода ограничений отображения типа будем формировать список свойств на сервере.
&НаКлиенте
Процедура Протестировать(Команда)
Основное = Новый Структура;
Основное.Вставить("Наименование", "");
Основное.Вставить("Код", 0);
Основное.Вставить("ДатаРождения", Неопределено);
Основное.Вставить("Период", Новый СтандартныйПериод(ВариантСтандартногоПериода.ЭтотМесяц));
Основное.Вставить("Комментарий", "");
ДниНедели = Новый Массив;
ДниНедели.Добавить(Истина);
ДниНедели.Добавить(Истина);
ДниНедели.Добавить(Истина);
ДниНедели.Добавить(Истина);
ДниНедели.Добавить(Истина);
ДниНедели.Добавить(Ложь);
ДниНедели.Добавить(Ложь);
График = Новый Структура;
График.Вставить("Вахта", Ложь);
График.Вставить("Режим", "1/1");
График.Вставить("РабочиеДни", ДниНедели);
ПрочийМассив = Новый Массив;
ПрочийМассив.Добавить("Стр");
ПрочийМассив.Добавить("3,14");
ПрочийМассив.Добавить(Новый Структура("Ст1, Ст2"));
ПрочийМассив.Добавить(Новый Структура("Ст3, Ст4"));
Прочее = Новый Соответствие;
Прочее.Вставить("Цвет", Новый Цвет);
Прочее.Вставить("Шрифт", Новый Шрифт);
Прочее.Вставить("Свернутый массив", ПрочийМассив);
Данные = Новый Структура;
Данные.Вставить("Основное", Основное);
Данные.Вставить("График", График);
Данные.Вставить("Прочее", Прочее);
ПараметрыОткрытия = Новый Структура("Заголовок, Данные, Свойства",
"Тестовое заполнение", Данные, ПолучитьСвойства());
ОписаниеОповещения = Новый ОписаниеОповещения("ПолучитьРезультат", ЭтотОбъект);
ОткрытьФорму("ВнешняяОбработка.УниверсальныйВводЗначений.Форма.ВводЗначений", ПараметрыОткрытия,,,,, ОписаниеОповещения);
КонецПроцедуры
&НаСервере
Функция ПолучитьСвойства()
Свойства = Новый Соответствие;
Свойства.Вставить("__root_group__", Новый Структура("Группировка", ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда));
Свойства.Вставить("Основное", Новый Структура("Отображение, ОтображатьЗаголовок", ОтображениеОбычнойГруппы.Нет, Ложь));
Свойства.Вставить("Наименование", Новый Структура("Заголовок, ПроверкаЗаполнения, Подсказка, ТипЗначения",
"ФИО", Истина, "В формате 'Фамилия И.О.'",
Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(35))));
Свойства.Вставить("Код", Новый Структура("Заголовок, ПроверкаЗаполнения", "Табельный №", Истина));
Свойства.Вставить("Вахта", Новый Структура("Заголовок, Вид", "Вахта", ВидПоляФормы.ПолеФлажка));
Свойства.Вставить("ДатаРождения", Новый Структура("Заголовок, ТипЗначения", "Дата рождения",
Новый ОписаниеТипов("Дата",,, Новый КвалификаторыДаты(ЧастиДаты.Дата))));
Свойства.Вставить("Комментарий", Новый Структура("Заголовок, ТипЗначения, МногострочныйРежим", "Комментарий",
Новый ОписаниеТипов("Строка"), Истина));
Свойства.Вставить("РабочиеДни", Новый Структура("Заголовок", "Рабочие дни"));
Свойства.Вставить("РабочиеДни[0]", Новый Структура("Заголовок, Вид", "Пн.", ВидПоляФормы.ПолеФлажка));
Свойства.Вставить("РабочиеДни[1]", Новый Структура("Заголовок, Вид", "Вт.", ВидПоляФормы.ПолеФлажка));
Свойства.Вставить("РабочиеДни[2]", Новый Структура("Заголовок, Вид", "Ср.", ВидПоляФормы.ПолеФлажка));
Свойства.Вставить("РабочиеДни[3]", Новый Структура("Заголовок, Вид", "Чт.", ВидПоляФормы.ПолеФлажка));
Свойства.Вставить("РабочиеДни[4]", Новый Структура("Заголовок, Вид", "Пт.", ВидПоляФормы.ПолеФлажка));
Свойства.Вставить("РабочиеДни[5]", Новый Структура("Заголовок, Вид", "Сб.", ВидПоляФормы.ПолеФлажка));
Свойства.Вставить("РабочиеДни[6]", Новый Структура("Заголовок, Вид", "Вс.", ВидПоляФормы.ПолеФлажка));
Свойства.Вставить("Свернутый массив", Новый Структура("Поведение, Свернута, Заголовок, ЗаголовокСвернутогоОтображения",
ПоведениеОбычнойГруппы.Свертываемая, Истина, "[-] Свернутый массив", "[+] Свернутый массив"));
Список = Новый СписокЗначений;
Список.Добавить("1/1");
Список.Добавить("2/2");
Список.Добавить("2/3");
Свойства.Вставить("Режим", Новый Структура("РежимВыбораИзСписка, СписокВыбора", Истина, Список));
Возврат ПоместитьВоВременноеХранилище(Свойства);
КонецФункции
Проверено на следующих конфигурациях и релизах:
- Бухгалтерия предприятия КОРП, редакция 3.0, релизы 3.0.174.30