gifts2017

Простые радости жизни программиста 1С: выбор типа значения

Опубликовал Юрий Осипов (yuraos) в раздел Программирование - Работа с интерфейсом

Предлагаемая в работе обработка включает обычную и управляемую формы, которые максимально точно реализуют функциональность системного диалога выбора типа в толстом клиенте обычное приложение (включая оформление диалога).
Эти формы имеют дополнительные интерфейсные удобства и могут быть использованы  в качестве альтернативных диалогов выбора типа.


Красота, конечно, спасет мир, но, похоже, никто в этом мире не думает о спасении.


Версии обработки:

Версия 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.

В диалоге начиная с версии 1.2 при показе типа  "ДвоичныеДанные" в списке типов диалога, также отображаются некоторые другие типы данных,
не имеющие штатных средств редактирования ( Рис.18.5):

  • "ХранилищеЗначения"
  • "УникальныйИдентификатор"

6. Формы диалогов могут работать как в режиме редактирования составного типа данных, так и в режиме выбора типа текущего значения реквизита (из списка возможных типов, определяемых описанием составного типа реквизита).

7. Через параметры формы диалогов полноценно поддерживаются следующие представления списка типов в диалоге:

  • "Таблица значений" (Рис.7, Рис.8, только для управляемой формы диалога);
  • "Одноуровневое дерево значений" (Рис.9, Рис.10);
  • "Многоуровневое дерево значений" (Рис.11, Рис.12, действует по умолчанию);

8. Формы диалогов при закрытии с подтверждением возвращают значение типа "ОписаниеТипов", которое соответствует отредактированному описанию типа или выбранному типу значения (с учетом квалификаторов данных).

При этом поддерживаются всевозможные режимы выбора значений в формах 1С

(определяется режимом открытия и установкой параметров формы диалога):

  • "Модальный выбор"
  • "Асинхронный выбор (обработка выбора)"
  • "Асинхронный выбор (оповещение о закрытии)"

Примечание:
При использовании режима  "Асинхронный выбор (обработка выбора)" в обработчике события "ОбработкаВыбора" поля ввода может возникнуть неопределенная ситуация, если в составном типе реквизита использован тип "ОписаниеТипов".

А именно - как интерпретировать значение переменной ВыбранноеЗначение:
- Это выбрано ограничение типа реквизита (в диалоге выбора типа в режиме редактирования составного типа).
- Это выбран тип текущего значения реквизита (в диалоге выбора типа в режиме выбора типа).
- Это в поле ввода просто выбрано текущее значение реквизита типа "ОписаниеТипов".

В демонстрационных формах этой обработки считается:
- Если ВыбранноеЗначение - описание простого типа, то выбран тип текущего значения реквизита.
- Если ВыбранноеЗначение - описание составного типа, то выбрано текущее значение реквизита типа "ОписаниеТипов".


Дополнительные интерфейсные удобства:

  1. В режиме выбора типа значения:
    • Показ квалификаторов примитивных тиров данных (Рис.4, Рис.6) аналогично тому, как в режиме редактирования, но только для просмотра;
  2. В режиме редактирования типа:
    • При редактировании составного типа в списке типов доступны для пометки узлы групп типов. При изменении пометки группы типов устанавливаются или снимаются метки со всех входящих в группу строк типов.
    • Пометка строки в списке типов для выбора (установки метки) при снятии флага "Составной тип данных" (Рис.13).
      Строка помечается двойным кликом при установленном флаге и выделяется подчеркиванием.
  3. Контекстное меню флага "Составной тип данных" (Рис.14.1, Рис.14.2, Рис.14.3), которое позволяет:
    • а. Отметить все строки в списке типов для выбора;
    • б. Сбросить метки выбора со всех строк списка типов;
    • в. Выбрать один из “предопределенных” составных типов конфигурации:
      • - Тип "ЛюбаяСсылка";
      • - Тип "ВсеСсылки" указанного типа прикладных объектов;
    • г. Выбрать составной тип одного из планов видов характеристик в конфигурации;
      д. Выбрать один из определяемых типов в конфигурации (содержащих только поддерживаемые диалогом типы);
      е. Восстановить исходное значение составного типа (переданное при открытии диалога);
  4. Контекстное меню списка типов диалога (Рис.15), которое позволяет:
    • Включить/выключить режим показа имен типов (объектов) вместо их синонимов
      (запоминаемая настройка диалога, по умолчанию - Истина);
    • Включить/выключить дополнительное оформление списка типов
      (запоминаемая настройка диалога, по умолчанию - Ложь):
      • Группы типов в списке выделяются светло-серым фоном;
      • В режиме редактирования типа (Рис.16):
        Изначально выбранные при открытии типы выделяются жирным шрифтом;
      • В режиме выбора типа (Рис.17):
        Переданное при открытии диалога текущее значение типа выделяется жирным шрифтом;


