24 мая 2014 г.

Реализация иерархии в перечислениях

Все мы привыкли, что перечисления в 1С обычно содержат небольшой, редко изменяемый, набор значений и в иерархическом представлении, соответственно, не нуждаются. Но в активно развивающейся учетной системе может возникнуть ситуация, что какое-нибудь перечисление будет периодически дополняться новыми значениями. И в определенный момент возникнет ситуация, в которой со списком этих значений станет неудобно работать. Как следствие, может возникнуть вопрос о реализации механизма группировок в перечислении. И если пользователю особо не важно, как это будет реализовано, лишь бы удобно было работать, то нам, разработчикам, желательно реализовать это все с наименьшими изменениями конфигурации.
Следовательно, о создании справочника с одноименными предопределенными элементами с последующей подменой реквизитов и правкой кода речь не идет. Хотелось бы так же обойтись без создания служебных объектов для хранения соответствия значений перечисления определенной группе. Поэтому всю необходимую информацию можно хранить либо в макетах перечисления, либо в самом коде. В моей реализации все необходимые данные будут находится в модуле менеджера перечисления.

В качестве примера создадим новую конфигурацию и добавим перечисление и создадим в нем набор значений.

В менеджере перечисления добавим код:

Функция ПолучитьГруппуРасход()
 
 мОперации = Новый Массив;
 мОперации.Добавить(ЗначениеПеречисления1);
 мОперации.Добавить(ЗначениеПеречисления3);
 мОперации.Добавить(ЗначениеПеречисления5);
 мОперации.Добавить(ЗначениеПеречисления6);
 мОперации.Добавить(ЗначениеПеречисления7);
 
 Возврат мОперации;
 
КонецФункции

Функция ПолучитьГруппуПриход()
 
 мОперации = Новый Массив;
 мОперации.Добавить(ЗначениеПеречисления2);
 мОперации.Добавить(ЗначениеПеречисления4);
 мОперации.Добавить(ЗначениеПеречисления10);
 мОперации.Добавить(ЗначениеПеречисления11);
 мОперации.Добавить(ЗначениеПеречисления12);
 
 Возврат мОперации;
 
КонецФункции

Функция ПолучитьГруппы() Экспорт
 
 Возврат Новый Структура("Расход, Приход", 
   ПолучитьГруппуРасход(), 
   ПолучитьГруппуПриход());
 
КонецФункции

Функция ПолучитьГруппуЗначения(Значение) Экспорт
 
 Группы = ПолучитьГруппы();
 Группа = "Прочие";
 Если НЕ Группы.Расход.Найти(Значение) = Неопределено Тогда
  Группа = "Расход";
 ИначеЕсли НЕ Группы.Приход.Найти(Значение) = Неопределено Тогда
  Группа = "Приход";
 КонецЕсли;
 
 Возврат Группа; 
 
КонецФункции

Теперь переходим к созданию и настройке формы выбора перечисления. Для начала модифицируем свойства динамического списка. Переделаем запрос списка на произвольный:

ВЫБРАТЬ
 ПеречислениеВарианты.Ссылка,
 ПеречислениеВарианты.Порядок,
 ВЫБОР
  КОГДА ПеречислениеВарианты.Ссылка В (&Расход)
   ТОГДА "Расход"
  КОГДА ПеречислениеВарианты.Ссылка В (&Приход)
   ТОГДА "Приход"
  ИНАЧЕ "Прочие"
 КОНЕЦ КАК Группа
ИЗ
 Перечисление.Варианты КАК ПеречислениеВарианты

В настройках списка на вкладке "Группировка" укажем поле "Группа". В свойствах элемента списка изменим свойство "Отображение" на "Иерархический список". В модуле формы опишем процедуру ПриСозданииНаСервере:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
 
 мГруппы = Перечисления.Варианты.ПолучитьГруппы();
 Список.Параметры.УстановитьЗначениеПараметра("Расход", мГруппы.Расход);
 Список.Параметры.УстановитьЗначениеПараметра("Приход", мГруппы.Приход);
 
КонецПроцедуры

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


Теперь отработаем ситуацию для документа, в котором набор значений ограничивался списком выбора. Создаем в конфигурации копию нашего документа, создаем и настраиваем ему форму документа. Для элемента формы "Вариант" определяем список выбора:


Для уже существующего документа необходимо будет сбросить свойство "Режим выбора из списка". Дописываем форму выбора перечисления:

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

Теперь открытии формы выбора из этого документа набор значений перечисления будет ограничен списком выбора элемента.


1 комментарий: