Красота, конечно, спасет мир, но, похоже, никто в этом мире не думает о спасении.
Версии обработки:
Версия 1.3 от 02.01.2018
+ добавлен показ типа "СписокЗначений" при показе дополнительных типов (вместе с типом "ДвоичныеДанные").
+ в группу типов "Системные перечисления" добавлен тип "СтатусСообщения".
+ добавлен показ типов ключей записей регистров учета (сведений, накопления, бухгалтерии и расчета)
( Рис.19.1, Рис.20.1, Рис.19.2, Рис.20.2 ).
+ добавлен показ типов менеджеров констант, а также типов объектов встроенных отчетов и обработок
(опция не имеет смысла для управляемой формы диалога из-за недоступности типов, Рис.19.1, Рис.20.1, Рис.19.2).
+ добавлена возможность испоьзования кратких названий групп ссылочных типов
("Справочники" вместо "СправочникСсылка").
+ добавлена возможность указания заголовка диалога, отличного от выводимого по умолчанию.
+ тип параметра открытия диалога "ТипыВВидеДерева" , определяющий представление списка типов,
изменен на числовой (с сохранением поведения для обратной совместимости):
0 - "список", 1 - "многоуровневое дерево", 2 - "одноуровневое дерево".
+ добавлена смена представления списка типов в диалоге с возможностью сохранения
выбранного значения в настройках формы-владельца, открывшей диалог ( Рис.19.3, Рис.20.3 ).
+ исправлены замеченные ошибки.
Версия 1.2 от 11.04.2016
+ поиск по строке в имени или синониме типа (Рис.18.1, Рис.18.4), ограничение поиска изначально отмеченными типами (Рис.18.2);
+ показ только отмеченных строк в списке типов (как особый режим поиска, Рис.18.3);
+ показ дополнительных типов "ХранилищеЗначения", "УникальныйИдентификатор" (в дополнение к "ДвоичныеДанные", Рис.18.5);
Версия 1.1 от 13.03.2016
+ в контекстное меню флага "Составной тип данных" добавлено два подменю:
- "Выбрать тип характеристик" (Рис.14.2, для установки в списке составного типа "Характеристика.ИмяПВХ")
- "Выбрать определяемый тип" (Рис.14.3, для установки в списке составного типа "ОпределяемыйТип.ИмяОТ")
Версия 1.0 от 17.02.2016 (Исходная)
Предыстория:
Здоровый консерватизм и врожденное стремление к прекрасному послужили причиной для появления данной разработки. Лично у меня (и думаю, что я не одинок) сравнение диалогов выбора типа в обычном и управляемом приложении всегда вызывает когнитивный диссонанс.
Примером для подражания и отправной точкой для работы послужила форма выбора типа объекта в известной обработке «Администратор 1С». К списку ссылочных типов формы были добавлены примитивные и прочие типы. Также были добавлены квалификаторы данных и режим редактирования составного типа. Общая функциональность и оформление формы были максимально приближены к системному диалогу (насколько это возможно при использовании стандартной библиотеки картинок).
Формы обработки:
- "DemoОбычное": Основная форма для обычного приложения (Рис.1),
служит для демонстрации использования альтернативного диалога выбора типа в режиме обычного приложения; - "DemoУправляемое": Основная форма для управляемого приложения (Рис.2),
служит для демонстрации использования альтернативного диалога выбора типа в режиме управляемого приложения; - "EditTypeОбычное": Служебная универсальная форма (Рис.3, Рис.4),
реализует функционал системного диалога редактирования/выбора типа для обычного приложения; - "EditTypeУправляемое": Служебная универсальная форма (Рис.5, Рис.6),
реализует функционал системного диалога редактирования/выбора типа для управляемого приложения;
Возможности альтернативных диалогов выбора типа:
1. Формы альтернативных диалогов максимально полно реализуют функциональность системного диалога редактирования/выбора типа обычного приложения (включая оформление).
2. Диалоги имеют двойной русско-английский интерфейс, инициализируемый программным образом при открытии формы. При разработке форм диалогов устранены некоторые корявости системного диалога и добавлены дополнительные интерфейсные удобства.
3. Формы альтернативных диалогов редактирования/выбора типа полностью самодостаточны и универсальны. Они могут использоваться как общие формы в составе любой конфигурации, так и в составе форм любого объекта метаданных.
4. Альтернативные диалоги редактирования/выбора типа поддерживают выбор основных типов данных, которые можно хранить в реквизитах объектов или форм и для которых есть штатные средства выбора значений (включая некоторые системные перечисления).
5. Также добавлена возможность (через параметры формы) включать в списке типов диалога показ типа "ДвоичныеДанные" (Рис.3, Рис.4, Рис.5, Рис.6). В настоящий момент эта возможность практической ценности не имеет (этот тип нельзя напрямую хранить в реквизитах объектов и форм). Возможность добавлена ради доступа к квалификаторам двоичных данных, которые появились у объекта "ОписаниеТипов" в платформе версии 8.3.
В диалоге при показе типа "ДвоичныеДанные" в списке типов диалога, также отображаются некоторые другие типы данных ( Рис.18.5):
- "ХранилищеЗначения"
- "УникальныйИдентификатор"
- "СписокЗначений"
6. Добавлена возможность (через параметры формы) включать в списке типов диалога показ
типов менеджеров значений констант и типов ключей записей регистров учета
( Рис.19.2, Рис.20.2 ):
- "КонстантаМенеджерЗначения.ИмяКонстанты"
- "РегистрСведенийКлючЗаписи.ИмяРегистра"
- "РегистрНакопленияКлючЗаписи.ИмяРегистра"
- "РегистрБухгалтерииКлючЗаписи.ИмяРегистра"
- "РегистрРасчетаКлючЗаписи.ИмяРегистра"
7. Формы диалогов могут работать как в режиме редактирования составного типа данных,
так и в режиме выбора типа текущего значения реквизита (из списка возможных типов,
определяемых описанием составного типа реквизита).
8. Через параметры формы диалогов полноценно поддерживаются следующие представления списка типов в диалоге:
- "Таблица значений" (Рис.7, Рис.8, только для управляемой формы диалога);
- "Одноуровневое дерево значений" (Рис.9, Рис.10);
- "Многоуровневое дерево значений" (Рис.11, Рис.12, действует по умолчанию);
Установленное при открытии представление списка типов можно изменить
из контекстного меню списка ( Рис.19.3, Рис.20.3 ).
При этом установленное значение представления сохраняется в реквизите формы-владельца диалога
(если через параметры формы диалога передано имя этого реквизита).
Также при успешном сохранении выполняется оповещение формы-владельца диалога
глобальным методом Оповестить() со следующими параметрами:
ИмяСобытия = "EditType.ТипыВВидеДерева.Смена"
Параметр = [выбранное значение представления списка: 0, 1, 2]
Источник = [ссылка на форму-владельца диалога]
Ответственность за дальнейшее сохранение/восстановление выбранного представления списка типов
возлагается на форму-владельца диалога.
9. Формы диалогов при закрытии с подтверждением возвращают значение типа "ОписаниеТипов", которое соответствует
отредактированному описанию типа или выбранному типу значения (с учетом квалификаторов данных).
При этом поддерживаются всевозможные режимы выбора значений в формах 1С
(определяется режимом открытия и установкой параметров формы диалога):
- "Модальный выбор"
- "Асинхронный выбор (обработка выбора)"
- "Асинхронный выбор (оповещение о закрытии)"
Примечание:
При использовании режима "Асинхронный выбор (обработка выбора)" в обработчике события "ОбработкаВыбора"
поля ввода может возникнуть неопределенная ситуация, если в составном типе реквизита использован тип "ОписаниеТипов".
А именно - как интерпретировать значение переменной ВыбранноеЗначение:
- Это выбрано ограничение типа реквизита (в диалоге выбора типа в режиме редактирования составного типа).
- Это выбран тип текущего значения реквизита (в диалоге выбора типа в режиме выбора типа).
- Это в поле ввода просто выбрано текущее значение реквизита типа "ОписаниеТипов".
В демонстрационных формах этой обработки считается:
- Если ВыбранноеЗначение - описание простого типа, то выбран тип текущего значения реквизита.
- Если ВыбранноеЗначение - описание составного типа, то выбрано текущее значение реквизита типа "ОписаниеТипов".
Дополнительные интерфейсные удобства:
- Во всех режимах выбора имеется возможность указания заголовка диалога
отличного от того, что выводится по умолчанию. - В режиме выбора типа значения:
- В режиме редактирования типа:
- При редактировании составного типа в списке типов доступны для пометки узлы групп типов.
При изменении пометки группы типов устанавливаются или снимаются метки со всех входящих в группу строк типов. - Пометка строки в списке типов для выбора (установки метки) при снятии флага "Составной тип данных" (Рис.13).
Строка помечается двойным кликом при установленном флаге и выделяется подчеркиванием.
- При редактировании составного типа в списке типов доступны для пометки узлы групп типов.
- Контекстное меню флага "Составной тип данных" (Рис.14.1, Рис.14.2, Рис.14.3), которое позволяет:
- а. Отметить все строки в списке типов для выбора;
- б. Сбросить метки выбора со всех строк списка типов;
- в. Выбрать один из “предопределенных” составных типов конфигурации:
- - Тип "ЛюбаяСсылка";
- - Тип "ВсеСсылки" указанного типа прикладных объектов;
- г. Выбрать составной тип одного из планов видов характеристик в конфигурации;
д. Выбрать один из определяемых типов в конфигурации (содержащих только поддерживаемые диалогом типы);
е. Восстановить исходное значение составного типа (переданное при открытии диалога);
- Контекстное меню списка типов диалога (Рис.15), которое позволяет:
- Включить/выключить режим показа имен типов (объектов) вместо их синонимов
(запоминаемая настройка диалога, по умолчанию - Истина); - Включить/выключить дополнительное оформление списка типов
(запоминаемая настройка диалога, по умолчанию - Ложь): - Сменить представление списка типов ( Рис.19.3, Рис.20.3 ):
- "список", "многоуровневое дерево", "одноуровневое дерево";
- Включить/выключить режим показа имен типов (объектов) вместо их синонимов
Особенности поиска в списке типов в альтернативном диалоге:
В диалоге (начиная с версии 1.2) имеется два режима поиска:
- Поиск по строке в имени или синониме типа - устанавливается при вводе символов в строке поиска над списком типов (Рис.18.1, Рис.18.4);
- Показ отмеченных строк списка (с текущей пометкой) - переключается нажатием на гиперссылку картинки справа от строки поиска (Рис.18.3);
Оба режима поиска доступны как при редактировании составного типа (Рис.18.1), так и при выборе текущего типа значения (Рис.18.4).
Поиск по строке в имени или синониме типа реализован на запросе к временной таблице списка типов с условием
на поле поиска ПОДОБНО шаблону поиска. Поле поиска выбирается в соответствии с установленным режимом
показа имен типов (объектов) вместо их синонимов.
При этом шаблон поиска строится по строке поиска следующим образом:
- В строке поиска слева и справа отсекаются конечные пробелы;
- Внутренние пробелы заменяются на символы процента "%";
- Двойные звездочки "**" заменяются на одинарные символы процента "%";
- Все кратные символы процента "%" заменяются на одинарные;
- Шаблон поиска дополняется слева и справа символами процента "%";
Специальные сочетания символов в строке поиска (вырезаются из шаблона и модифицируют условия поиска):
- Символы "^%" в начале строки поиска - отменяют дополнение шаблона поиска слева символом "%" (поиск ПОДОБНО СЛЕВА, Рис.18.4);
- Символы "^%" в конце строки поиска - отменяют дополнение шаблона поиска справа символом "%" (поиск ПОДОБНО СПРАВА, Рис.18.6);
- Символы "[]" ("пустой" диапазон символов) в любой части строки поиска - ограничивает поиск только изначально отмеченными строками списка (Рис.18.2);
Результаты поиска показываются в специальной таблице результатов поиска (в дереве значений).
Строки основного списка типов синхронизуются с таблицей результатов поиска при пометке и активизации его строк.
Быстрые клавиши, связанные с поиском в списке типов (Рис.18.6):
- Ctrl+Alt+M - активизировать строку поиска (также, как в системном диалоге);
- Ctrl+Shift+1 - включить/выключить режим показа только отмеченных строк списка;
- Ctrl+Shift+2 - очистить результаты поиска;
Использование альтернативных диалогов выбора типа:
- Режим редактирования типа требуется сравнительно редко, например, когда в реквизите типа "ОписаниеТипов"
задается дополнительное ограничение типа другого реквизита составного типа значения.
Для открытия альтернативного диалога выбора типа в этом случае можно использовать следующие события элементов формы:- Событие "НачалоВыбора" поля ввода формы (если описание типов редактируется напрямую);
- Событие "Нажатие" или процедура обработки команды формы (если описание типов редактируется кнопкой формы);
- Событие "Выбор" табличного поля формы (если описание типа редактируется при клике
по строке табличного поля в специально предусмотренной колонке);
- Режим выбора типа значения требуется значительно чаще (при редактировании в полях ввода реквизитов составного типа).
Для открытия альтернативного диалога выбора типа в режиме выбора типа можно использовать событие "НачалоВыбора"
поля ввода значения реквизита в форме, когда значение реквизита составного типа равно Неопределено
(системный диалог выбора типа открывается именно в этом случае).
Есть также другой удобный способ для программного открытия диалога выбора типа (Рис.1, Рис.2):
В обработчике события "Очистка" поля ввода
методами ЭтаФорма.ВыбратьИзСписка() или ЭтаФорма.ПоказатьВыборИзСписка()
выводить меню в виде выпадающего списка,
в котором предлагать пользователю следующие возможности:- "Выбрать тип значения" (выбрать текущий тип в альтернативном диалоге выбора);
- “Пустое значение” (установить реквизиту пустое значение текущего типа, если тип простой);
- "Очистить" (присвоить реквизиту значение Неопределено);
- Примеры использования альтернативных диалогов выбора типа смотрите ниже в приложениях к работе,
а также в исходном коде демонстрационных форм обработки.
Ограничения обратной совместимости:
- Под платформой 8.2 все формы этой обработки будут нормально работать в толстом и тонком клиентах.
- При работе на Web-клиенте под 8.2 будет ошибка компиляции модуля формы "EditTypeУправляемое"
из-за "открытого" использования глобального асинхронного метода ПоказатьПредупреждение() ,
появившегося только под платформой 8.3.
Проблема решается закомментариванием строки с вызовом этого метода на стороне Web-клиенте,
специально выделенной для этой цели инструкцией препроцессора.
- Под платформой 8.3.7 и выше в форме "EditTypeУправляемое"
при изменении представления списка типов с многоуровневого на одноуровневый и наоборот,
а также при включении/отключении режима показа только отмеченных строк в списке,
наблюдается неприятный визуальный эффект:
форма диалога "самостоятельно" увеличивает размер по вертикали и горизонтали.
Приложение 1 (Пример кода использования диалога в режиме обычного приложения):
Пояснения к примеру:
Объект – основной реквизит обработки;
ТестРеквизит – реквизит обработки составного типа (непосредственно редактируется в форме);
ТестРеквизитТип – дополнительное ограничение типа реквизита ТестРеквизит (непосредственно редактируется в форме);
Смысл остальных реквизитов ясен из их названия, пример ориентирован на платформу 8.3
// На клиенте обычного приложения
Процедура ТестРеквизитНачалоВыбора(Элемент, СтандартнаяОбработка)
Перем Оповещение;
Перем ПараметрыВыбора;
Если ТипЗнч(Объект.ТестРеквизит) = Тип("ОписаниеТипов") И Объект.СистемныйДиалог <> Истина Тогда
// выбираем значение описания типа в нашем красивом диалоге
СтандартнаяОбработка = Ложь;
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,Истина);
ТипОО = ТипIf("ОписаниеОповещения");
стПараметры = Новый Структура;
стПараметры.Вставить("ЗаголовокДиалога","");
стПараметры.Вставить("РежимВыбораТипаДанных",Ложь);
стПараметры.Вставить("ТипыВВидеДерева",Объект.ТипыВВидеДерева);
стПараметры.Вставить("ТипыВВидеДереваИмяРеквизита","Объект.ТипыВВидеДерева");
стПараметры.Вставить("ПоказыватьТипBD",Объект.ПоказыватьТипBD);
стПараметры.Вставить("ПоказыватьКонстанты",Объект.ПоказыватьКонстанты);
стПараметры.Вставить("ПоказыватьОтчетыОбработки",Объект.ПоказыватьОтчетыОбработки);
стПараметры.Вставить("ПоказыватьРегистры",Объект.ПоказыватьРегистры);
стПараметры.Вставить("КраткиеИменаГруппТипов",Объект.КраткиеИменаГруппТипов);
стПараметры.Вставить("ТипЗначения",Объект.ТестРеквизит);
стПараметры.Вставить("ТекущийТип",Неопределено);
Если Объект.РежимВыбораТипа = "МодальныйВыбор" Тогда
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное");
Диалог.ФормаВладелец = ЭтаФорма;
Диалог.ОписаниеОповещенияОЗакрытии = Неопределено;
Диалог.Параметры = стПараметры;;
ВыбранноеЗначение = Диалог.ОткрытьМодально(180);
Если ВыбранноеЗначение <> Неопределено Тогда
ТестРеквизитПриВыбореЗначения(ВыбранноеЗначение,ПараметрыВыбора);
КонецЕсли;
ИначеЕсли Объект.РежимВыбораТипа = "ОбработкаВыбора" Тогда
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное",Элемент,ЭтаФорма);
Диалог.ФормаВладелец = ЭтаФорма;
Диалог.ОписаниеОповещенияОЗакрытии = Неопределено;
Диалог.Параметры = стПараметры;;
Диалог.Открыть();
ИначеЕсли Объект.РежимВыбораТипа = "ОповещениеОЗакрытии" И ТипОО <> Null Тогда
мсПараметры = Новый Массив;
мсПараметры.Добавить("ТестРеквизитПриВыбореЗначения");
мсПараметры.Добавить(ЭтаФорма);
мсПараметры.Добавить(ПараметрыВыбора);
Оповещение = Новый(ТипОО,мсПараметры);
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное",Неопределено,ЭтаФорма);
Диалог.ФормаВладелец = ЭтаФорма;
Диалог.ОписаниеОповещенияОЗакрытии = Оповещение;
Диалог.Параметры = стПараметры;;
Диалог.Открыть();
КонецЕсли;
ИначеЕсли Объект.ТестРеквизит = Неопределено И Объект.СистемныйДиалог <> Истина Тогда
// по нажатию кнопки выбора типа - выбираем тип значения в поле ввода в нашем красивом диалоге
СтандартнаяОбработка = Ложь;
ТестРеквизитВыбратьТип(Элемент,Объект.ТестРеквизит,Объект.ТестРеквизитТип,Ложь);
Иначе
КонецЕсли;
КонецПроцедуры
Процедура ТестРеквизитОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
Если ТипЗнч(ВыбранноеЗначение) = Тип("ОписаниеТипов") И Объект.РежимВыбораТипа = "ОбработкаВыбора"
И ВыбранноеЗначение.Типы().Количество() = 1 Тогда
// из формы выбора прилетело значение "ОписаниеТипов" простого типа -
// - считаем, что в диалоге выбора типа выбран текущий тип значения реквизита
СтандартнаяОбработка = Ложь;
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,Ложь);
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора);
Иначе
// из формы выбора прилетело значение, отличное от "ОписаниеТипов" простого типа -
// - считаем, что в форме выбора выбрано значение реквизита
СтандартнаяОбработка = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ТестРеквизитОчистка(Элемент, СтандартнаяОбработка)
Перем Оповещение;
Перем ПараметрыОповещения;
СтандартнаяОбработка = Ложь;
ТипОО = ТипIf("ОписаниеОповещения");
ПараметрыОповещения = Новый Структура("Элемент",Элемент);
Меню = Новый СписокЗначений;
Меню.Добавить(1, НСтр("ru = 'Выбрать тип значения'; en = 'Select data type'"),,БиблиотекаКартинок.ВыбратьТип);
Если (Объект.ТестРеквизитТип.Типы().Количество()=1) Тогда
Меню.Добавить(2, НСтр("ru = 'Пустое значение'; en = 'Empty value'"),,БиблиотекаКартинок.Выбрать);
КонецЕсли;
Выбор0 = Меню.Добавить(0, НСтр("ru = 'Очистить'; en = 'Clear'"),,БиблиотекаКартинок.Очистить);
Если Объект.РежимВыбораТипа <> "МодальныйВыбор" И ТипЗнч(ЭтаФорма) = ТипIf("УправляемаяФорма") И ТипОО <> Null Тогда
мсПараметры = Новый Массив;
мсПараметры.Добавить("ТестРеквизитОчисткаПродолжение");
мсПараметры.Добавить(ЭтаФорма);
мсПараметры.Добавить(ПараметрыОповещения);
Оповещение = Новый(ТипОО,мсПараметры);
ЭтаФорма.ПоказатьВыборИзСписка(Оповещение,Меню,Элемент,Выбор0);
Иначе
Выбор = ЭтаФорма.ВыбратьИзСписка(Меню,Элемент,Выбор0);
ТестРеквизитОчисткаПродолжение(Выбор, ПараметрыОповещения);
КонецЕсли;
КонецПроцедуры
Процедура ТестРеквизитОчисткаПродолжение(Выбор, ПараметрыОповещения) Экспорт
Перем Элемент;
Если Выбор = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ПараметрыОповещения) = Тип("Структура") Тогда
ПараметрыОповещения.Свойство("Элемент",Элемент);
КонецЕсли;
Если Выбор.Значение = 0 Тогда
Объект.ТестРеквизит = Неопределено;
ТестРеквизитПриИзменении(Элемент);
ИначеЕсли Выбор.Значение = 2 Тогда
Объект.ТестРеквизит = Объект.ТестРеквизитТип.ПривестиЗначение(Неопределено);
ТестРеквизитПриИзменении(Элемент);
ИначеЕсли Выбор.Значение = 1 Тогда
ТестРеквизитВыбратьТип(Элемент,Объект.ТестРеквизит,Объект.ТестРеквизитТип,Ложь);
КонецЕсли;
КонецПроцедуры
Процедура ТестРеквизитВыбратьТип(Элемент,Значение,ТипЗначения,ЭтоРедактированиеТипаДанных)
Перем Оповещение;
Перем ПараметрыВыбора;
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,ЭтоРедактированиеТипаДанных);
ТипОО = ТипIf("ОписаниеОповещения");
Если ТипЗнч(ТипЗначения.ПривестиЗначение(Значение)) = ТипЗнч(Значение) Тогда
ТекущийТип = ТипЗнч(Значение);
Иначе // для простых типов "двоичные данные", "хранилище значения" и "ключ записи регистра учета"
// - результат приведения значения почему-то строковое значение
ТекущийТип = ТипЗнч(Неопределено);
КонецЕсли;
// установка параметров диалога
стПараметры = Новый Структура;
// 1. Заголовок диалога редактирования/выбора типа
// по умолчанию: "Редактирование типа данных"/"Выбор типа данных"
стПараметры.Вставить("ЗаголовокДиалога","");
// 2. Режим работы диалога редактирования/выбора типа (обязателен!)
стПараметры.Вставить("РежимВыбораТипаДанных",(ЭтоРедактированиеТипаДанных <> Истина));
// 3. Представление списка типов в диалоге (по умолчанию - многоуровневое "ДеревоЗначений")
стПараметры.Вставить("ТипыВВидеДерева",Объект.ТипыВВидеДерева);
// 4. Путь в данных формы для сохранения измененного в диалоге представления списка типов
стПараметры.Вставить("ТипыВВидеДереваИмяРеквизита","Объект.ТипыВВидеДерева");
// 5. Признак показа в диалоге дополнительных типов "ДвоичныеДанные", "СписокЗначений" и т.п.
// (параметр добавлен для доступа к квалификаторам двоичных данных)
стПараметры.Вставить("ПоказыватьТипBD",Объект.ПоказыватьТипBD);
// 6. Признак показа в диалоге типов менелжеров записи значений констант
// (недоступно на клиенте в управляемом приложения!)
стПараметры.Вставить("ПоказыватьКонстанты",Объект.ПоказыватьКонстанты);
// 7. Признак показа в диалоге типов объектов отчетов и обработок
// (недоступно на клиенте в управляемом приложения!)
стПараметры.Вставить("ПоказыватьОтчетыОбработки",Объект.ПоказыватьОтчетыОбработки);
// 8. Признак показа в диалоге типов ключей записей регистров учета
стПараметры.Вставить("ПоказыватьРегистры",Объект.ПоказыватьРегистры);
// 9. Признак показа кратких имен групп ссылочных типов данных
// (например, "Справочник" вместо "СправочникСсылка")
стПараметры.Вставить("КраткиеИменаГруппТипов",Объект.КраткиеИменаГруппТипов);
//10. Составной тип данных для редактирования или для выбора текущего типа значения реквизита
// (обязателен!)
стПараметры.Вставить("ТипЗначения",ТипЗначения);
//11. Тип, определяющий текущую строку в списке типов при открытии
// (в режиме редактирования типа можно не указывать)
стПараметры.Вставить("ТекущийТип",ТекущийТип);
Если Объект.РежимВыбораТипа = "МодальныйВыбор" Тогда
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное");
//12. Параметр для имитации блокировки окна владельца диалога
Диалог.ФормаВладелец = ЭтаФорма;
//13. Параметр для имитации оповещения о закрытии диалога
Диалог.ОписаниеОповещенияОЗакрытии = Неопределено;
Диалог.Параметры = стПараметры;;
ВыбранноеЗначение = Диалог.ОткрытьМодально(180);
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора);
ИначеЕсли Объект.РежимВыбораТипа = "ОбработкаВыбора" Тогда
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное",Элемент,ЭтаФорма);
//12. Параметр для имитации блокировки окна владельца диалога
Диалог.ФормаВладелец = ЭтаФорма;
//13. Параметр для имитации оповещения о закрытии диалога
Диалог.Параметры = стПараметры;;
Диалог.Открыть();
ИначеЕсли Объект.РежимВыбораТипа = "ОповещениеОЗакрытии" И ТипОО <> Null Тогда
мсПараметры = Новый Массив;
мсПараметры.Добавить("ТестРеквизитПриВыбореТипаЗначения");
мсПараметры.Добавить(ЭтаФорма);
мсПараметры.Добавить(ПараметрыВыбора);
Оповещение = Новый(ТипОО,мсПараметры);
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное",Неопределено,ЭтаФорма);
//12. Параметр для имитации блокировки окна владельца диалога
Диалог.ФормаВладелец = ЭтаФорма;
//12. Параметр для имитации оповещения о закрытии диалога
Диалог.ОписаниеОповещенияОЗакрытии = Оповещение;
Диалог.Параметры = стПараметры;;
Диалог.Открыть();
КонецЕсли;
КонецПроцедуры
Процедура ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора) Экспорт
Перем Элемент;
Перем ЭтоРедактированиеТипаДанных;
Если ТипЗнч(ПараметрыВыбора) = Тип("Структура") Тогда
ПараметрыВыбора.Свойство("Элемент",Элемент);
ПараметрыВыбора.Свойство("ЭтоРедактированиеТипаДанных",ЭтоРедактированиеТипаДанных);
КонецЕсли;
Если ТипЗнч(ВыбранноеЗначение) <> Тип("ОписаниеТипов") Тогда
Возврат;
КонецЕсли;
Если ЭтоРедактированиеТипаДанных = Истина Тогда
Объект.ТестРеквизитТип = ВыбранноеЗначение;
КонецЕсли;
Объект.ТестРеквизит = ВыбранноеЗначение.ПривестиЗначение(Объект.ТестРеквизит);
ТестРеквизитПриИзменении(ЭлементыФормы.ТестРеквизит);
КонецПроцедуры
Процедура ТестРеквизитПриВыбореЗначения(ВыбранноеЗначение,ПараметрыВыбора) Экспорт
Перем Элемент;
Перем ЭтоРедактированиеТипаДанных;
Если ТипЗнч(ПараметрыВыбора) = Тип("Структура") Тогда
ПараметрыВыбора.Свойство("Элемент",Элемент);
ПараметрыВыбора.Свойство("ЭтоРедактированиеТипаДанных",ЭтоРедактированиеТипаДанных);
КонецЕсли;
Объект.ТестРеквизит = ВыбранноеЗначение;
ТестРеквизитПриИзменении(ЭлементыФормы.ТестРеквизит);
КонецПроцедуры
Процедура ТестРеквизитПриИзменении(Элемент)
ПолеФормыКонтрольТипЗначения(Элемент,Объект.ТестРеквизитТип,Объект.ТестРеквизит);
КонецПроцедуры
Процедура ПолеФормыКонтрольТипЗначения(Элемент,ТипЗначения,Значение)
СтрФорматЧ = "";
ПЧ = Неопределено;
Если ТипЗначения.СодержитТип(Тип("Число")) Тогда
ДЛ = ТипЗначения.КвалификаторыЧисла.Разрядность;
ТЧ = ТипЗначения.КвалификаторыЧисла.РазрядностьДробнойЧасти;
ПЧ = (ТипЗначения.КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный);
СтрФорматЧ = "ЧЦ="+Формат(ДЛ,"ЧДЦ=; ЧН=; ЧГ=0")+"; ЧДЦ="+Формат(ТЧ,"ЧДЦ=; ЧН=; ЧГ=0");
КонецЕсли;
СтрФорматД = "";
Если ТипЗначения.СодержитТип(Тип("Дата")) Тогда
ТЧ = ТипЗначения.КвалификаторыДаты.ЧастиДаты;
Если ТЧ = ЧастиДаты.Дата Тогда
СтрФорматД = "ДЛФ=D";
ИначеЕсли ТЧ = ЧастиДаты.Время Тогда
СтрФорматД = "ДЛФ=T";
КонецЕсли;
КонецЕсли;
СтрФормат = СтрФорматЧ +
?(ЗначениеЗаполнено(СтрФорматЧ) И ЗначениеЗаполнено(СтрФорматД),"; ","") + СтрФорматД;
Попытка
Элемент.Формат = СтрФормат;
Исключение
КонецПопытки;
Если ТипЗнч(Значение) = Тип("Число") И ПЧ = Истина И Значение < 0 Тогда
// контроль положительности числа по ограничениям в типе данных
Значение = -Значение;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Число") ИЛИ ТипЗнч(Значение) = Тип("Строка")
ИЛИ ТипЗнч(Значение) = Тип("Дата") ИЛИ ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
// контроль длины и точности значения по ограничениям в типе данных
Значение = ТипЗначения.ПривестиЗначение(Значение);
КонецЕсли;
Элемент.ВыбиратьТип = (Значение = Неопределено);
КонецПроцедуры
Приложение 2 (пример кода использования диалога в режиме управляемого приложения):
Пояснения к примеру:
Объект – основной реквизит обработки;
ТестРеквизит – реквизит обработки составного типа (непосредственно редактируется в форме);
ТестРеквизитТип – дополнительное ограничение типа реквизита ТестРеквизит (непосредственно редактируется в форме);
Смысл остальных реквизитов ясен из их названия, пример ориентирован на платформу 8.3.
// На клиенте управляемого приложения
&НаКлиенте
Процедура ТестРеквизитНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
Перем Оповещение;
Перем ПараметрыВыбора;
Если ТипЗнч(Объект.ТестРеквизит) = Тип("ОписаниеТипов") И Объект.СистемныйДиалог <> Истина Тогда
// выбираем значение описания типа в нашем красивом диалоге
СтандартнаяОбработка = Ложь;
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,Истина);
ТипОО = ТипIf("ОписаниеОповещения");
стПараметры = Новый Структура;
стПараметры.Вставить("ЗаголовокДиалога","");
стПараметры.Вставить("РежимВыбораТипаДанных",Ложь);
стПараметры.Вставить("ТипыВВидеДерева",Объект.ТипыВВидеДерева);
стПараметры.Вставить("ТипыВВидеДереваИмяРеквизита","Объект.ТипыВВидеДерева");
стПараметры.Вставить("ПоказыватьТипBD",Объект.ПоказыватьТипBD);
стПараметры.Вставить("ПоказыватьКонстанты",Объект.ПоказыватьКонстанты);
стПараметры.Вставить("ПоказыватьОтчетыОбработки",Объект.ПоказыватьОтчетыОбработки);
стПараметры.Вставить("ПоказыватьРегистры",Объект.ПоказыватьРегистры);
стПараметры.Вставить("КраткиеИменаГруппТипов",Объект.КраткиеИменаГруппТипов);
стПараметры.Вставить("ТипЗначения",Объект.ТестРеквизит);
стПараметры.Вставить("ТекущийТип",Неопределено);
Если Объект.РежимВыбораТипа = "МодальныйВыбор" Тогда
ВыбранноеЗначение = ОткрытьФормуМодально(ПутьКФорме+"EditTypeУправляемое",стПараметры);
Если ВыбранноеЗначение <> Неопределено Тогда
ТестРеквизитПриВыбореЗначения(ВыбранноеЗначение,ПараметрыВыбора);
КонецЕсли;
ИначеЕсли Объект.РежимВыбораТипа = "ОбработкаВыбора" Тогда
ОткрытьФорму(ПутьКФорме+"EditTypeУправляемое",стПараметры,Элемент,ЭтаФорма);
ИначеЕсли Объект.РежимВыбораТипа = "ОповещениеОЗакрытии" И ТипОО <> Null Тогда
мсПараметры = Новый Массив;
мсПараметры.Добавить("ТестРеквизитПриВыбореЗначения");
мсПараметры.Добавить(ЭтаФорма);
мсПараметры.Добавить(ПараметрыВыбора);
Оповещение = Новый(ТипОО,мсПараметры);
#Если ВебКлиент Тогда
Диалог = Вычислить("ОткрытьФорму(ПутьКФорме+""EditTypeУправляемое"",стПараметры,Неопределено,ЭтаФорма,,,Оповещение)");
#Иначе
Выполнить("ОткрытьФорму(ПутьКФорме+""EditTypeУправляемое"",стПараметры,Неопределено,ЭтаФорма,,,Оповещение)");
#КонецЕсли
КонецЕсли;
ИначеЕсли Объект.ТестРеквизит = Неопределено И Объект.СистемныйДиалог <> Истина Тогда
// при выборе типа - выбираем тип значения в поле ввода в нашем красивом диалоге
СтандартнаяОбработка = Ложь;
ТестРеквизитВыбратьТип(Элемент,Объект.ТестРеквизит,Объект.ТестРеквизитТип,Ложь);
Иначе
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТестРеквизитОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
Если ТипЗнч(ВыбранноеЗначение) = Тип("ОписаниеТипов") И Объект.РежимВыбораТипа = "ОбработкаВыбора"
И ВыбранноеЗначение.Типы().Количество() = 1 Тогда
// из формы выбора прилетело значение "ОписаниеТипов" простого типа -
// - считаем, что в диалоге выбора типа выбран текущий тип значения реквизита
СтандартнаяОбработка = Ложь;
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,Ложь);
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора);
Иначе
// из формы выбора прилетело значение, отличное от "ОписаниеТипов" простого типа -
// - считаем, что в форме выбора выбрано значение реквизита
СтандартнаяОбработка = Истина;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТестРеквизитОчистка(Элемент, СтандартнаяОбработка)
Перем Оповещение;
Перем ПараметрыОповещения;
СтандартнаяОбработка = Ложь;
ТипОО = ТипIf("ОписаниеОповещения");
ПараметрыОповещения = Новый Структура("Элемент",Элемент);
Меню = Новый СписокЗначений;
Меню.Добавить(1, НСтр("ru = 'Выбрать тип значения'; en = 'Select data type'"),,БиблиотекаКартинок.ВыбратьТип);
Если (Объект.ТестРеквизитТип.Типы().Количество()=1) Тогда
Меню.Добавить(2, НСтр("ru = 'Пустое значение'; en = 'Empty value'"),,БиблиотекаКартинок.Выбрать);
КонецЕсли;
Выбор0 = Меню.Добавить(0, НСтр("ru = 'Очистить'; en = 'Clear'"),,БиблиотекаКартинок.Очистить);
Если Объект.РежимВыбораТипа <> "МодальныйВыбор" И ТипЗнч(ЭтаФорма) = ТипIf("УправляемаяФорма") И ТипОО <> Null Тогда
мсПараметры = Новый Массив;
мсПараметры.Добавить("ТестРеквизитОчисткаПродолжение");
мсПараметры.Добавить(ЭтаФорма);
мсПараметры.Добавить(ПараметрыОповещения);
Оповещение = Новый(ТипОО,мсПараметры);
ЭтаФорма.ПоказатьВыборИзСписка(Оповещение,Меню,Элемент,Выбор0);
Иначе
Выбор = ЭтаФорма.ВыбратьИзСписка(Меню,Элемент,Выбор0);
ТестРеквизитОчисткаПродолжение(Выбор, ПараметрыОповещения);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТестРеквизитОчисткаПродолжение(Выбор, ПараметрыОповещения) Экспорт
Перем Элемент;
Если Выбор = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ПараметрыОповещения) = Тип("Структура") Тогда
ПараметрыОповещения.Свойство("Элемент",Элемент);
КонецЕсли;
Если Выбор.Значение = 0 Тогда
Объект.ТестРеквизит = Неопределено;
ТестРеквизитПриИзменении(Элемент);
ИначеЕсли Выбор.Значение = 2 Тогда
Объект.ТестРеквизит = Объект.ТестРеквизитТип.ПривестиЗначение(Неопределено);
ТестРеквизитПриИзменении(Элемент);
ИначеЕсли Выбор.Значение = 1 Тогда
ТестРеквизитВыбратьТип(Элемент,Объект.ТестРеквизит,Объект.ТестРеквизитТип,Ложь);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТестРеквизитВыбратьТип(Элемент,Значение,ТипЗначения,ЭтоРедактированиеТипаДанных)
Перем Оповещение;
Перем ПараметрыВыбора;
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,ЭтоРедактированиеТипаДанных);
ТипОО = ТипIf("ОписаниеОповещения");
Если ТипЗнч(ТипЗначения.ПривестиЗначение(Значение)) = ТипЗнч(Значение) Тогда
ТекущийТип = ТипЗнч(Значение);
Иначе // для простых типов "двоичные данные", "хранилище значения" и "ключ записи регистра учета"
// - результат приведения значения почему-то строковое значение
ТекущийТип = ТипЗнч(Неопределено);
КонецЕсли;
// установка параметров диалога
стПараметры = Новый Структура;
// 1. Заголовок диалога редактирования/выбора типа
// по умолчанию: "Редактирование типа данных"/"Выбор типа данных"
стПараметры.Вставить("ЗаголовокДиалога","");
// 2. Режим работы диалога редактирования/выбора типа (обязателен!)
стПараметры.Вставить("РежимВыбораТипаДанных",(ЭтоРедактированиеТипаДанных <> Истина));
// 3. Представление списка типов в диалоге (по умолчанию - многоуровневое "ДеревоЗначений")
стПараметры.Вставить("ТипыВВидеДерева",Объект.ТипыВВидеДерева);
// 4. Путь в данных формы для сохранения измененного в диалоге представления списка типов
стПараметры.Вставить("ТипыВВидеДереваИмяРеквизита","Объект.ТипыВВидеДерева");
// 5. Признак показа в диалоге дополнительных типов "ДвоичныеДанные", "СписокЗначений" и т.п.
// (параметр добавлен для доступа к квалификаторам двоичных данных)
стПараметры.Вставить("ПоказыватьТипBD",Объект.ПоказыватьТипBD);
// 6. Признак показа в диалоге типов менелжеров записи значений констант
// (недоступно на клиенте в управляемом приложения!)
стПараметры.Вставить("ПоказыватьКонстанты",Объект.ПоказыватьКонстанты);
// 7. Признак показа в диалоге типов объектов отчетов и обработок
// (недоступно на клиенте в управляемом приложения!)
стПараметры.Вставить("ПоказыватьОтчетыОбработки",Объект.ПоказыватьОтчетыОбработки);
// 8. Признак показа в диалоге типов ключей записей регистров учета
стПараметры.Вставить("ПоказыватьРегистры",Объект.ПоказыватьРегистры);
// 9. Признак показа кратких имен групп ссылочных типов данных
// (например, "Справочник" вместо "СправочникСсылка")
стПараметры.Вставить("КраткиеИменаГруппТипов",Объект.КраткиеИменаГруппТипов);
//10. Составной тип данных для редактирования или для выбора текущего типа значения реквизита
// (обязателен!)
стПараметры.Вставить("ТипЗначения",ТипЗначения);
//11. Тип, определяющий текущую строку в списке типов при открытии
// (в режиме редактирования типа можно не указывать)
стПараметры.Вставить("ТекущийТип",ТекущийТип);
Если Объект.РежимВыбораТипа = "МодальныйВыбор" Тогда
ВыбранноеЗначение = ОткрытьФормуМодально(ПутьКФорме+"EditTypeУправляемое",стПараметры);
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора);
ИначеЕсли Объект.РежимВыбораТипа = "ОбработкаВыбора" Тогда
ОткрытьФорму(ПутьКФорме+"EditTypeУправляемое",стПараметры,Элемент,ЭтаФорма);
ИначеЕсли Объект.РежимВыбораТипа = "ОповещениеОЗакрытии" И ТипОО <> Null Тогда
мсПараметры = Новый Массив;
мсПараметры.Добавить("ТестРеквизитПриВыбореТипаЗначения");
мсПараметры.Добавить(ЭтаФорма);
мсПараметры.Добавить(ПараметрыВыбора);
Оповещение = Новый(ТипОО,мсПараметры);
#Если ВебКлиент Тогда
Диалог = Вычислить("ОткрытьФорму(ПутьКФорме+""EditTypeУправляемое"",стПараметры,Неопределено,ЭтаФорма,,,Оповещение)");
#Иначе
Выполнить("ОткрытьФорму(ПутьКФорме+""EditTypeУправляемое"",стПараметры,Неопределено,ЭтаФорма,,,Оповещение)");
#КонецЕсли
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора) Экспорт
Перем Элемент;
Перем ЭтоРедактированиеТипаДанных;
Если ТипЗнч(ПараметрыВыбора) = Тип("Структура") Тогда
ПараметрыВыбора.Свойство("Элемент",Элемент);
ПараметрыВыбора.Свойство("ЭтоРедактированиеТипаДанных",ЭтоРедактированиеТипаДанных);
КонецЕсли;
Если ТипЗнч(ВыбранноеЗначение) <> Тип("ОписаниеТипов") Тогда
Возврат;
КонецЕсли;
Если ЭтоРедактированиеТипаДанных = Истина Тогда
Объект.ТестРеквизитТип = ВыбранноеЗначение;
КонецЕсли;
Объект.ТестРеквизит = ВыбранноеЗначение.ПривестиЗначение(Объект.ТестРеквизит);
ТестРеквизитПриИзменении(Элементы.ТестРеквизит);
КонецПроцедуры
&НаКлиенте
Процедура ТестРеквизитПриВыбореЗначения(ВыбранноеЗначение,ПараметрыВыбора) Экспорт
Перем Элемент;
Перем ЭтоРедактированиеТипаДанных;
Если ТипЗнч(ПараметрыВыбора) = Тип("Структура") Тогда
ПараметрыВыбора.Свойство("Элемент",Элемент);
ПараметрыВыбора.Свойство("ЭтоРедактированиеТипаДанных",ЭтоРедактированиеТипаДанных);
КонецЕсли;
Объект.ТестРеквизит = ВыбранноеЗначение;
ТестРеквизитПриИзменении(Элемент);
КонецПроцедуры
&НаКлиенте
Процедура ТестРеквизитПриИзменении(Элемент)
ПолеФормыКонтрольТипЗначения(Элемент,Объект.ТестРеквизитТип,Объект.ТестРеквизит);
КонецПроцедуры
&НаКлиенте
Процедура ПолеФормыКонтрольТипЗначения(Элемент,ТипЗначения,Значение)
СтрФорматЧ = "";
ПЧ = Неопределено;
Если ТипЗначения.СодержитТип(Тип("Число")) Тогда
ДЛ = ТипЗначения.КвалификаторыЧисла.Разрядность;
ТЧ = ТипЗначения.КвалификаторыЧисла.РазрядностьДробнойЧасти;
ПЧ = (ТипЗначения.КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный);
СтрФорматЧ = "ЧЦ="+Формат(ДЛ,"ЧДЦ=; ЧН=; ЧГ=0")+"; ЧДЦ="+Формат(ТЧ,"ЧДЦ=; ЧН=; ЧГ=0");
КонецЕсли;
СтрФорматД = "";
Если ТипЗначения.СодержитТип(Тип("Дата")) Тогда
ТЧ = ТипЗначения.КвалификаторыДаты.ЧастиДаты;
Если ТЧ = ЧастиДаты.Дата Тогда
СтрФорматД = "ДЛФ=D";
ИначеЕсли ТЧ = ЧастиДаты.Время Тогда
СтрФорматД = "ДЛФ=T";
КонецЕсли;
КонецЕсли;
СтрФормат = СтрФорматЧ +
?(ЗначениеЗаполнено(СтрФорматЧ) И ЗначениеЗаполнено(СтрФорматД),"; ","") + СтрФорматД;
Попытка
Элемент.Формат = СтрФормат;
Исключение
КонецПопытки;
Попытка
Элемент.ФорматРедактирования = СтрФормат;
Исключение
КонецПопытки;
Если ТипЗнч(Значение) = Тип("Число") И ПЧ = Истина И Значение < 0 Тогда
// контроль положительности числа по ограничениям в типе данных
Значение = -Значение;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Число") ИЛИ ТипЗнч(Значение) = Тип("Строка")
ИЛИ ТипЗнч(Значение) = Тип("Дата") ИЛИ ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
// контроль длины и точности значения по ограничениям в типе данных
Значение = ТипЗначения.ПривестиЗначение(Значение);
КонецЕсли;
Элемент.ВыбиратьТип = (Значение = Неопределено);
КонецПроцедуры