Особенности поиска в списке типов в альтернативном диалоге:

В диалоге (начиная с версии 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. Режим выбора типа значения требуется значительно чаще (при редактировании в полях ввода реквизитов составного типа).

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

    Пожалуй, наиболее естественным на настоящий момент является следующий способ для программного вызова выбора типа (Рис.1, Рис.2):

В обработчике события "Очистка" поля ввода методами ЭтаФорма.ВыбратьИзСписка() или ЭтаФорма.ПоказатьВыборИзСписка() выводить меню в виде выпадающего списка, в котором  предлагать пользователю следующие возможности:

    • "Выбрать тип значения" (выбрать текущий тип в альтернативном диалоге выбора);
    • “Пустое значение” (установить реквизиту пустое значение текущего типа, если тип простой);
    • "Очистить" (присвоить реквизиту значение Неопределено);


Примеры использования альтернативных диалогов выбора типа смотрите ниже в приложениях к работе, а также в исходном коде демонстрационных форм обработки.


Ограничения обратной совместимости:

   - Под платформой 8.2 все формы этой обработки будут нормально работать в толстом и тонком клиентах.
   - При работе управляемых форм на Web-клиенте под 8.2 будет ошибка компиляции модулей форм из-за "открытого" использования
     глобального асинхронного метода ПоказатьПредупреждение() или использования глобального метода ОткрытьФорму()
     с указанием параметра
ОписаниеОповещенияОЗакрытии, появившегося только под платформой 8.3.

     Проблема решается закомментариванием строк с вызовом этих методов на стороне Web-клиента,
     специально выделенных для этого инструкциями препроцессора.


Приложение 1 (Пример кода использования диалога в режиме обычного приложения):

Пояснения к примеру:
Объект – основной реквизит обработки;
ТестРеквизит – реквизит обработки составного типа (непосредственно редактируется в форме);
ТестРеквизитТип – дополнительное ограничение типа реквизита ТестРеквизит (непосредственно редактируется в форме);
Смысл остальных реквизитов ясен из их названия, пример ориентирован на платформу 8.3


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

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


Процедура
ТестРеквизитОчистка(Элемент, СтандартнаяОбработка)
   
СтандартнаяОбработка = Ложь;
   
ПараметрыОповещения = Новый Структура("Элемент",Элемент);
   
Меню = Новый СписокЗначений;
   
Меню.Добавить(1, "Выбрать тип значения",,БиблиотекаКартинок.ВыбратьТип);
    Если (
Объект.ТестРеквизитТип.Типы().Количество()=1) Тогда
       
Меню.Добавить(2, "Пустое значение",,БиблиотекаКартинок.Выбрать);
    КонецЕсли;
   
Выбор0 = Меню.Добавить(0, "Очистить",,БиблиотекаКартинок.Очистить);
   
Выбор = ЭтаФорма.ВыбратьИзСписка(Меню,Элемент,Выбор0);
   
ТестРеквизитОчисткаПродолжение(Выбор, ПараметрыОповещения);
КонецПроцедуры

Процедура
ТестРеквизитОчисткаПродолжение(Выбор, ПараметрыОповещения) Экспорт
    Перем
Элемент;
    Если
Выбор = Неопределено Тогда
        Возврат;
    КонецЕсли;
    Если
ТипЗнч(ПараметрыОповещения) = Тип("Структура") Тогда
       
ПараметрыОповещения.Свойство("Элемент",Элемент);
    КонецЕсли;
    Если
Выбор.Значение = 0 Тогда
       
Объект.ТестРеквизит = Неопределено;
       
ТестРеквизитПриИзменении(Элемент);
    ИначеЕсли
Выбор.Значение = 2 Тогда
       
Объект.ТестРеквизит = Объект.ТестРеквизитТип.ПривестиЗначение(Неопределено);
       
ТестРеквизитПриИзменении(Элемент);
    ИначеЕсли
Выбор.Значение = 1 Тогда
       
ТестРеквизитВыбратьТип(Элемент,Объект.ТестРеквизит,Объект.ТестРеквизитТип,Ложь);
    КонецЕсли;
КонецПроцедуры

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


Процедура
ТестРеквизитВыбратьТип(Элемент,Значение,ТипЗначения,ЭтоРедактированиеТипаДанных)
    Перем
Оповещение;
    Перем
ПараметрыВыбора;
   
РежимВыбораТипаДанныхП = (ЭтоРедактированиеТипаДанных <> Истина);
    Если
Объект.ТипыВВидеДерева <= 0 Тогда
       
// для выбора типа используется ДеревоЗначений (одноуровневое)
       
ТипыВВидеДереваП = Ложь;
    ИначеЕсли
Объект.ТипыВВидеДерева >= 1 Тогда
       
// для выбора типа используется ДеревоЗначений (многоуровневое)
       
ТипыВВидеДереваП = Истина;
    КонецЕсли;
   
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,ЭтоРедактированиеТипаДанных);
    Если
Объект.РежимВыбораТипа = "МодальныйВыбор" Тогда
       
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное");
       
Диалог.РежимВыбораТипаДанных = РежимВыбораТипаДанныхП; // режим работы диалога редактирования/выбора типа
       
Диалог.ТипыВВидеДерева = ТипыВВидеДереваП; // представление списка типов в диалоге
       
Диалог.ПоказыватьТипBD = Объект.ПоказыватьТипBD; // отображать в списке типов тип "ДвоичныеДанные"
       
Диалог.ТипЗначения = ТипЗначения; // составной тип данных для редактирования или для выбора текущего типа
       
Диалог.ТекущийТип = ТипЗнч(Значение); // определяет текущую строку в списке типов при открытии
       
Диалог.ФормаВладелец = Неопределено;  // параметр для имитации блокировки окна владельца диалога
       
Диалог.ОписаниеОповещенияОЗакрытии = Неопределено; // параметр для имитации оповещения о закрытии диалога
       
ВыбранноеЗначение = Диалог.ОткрытьМодально(180);
       
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора);
    ИначеЕсли
Объект.РежимВыбораТипа = "ОбработкаВыбора" Тогда
       
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное",Элемент,ЭтаФорма);
       
Диалог.РежимВыбораТипаДанных = РежимВыбораТипаДанныхП; // режим работы диалога редактирования/выбора типа
       
Диалог.ТипыВВидеДерева = ТипыВВидеДереваП; // представление списка типов в диалоге
       
Диалог.ПоказыватьТипBD = Объект.ПоказыватьТипBD; // отображать в списке типов тип "ДвоичныеДанные"
       
Диалог.ТипЗначения = ТипЗначения; // составной тип данных для редактирования или для выбора текущего типа
       
Диалог.ТекущийТип = ТипЗнч(Значение);  // определяет текущую строку в списке типов при открытии
       
Диалог.ФормаВладелец = ЭтаФорма; // параметр для имитации блокировки окна владельца диалога
       
Диалог.ОписаниеОповещенияОЗакрытии = Неопределено; // параметр для имитации оповещения о закрытии диалога
       
Диалог.Открыть();
    ИначеЕсли
Объект.РежимВыбораТипа = "ОповещениеОЗакрытии" Тогда
       
мсПараметры = Новый Массив;
       
мсПараметры.Добавить("ТестРеквизитПриВыбореТипаЗначения");
       
мсПараметры.Добавить(ЭтаФорма);
       
мсПараметры.Добавить(ПараметрыВыбора);
       
Оповещение = Новый(Тип("ОписаниеОповещения"),мсПараметры);
       
Диалог = ПолучитьФорму(ПутьКФорме+"EditTypeОбычное",Неопределено,ЭтаФорма);
       
Диалог.РежимВыбораТипаДанных = РежимВыбораТипаДанныхП; // режим работы диалога редактирования/выбора типа
       
Диалог.ТипыВВидеДерева = ТипыВВидеДереваП; // представление списка типов в диалоге
       
Диалог.ПоказыватьТипBD = Объект.ПоказыватьТипBD; // отображать в списке типов тип "ДвоичныеДанные"
       
Диалог.ТипЗначения = ТипЗначения; // составной тип данных для редактирования или для выбора текущего типа
       
Диалог.ТекущийТип = ТипЗнч(Значение); // определяет текущую строку в списке типов при открытии
       
Диалог.ФормаВладелец = ЭтаФорма; // параметр для имитации блокировки окна владельца диалога
       
Диалог.ОписаниеОповещенияОЗакрытии = Оповещение; // параметр для имитации оповещения о закрытии диалога
       
Диалог.Открыть();
    КонецЕсли;

КонецПроцедуры

Процедура
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора) Экспорт
    Перем
Элемент;
    Перем
ЭтоРедактированиеТипаДанных;
    Если
ТипЗнч(ПараметрыВыбора) = Тип("Структура") Тогда
       
ПараметрыВыбора.Свойство("Элемент",Элемент);
       
ПараметрыВыбора.Свойство("ЭтоРедактированиеТипаДанных",ЭтоРедактированиеТипаДанных);
    КонецЕсли;
    Если
ТипЗнч(ВыбранноеЗначение) <> Тип("ОписаниеТипов") Тогда
        Возврат;
    КонецЕсли;
    Если
ЭтоРедактированиеТипаДанных = Истина Тогда
       
Объект.ТестРеквизитТип = ВыбранноеЗначение;
    КонецЕсли;
   
Объект.ТестРеквизит = ВыбранноеЗначение.ПривестиЗначение(Объект.ТестРеквизит);
   
ТестРеквизитПриИзменении(ЭлементыФормы.ТестРеквизит);
КонецПроцедуры

Процедура
ТестРеквизитПриИзменении(Элемент)
   
ПолеФормыКонтрольТипЗначения(Элемент,Объект.ТестРеквизитТип,Объект.ТестРеквизит);
КонецПроцедуры

// управление свойствами поля ввода (формат текста поля, флаг выбора типа)
Процедура ПолеФормыКонтрольТипЗначения(Элемент,ТипЗначения,Значение)
   
СтрФорматЧ = "";
   
ПЧ = Неопределено;
    Если
ТипЗначения.СодержитТип(Тип("Число")) Тогда
       
ДЛ = ТипЗначения.КвалификаторыЧисла.Разрядность;
       
ТЧ = ТипЗначения.КвалификаторыЧисла.РазрядностьДробнойЧасти;
       
ПЧ = (ТипЗначения.КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный);
       
СтрФорматЧ = "ЧЦ="+Формат(ДЛ,"ЧДЦ=; ЧН=; ЧГ=0")+"; ЧДЦ="+Формат(ТЧ,"ЧДЦ=; ЧН=; ЧГ=0");
    КонецЕсли;
   
СтрФорматД = "";
    Если
ТипЗначения.СодержитТип(Тип("Дата")) Тогда
       
ТЧ = ТипЗначения.КвалификаторыДаты.ЧастиДаты;
        Если
ТЧ = ЧастиДаты.Дата Тогда
           
СтрФорматД = "ДЛФ=D";
        ИначеЕсли
ТЧ = ЧастиДаты.Время Тогда
           
СтрФорматД = "ДЛФ=T";
        КонецЕсли;
    КонецЕсли;
   
СтрФормат = СтрФорматЧ + ?(ЗначениеЗаполнено(СтрФорматЧ) И ЗначениеЗаполнено(СтрФорматД),"; ","") + СтрФорматД;
    Попытка
       
Элемент.Формат = СтрФормат;
    Исключение
    КонецПопытки;
    Если
ТипЗнч(Значение) = Тип("Число") И ПЧ = Истина И Значение < 0 Тогда
       
// контроль положительности числа по ограничениям в типе данных
       
Значение = -Значение;
    КонецЕсли;
    Если
ТипЗнч(Значение) = Тип("Число") ИЛИ ТипЗнч(Значение) = Тип("Строка") ИЛИ ТипЗнч(Значение) = Тип("Дата") ИЛИ ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
       
// контроль длины и точности значения по ограничениям в типе данных
       
Значение = ТипЗначения.ПривестиЗначение(Значение);
    КонецЕсли;
   
Элемент.ВыбиратьТип = (Значение = Неопределено);
КонецПроцедуры

Приложение 2 (пример кода использования диалога в режиме управляемого приложения):

Пояснения к примеру:
Объект – основной реквизит обработки;
ТестРеквизит – реквизит обработки составного типа (непосредственно редактируется в форме);
ТестРеквизитТип – дополнительное ограничение типа реквизита ТестРеквизит (непосредственно редактируется в форме);
Смысл остальных реквизитов ясен из их названия, пример ориентирован на платформу 8.3.


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

&НаКлиенте
Процедура ТестРеквизитТипОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
   
СтандартнаяОбработка = Ложь;
   
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,Истина);
   
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора);
КонецПроцедуры


&НаКлиенте
Процедура ТестРеквизитОчистка(Элемент, СтандартнаяОбработка)
    Перем
Оповещение;
    Перем
ПараметрыОповещения;
   
СтандартнаяОбработка = Ложь;
   
ТипОО = Тип("ОписаниеОповещения");
   
ПараметрыОповещения = Новый Структура("Элемент",Элемент);
   
Меню = Новый СписокЗначений;
   
Меню.Добавить(1, "Выбрать тип значения",,БиблиотекаКартинок.ВыбратьТип);
    Если (
Объект.ТестРеквизитТип.Типы().Количество()=1) Тогда
       
Меню.Добавить(2, "Пустое значение",,БиблиотекаКартинок.Выбрать);
    КонецЕсли;
   
Выбор0 = Меню.Добавить(0, "Очистить",,БиблиотекаКартинок.Очистить);
    Если
Объект.РежимВыбораТипа <> "МодальныйВыбор" Тогда
       
мсПараметры = Новый Массив;
       
мсПараметры.Добавить("ТестРеквизитОчисткаПродолжение");
       
мсПараметры.Добавить(ЭтаФорма);
       
мсПараметры.Добавить(ПараметрыОповещения);
       
Оповещение = Новый(Тип("ОписаниеОповещения"),мсПараметры);
       
ЭтаФорма.ПоказатьВыборИзСписка(Оповещение,Меню,Элемент,Выбор0);
    Иначе
       
Выбор = ЭтаФорма.ВыбратьИзСписка(Меню,Элемент,Выбор0);
       
ТестРеквизитОчисткаПродолжение(Выбор, ПараметрыОповещения);
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ТестРеквизитОчисткаПродолжение(Выбор, ПараметрыОповещения) Экспорт
    Перем
Элемент;
    Если
Выбор = Неопределено Тогда
        Возврат;
    КонецЕсли;
    Если
ТипЗнч(ПараметрыОповещения) = Тип("Структура") Тогда
       
ПараметрыОповещения.Свойство("Элемент",Элемент);
    КонецЕсли;
    Если
Выбор.Значение = 0 Тогда
       
Объект.ТестРеквизит = Неопределено;
       
ТестРеквизитПриИзменении(Элемент);
    ИначеЕсли
Выбор.Значение = 2 Тогда
       
Объект.ТестРеквизит = Объект.ТестРеквизитТип.ПривестиЗначение(Неопределено);
       
ТестРеквизитПриИзменении(Элемент);
    ИначеЕсли
Выбор.Значение = 1 Тогда
       
ТестРеквизитВыбратьТип(Элемент,Объект.ТестРеквизит,Объект.ТестРеквизитТип,Ложь);
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ТестРеквизитОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
    Если
ТипЗнч(ВыбранноеЗначение) = Тип("ОписаниеТипов") И Объект.РежимВыбораТипа = "ОбработкаВыбора" И ВыбранноеЗначение.Типы().Количество() = 1 Тогда
       
// из формы выбора прилетело значение "ОписаниеТипов" простого типа -
        // - считаем, что в диалоге выбора типа выбран текущий тип значения реквизита
       
СтандартнаяОбработка = Ложь;
       
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,Ложь);
       
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора);
    Иначе
       
// из формы выбора прилетело значение, отличное от "ОписаниеТипов" простого типа -
        // - считаем, что в форме выбора выбрано значение реквизита
       
СтандартнаяОбработка = Истина;
    КонецЕсли;
КонецПроцедуры


&НаКлиенте
Процедура ТестРеквизитВыбратьТип(Элемент,Значение,ТипЗначения,ЭтоРедактированиеТипаДанных)
    Перем
Оповещение;
    Перем
ПараметрыВыбора;
   
РежимВыбораТипаДанныхП = (ЭтоРедактированиеТипаДанных <> Истина);
    Если
Объект.ТипыВВидеДерева <= 0 Тогда
       
// для выбора типа используется ТаблицаЗначений
       
ТипыВВидеДереваП = Ложь;
    ИначеЕсли
Объект.ТипыВВидеДерева = 1 Тогда
       
// для выбора типа используется ДеревоЗначений (многоуровневое)
       
ТипыВВидеДереваП = Истина;
    ИначеЕсли
Объект.ТипыВВидеДерева >= 2 Тогда
       
// третье состояние флага
        // для выбора типа используется ДеревоЗначений (одноуровневое)
       
ТипыВВидеДереваП = Null;
    КонецЕсли;
   
ПараметрыВыбора = Новый Структура("Элемент,ЭтоРедактированиеТипаДанных",Элемент,ЭтоРедактированиеТипаДанных);
   
стПараметры = Новый Структура;
   
стПараметры.Вставить("РежимВыбораТипаДанных",РежимВыбораТипаДанныхП); // режим работы диалога редактирования/выбора типа
   
стПараметры.Вставить("ТипыВВидеДерева",ТипыВВидеДереваП); // представление списка типов в диалоге
   
стПараметры.Вставить("ПоказыватьТипBD",Объект.ПоказыватьТипBD);// отображать в списке типов тип "ДвоичныеДанные")
   
стПараметры.Вставить("ТипЗначения",ТипЗначения); // составной тип данных для редактирования или для выбора текущего типа
   
стПараметры.Вставить("ТекущийТип",ТипЗнч(Значение)); // определяет текущую строку в списке типов при открытии
   
Если Объект.РежимВыбораТипа = "МодальныйВыбор" Тогда
       
ВыбранноеЗначение = ОткрытьФормуМодально(ПутьКФорме+"EditTypeУправляемое",стПараметры);
       
ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора);
    ИначеЕсли
Объект.РежимВыбораТипа = "ОбработкаВыбора" Тогда
       
ОткрытьФорму(ПутьКФорме+"EditTypeУправляемое",стПараметры,Элемент,ЭтаФорма);
    ИначеЕсли
Объект.РежимВыбораТипа = "ОповещениеОЗакрытии" И ТипОО <> Null Тогда
       
мсПараметры = Новый Массив;
       
мсПараметры.Добавить("ТестРеквизитПриВыбореТипаЗначения");
       
мсПараметры.Добавить(ЭтаФорма);
       
мсПараметры.Добавить(ПараметрыВыбора);
       
Оповещение = Новый(Тип("ОписаниеОповещения"),мсПараметры);
       
ОткрытьФорму(ПутьКФорме+"EditTypeУправляемое",стПараметры,Неопределено,ЭтаФорма,,,Оповещение);
   
КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ТестРеквизитПриВыбореТипаЗначения(ВыбранноеЗначение,ПараметрыВыбора) Экспорт
    Перем
Элемент;
    Перем
ЭтоРедактированиеТипаДанных;
    Если
ТипЗнч(ПараметрыВыбора) = Тип("Структура") Тогда
       
ПараметрыВыбора.Свойство("Элемент",Элемент);
       
ПараметрыВыбора.Свойство("ЭтоРедактированиеТипаДанных",ЭтоРедактированиеТипаДанных);
    КонецЕсли;
    Если
ТипЗнч(ВыбранноеЗначение) <> Тип("ОписаниеТипов") Тогда
        Возврат;
    КонецЕсли;
    Если
ЭтоРедактированиеТипаДанных = Истина Тогда
       
Объект.ТестРеквизитТип = ВыбранноеЗначение;
    КонецЕсли;
   
Объект.ТестРеквизит = ВыбранноеЗначение.ПривестиЗначение(Объект.ТестРеквизит);
   
ТестРеквизитПриИзменении(Элементы.ТестРеквизит);
КонецПроцедуры

&НаКлиенте
Процедура ТестРеквизитПриИзменении(Элемент)
   
ПолеФормыКонтрольТипЗначения(Элемент,Объект.ТестРеквизитТип,Объект.ТестРеквизит);
КонецПроцедуры

&НаКлиенте
// управление свойствами поля ввода (формат текста поля, флаг выбора типа)
Процедура ПолеФормыКонтрольТипЗначения(Элемент,ТипЗначения,Значение)
   
СтрФорматЧ = "";
   
ПЧ = Неопределено;
    Если
ТипЗначения.СодержитТип(Тип("Число")) Тогда
       
ДЛ = ТипЗначения.КвалификаторыЧисла.Разрядность;
       
ТЧ = ТипЗначения.КвалификаторыЧисла.РазрядностьДробнойЧасти;
       
ПЧ = (ТипЗначения.КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный);
       
СтрФорматЧ = "ЧЦ="+Формат(ДЛ,"ЧДЦ=; ЧН=; ЧГ=0")+"; ЧДЦ="+Формат(ТЧ,"ЧДЦ=; ЧН=; ЧГ=0");
    КонецЕсли;
   
СтрФорматД = "";
    Если
ТипЗначения.СодержитТип(Тип("Дата")) Тогда
       
ТЧ = ТипЗначения.КвалификаторыДаты.ЧастиДаты;
        Если
ТЧ = ЧастиДаты.Дата Тогда
           
СтрФорматД = "ДЛФ=D";
        ИначеЕсли
ТЧ = ЧастиДаты.Время Тогда
           
СтрФорматД = "ДЛФ=T";
        КонецЕсли;
    КонецЕсли;
   
СтрФормат = СтрФорматЧ + ?(ЗначениеЗаполнено(СтрФорматЧ) И ЗначениеЗаполнено(СтрФорматД),"; ","") + СтрФорматД;
    Попытка
       
Элемент.Формат = СтрФормат;
    Исключение
    КонецПопытки;
    Попытка
       
Элемент.ФорматРедактирования = СтрФормат;
    Исключение
    КонецПопытки;
    Если
ТипЗнч(Значение) = Тип("Число") И ПЧ = Истина И Значение < 0 Тогда
       
// контроль положительности числа по ограничениям в типе данных
       
Значение = -Значение;
    КонецЕсли;
    Если
ТипЗнч(Значение) = Тип("Число") ИЛИ ТипЗнч(Значение) = Тип("Строка") ИЛИ ТипЗнч(Значение) = Тип("Дата") ИЛИ ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
       
// контроль длины и точности значения по ограничениям в типе данных
       
Значение = ТипЗначения.ПривестиЗначение(Значение);
    КонецЕсли;
   
Элемент.ВыбиратьТип = (Значение = Неопределено);
КонецПроцедуры


Актуальные версии обработки:

Актуальные версии обработки находятся в следующих файлах поставки:

  1. EditType83(1.2).epf
  2. EditType81(1.2).epf

 Остальные файлы оставлены для сохранения статистики загрузок и
не рекомендуются для скачивания.


Скачать файлы

Наименование Файл Версия Размер
EditType83(1.2) 9
.epf 157,56Kb
17.04.16
9
.epf 8.3.1.2 157,56Kb Скачать
EditType81(1.2) 4
.epf 80,89Kb
17.04.16
4
.epf 8.1.1.2 80,89Kb Скачать
EditType83(1.1) 5
.epf 127,92Kb
17.04.16
5
.epf 8.3.1.1 127,92Kb Скачать
EditType83(1.0) 8
.epf 124,42Kb
17.04.16
8
.epf 8.3.1.0 124,42Kb Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Юрий Осипов (yuraos) 18.02.16 08:28
Всем привет и доброго времени суток!

1. Версия для 8.1 пока не готова (сделаю быстрее, если будут особые пожелания).

2. В будущем в контекстное меню думаю вставить пару подменю:
- для выбора составного типа "Характеристика.ИмяПланаВидовХарактеристик
- для выбора составного типа "ОпределяемыйТип.ИмяОпределяемогоТипа"
2. Maxim Kolkin (the1) 18.02.16 09:10
Ну явно не хватает фильтра по типам
Прикрепленные файлы:
adhocprog; yuraos; +2 Ответить 5
3. Юрий Осипов (yuraos) 18.02.16 10:30
(2) the1,
да, увы, да не хватает
....
также не хватает в 1с поиска в таблицах по регулярным выражениям
(ну хотя бы по строке шаблона оператора ПОДОБНО).

А в дереве значений управляемой формы - вообще никакие поиски не работают
(приходится при необходимости их индексировать)!!!!!

вот когда 1С дорастет до выше сказанного - сделаю и отбор по строке в наименовании

;)
4. Юрий Осипов (yuraos) 18.02.16 10:37
(2)(3)
можно конечно извратиться с помощью запроса...
но делать серверный вызов для поиска в таблице на клиенте -
- это ЯВНЫЙ НЕ ФЭНШУЙ !!!!
5. Maxim Kolkin (the1) 20.02.16 09:14
6. Юрий Осипов (yuraos) 20.02.16 12:25
(5) the1,
понимаю что это можно сделать через запрос.
***
НО неохота делать это для управляемой формы:

7. Юрий Осипов (yuraos) 20.02.16 12:25
(6)
1. так-как потребуется серверный вызов с неизбежными тормозами при поиске.
(наверное можно наверное извратиться с ВРЕМЕННЫМ ХРАНИЛИЩЕМ, чтобы сделать этот вызов ВНЕКОНТЕКСТНЫМ).
8. Юрий Осипов (yuraos) 20.02.16 12:27
(6)
2. после получения списка удовлетворяющих условиям поиска строк
придется установить для этих строк признак отбора и включить сам отбор строк в таблице формы по этому признаку.

Но в настоящий момент
реально отбор строк в таблице управляемой формы работает только для таблицы формы связанной с "ТаблицейЗначения"
ДЛЯ "ДЕРЕВА ЗНАЧЕНИЙ" В УПРАВЛЯЕМОЙ ФОРМЕ ОТБОР СТРОК НЕ РАБОТАЕТ !!!
(в дополнении с отсутствием обычного поиска строк)
9. Юрий Осипов (yuraos) 20.02.16 12:36
(6)(7)(8)
так что этот поиск в настоящий момент можно сделать только в одном частном случае
(в случае представления таблицы типов в виде "ТаблицыЗначений" в управляемой форме)
***
и думаю что делать это не стоит ...
... не хочется нарушать универсальность функциональности в разных режимах.
10. Андрей Акулов (DrAku1a) 25.02.16 02:42
(2) the1, Юзаем пока что "Ctrl+F" в дереве.
11. Юрий Осипов (yuraos) 13.03.16 08:36
Всем доброго времени суток!
***
Обновлены файлы поставки::
Опубликована версия 1.1 от 13.03.2016
В контекстное меню флага "Составной тип данных" добавлено два подменю:
- "Выбрать тип характеристик" (Рис.14.2, для установки в списке составного типа "Характеристика.ИмяПВХ")
- "Выбрать определяемый тип" (Рис.14.3, для установки в списке составного типа "ОпределяемыйТип.ИмяОТ")
12. Юрий Осипов (yuraos) 13.03.16 08:50
ДАЛЬНЕЙШИЕ ПЛАНЫ:

1. По замечанию the1(2):
Таки сделаю поиск по строке, похожий на тот, что в системном диалоге.
Но сразу хочу сказать что получится довольно стремно -
- без выделения цветом вхождений строки поиска в таблице найденных строк.
(так как использовать тип "ФорматированнаяСтрока" в таблицах форм под 8.2 и 8.3 нельзя)
Может что-то изменится под 8.4 ...
Хотя на вряд ли, юзабилити у 1С - не в приоритете.

2. Судя по опросу, все-таки есть народ, который все еще варится на платформе 8.1.
И поскольку на моей новой работе тоже оказались базы под 8.1 -
- ДАУНГРЕЙДУ ДЛЯ 8.1 БЫТЬ !!!
...
но после добавления поиска по строке.
13. Юрий Осипов (yuraos) 17.04.16 10:21
Всем доброго времени суток!!!
Обновлены файлы поставки::

Опубликована версия 8.3.1.2 от 11.04.2016
Опубликована версия 8.1.1.2 от 11.04.2016 - обещанный даунгрэйд для платформы 1с-8.1

Новое в версиях:
- исполнено пожелание (2) the1
добавлен поиск по строке в имени/синониме типа с разными дополнительными опциями

(пришлось малость повозиться - но что не сделаешь для хорошего человека! ).

- добавлен показ только отмеченных строк в списке типов.


- добавлен показ типов "ХранилищеЗначений" и "УникальныйИдентификатор".
(особого смысла нет, но пусть будут - может у кого есть нештатные средства для редактирования этих типов)..

- подправлены кое какие мелкие косячки.
14. Maxim Kolkin (the1) 16.08.16 15:11
(13) yuraos, от теперь полная крутотень!
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа