1
0
mirror of https://github.com/firstBitSportivnaya/PSSL.git synced 2025-01-26 03:52:13 +02:00

refact predefind functions (#163)

Рефакторинг подсистемы предопределенных значений
This commit is contained in:
Denis Ushakov 2024-12-13 10:10:37 +03:00 committed by GitHub
parent 7e9eb46d52
commit 1f7bb7c3dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 602 additions and 595 deletions

View File

@ -206,9 +206,9 @@
КонецЕсли;
Менеджер = пбп_Переадресация.МенеджерОбъектаПоПолномуИмени(ИмяФормыВладельца);
ДопПараметры = пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов(
ДопПараметры = пбп_ПредопределенныеЗначенияСлужебный.ДопПараметрыОбработкиПредопределенныхЭлементов(
Таблица, Менеджер);
пбп_ПредопределенныеЗначения.СоздатьОбновитьПредопределенныеЗначения(Таблица, ДопПараметры);
пбп_ПредопределенныеЗначенияСлужебный.СоздатьОбновитьПредопределенныеЗначения(Таблица, ДопПараметры);
КонецПроцедуры

View File

@ -74,7 +74,7 @@
Процедура ПриДобавленииПодсистемы(Описание) Экспорт
Описание.Имя = "ПроектнаяБиблиотекаПодсистем";
Описание.Версия = "1.0.4.14";
Описание.Версия = "1.0.4.15";
// Требуется библиотека стандартных подсистем.
Описание.ТребуемыеПодсистемы.Добавить("СтандартныеПодсистемы");

View File

@ -37,93 +37,13 @@
ТЗПредопределенныхЗначений = пбп_ПредопределенныеЗначенияПереопределяемый
.ТаблицаПредопределенныхЭлементов(МенеджерОбъекта);
ТаблицаКонфликтныхЭлементов = ОбработатьПредопределенныеЗначения(ТЗПредопределенныхЗначений, МенеджерОбъекта);
ТаблицаКонфликтныхЭлементов = пбп_ПредопределенныеЗначенияСлужебный
.ОбработатьПредопределенныеЗначения(ТЗПредопределенныхЗначений, МенеджерОбъекта);
Возврат ТаблицаКонфликтныхЭлементов;
КонецФункции
// Обрабатывает таблицу предопределенных элементов. Операции включают в себя: установка пометок удаления
// на неиспользуемые элементы, отбор предопределенных значений, создание предопределенных элементов.
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// МенеджерОбъекта - СправочникМенеджер, ПланВидовХарактеристикМенеджер - менеджер объекта.
//
// Возвращаемое значение:
// ТаблицаЗначений - Таблица с конфликтными элементами
//
Функция ОбработатьПредопределенныеЗначения(ТаблицаПредопределенных, МенеджерОбъекта) Экспорт
Параметры = ДопПараметрыОбработкиПредопределенныхЭлементов(ТаблицаПредопределенных, МенеджерОбъекта);
ОбработатьНеиспользуемыеЭлементы(ТаблицаПредопределенных, Параметры.ПолноеИмя);
ЗаполнитьРодителейЭлементов(ТаблицаПредопределенных, Параметры);
ЗаполнитьКонтрольныеСуммыТаблицы(ТаблицаПредопределенных, Параметры);
ТаблицаКонфликтныхЭлементов = УдалитьИзТаблицыСуществующиеЭлементы(ТаблицаПредопределенных, Параметры);
СоздатьОбновитьПредопределенныеЗначения(ТаблицаПредопределенных, Параметры);
Возврат ТаблицаКонфликтныхЭлементов;
КонецФункции
// Подготавливает параметры необходимые для обработки предопределенных элементов
//
// Параметры:
// Таблица - ТаблицаЗначений - см. пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных.
// МенеджерОбъекта - СправочникМенеджер, ПланВидовХарактеристикМенеджер - менеджер объекта.
//
// Возвращаемое значение:
// Структура - Данные Менеджера объекта
// * Менеджер - СправочникМенеджер, ПланВидовХарактеристикМенеджер - менеджер объекта.
// * ПолноеИмя - Строка - Полное имя объекта метаданных.
// * Иерархический - Булево - Свойство объекта метаданных.
// * ИерархияГруппИЭлементов - Булево - Свойство объекта метаданных.
// * КлючиХешаЭлемент - Структура - Ключевые реквизиты для формирования хеша элемента.
// * КлючиХешаГруппа - Структура - Ключевые реквизиты для формирования хеша группы.
//
Функция ДопПараметрыОбработкиПредопределенныхЭлементов(Таблица, МенеджерОбъекта) Экспорт
Параметры = Новый Структура;
Параметры.Вставить("Менеджер", Неопределено);
Параметры.Вставить("ПолноеИмя", "");
Параметры.Вставить("Иерархический", Ложь);
Параметры.Вставить("ИерархияГруппИЭлементов", Ложь);
Параметры.Вставить("КлючиХешаЭлемент", Новый Структура);
Параметры.Вставить("КлючиХешаГруппа", Новый Структура);
Если Не пбп_ПредопределенныеЗначенияСлужебный.МенеджерВходитВПодсистемуПредопределенных(МенеджерОбъекта) Тогда
Возврат Параметры;
КонецЕсли;
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(МенеджерОбъекта));
Параметры = Новый Структура;
Параметры.Вставить("Менеджер", МенеджерОбъекта);
Параметры.Вставить("ПолноеИмя", ОбъектМетаданных.ПолноеИмя());
Параметры.Вставить("Иерархический", ОбъектМетаданных.Иерархический);
ИерархияГруппИЭлементов = ОбъектМетаданных.Иерархический;
Если Метаданные.Справочники.Содержит(ОбъектМетаданных) Тогда
ИерархияГруппИЭлементов =
ОбъектМетаданных.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов;
КонецЕсли;
Параметры.Вставить("ИерархияГруппИЭлементов", ИерархияГруппИЭлементов);
мКолонки = Новый Массив;
Для Каждого Колонка Из Таблица.Колонки Цикл
мКолонки.Добавить(Колонка.Имя);
КонецЦикла;
Параметры.Вставить("КлючиХешаЭлемент", КлючиХешаПредопределенногоЭлемента(мКолонки, Ложь));
Параметры.Вставить("КлючиХешаГруппа", КлючиХешаПредопределенногоЭлемента(мКолонки, Истина));
Возврат Параметры;
КонецФункции
// Возвращает ключи хеша на основании массива полей элемента
//
// Параметры:
@ -155,215 +75,6 @@
КонецФункции
// Получает все предопределенные элементы объекта, помечает на удаление те, которые удалены из кода.
// При установке пометки удаления для групп, также устанавливается для всех подчиенных элементов.
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ПолноеИмяОбъекта - Строка - Полное имя объекта метаданных.
//
Процедура ОбработатьНеиспользуемыеЭлементы(ТаблицаПредопределенных, ПолноеИмяОбъекта = "") Экспорт
ПолноеИмяОбъекта = ИмяОбъектаМетаданных(ПолноеИмяОбъекта);
ТаблицаПредопределенных.Индексы.Добавить("ИдентификаторНастройки");
Запрос = Новый Запрос;
ТекстЗапроса =
"ВЫБРАТЬ
| пбп_ПредопределенныеЗначения.Ссылка КАК Ссылка,
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки КАК ИдентификаторНастройки
|ИЗ
| %1 КАК пбп_ПредопределенныеЗначения
|ГДЕ
| НЕ пбп_ПредопределенныеЗначения.ПометкаУдаления
|
|УПОРЯДОЧИТЬ ПО
| Ссылка
|ИТОГИ ПО
| Ссылка ИЕРАРХИЯ";
Если пбп_ОбщегоНазначенияПовтИсп.ПолучитьЗначениеКонстанты("пбп_ИспользоватьПользовательскиеФункции") Тогда
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ГДЕ
| НЕ пбп_ПредопределенныеЗначения.ПометкаУдаления",
"ГДЕ
| НЕ пбп_ПредопределенныеЗначения.ПометкаУдаления
| И пбп_ПредопределенныеЗначения.ИдентификаторНастройки <> """"");
КонецЕсли;
Запрос.Текст = СтрШаблон(ТекстЗапроса, ПолноеИмяОбъекта);
Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ПометитьНаУдалениеВсеВложения(Выборка, ТаблицаПредопределенных);
КонецПроцедуры
// Заполняет существующих родителей предопределенных элементов
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ДополнительныеПараметры - Структура - см.пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов
//
Процедура ЗаполнитьРодителейЭлементов(ТаблицаПредопределенных, ДополнительныеПараметры) Экспорт
Идентификаторы = ТаблицаПредопределенных.ВыгрузитьКолонку("ИдентификаторРодитель");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| пбп_ПредопределенныеЗначения.Ссылка КАК Ссылка,
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки КАК ИдентификаторНастройки
|ИЗ
| %1 КАК пбп_ПредопределенныеЗначения
|ГДЕ
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки В(&ИдентификаторыРодитель)";
Запрос.Текст = СтрШаблон(Запрос.Текст, ДополнительныеПараметры.ПолноеИмя);
Запрос.УстановитьПараметр("ИдентификаторыРодитель", Идентификаторы);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Для Каждого Строка Из ТаблицаПредопределенных Цикл
ВыборкаДетальныеЗаписи.Сбросить();
Если ВыборкаДетальныеЗаписи.НайтиСледующий(Строка.ИдентификаторРодитель, "ИдентификаторНастройки") Тогда
Строка.Родитель = ВыборкаДетальныеЗаписи.Ссылка;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Заполняет хеш предопределенных элементов
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ДополнительныеПараметры - Структура - см.пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов
//
Процедура ЗаполнитьКонтрольныеСуммыТаблицы(ТаблицаПредопределенных, ДополнительныеПараметры) Экспорт
Если Не ЗначениеЗаполнено(ТаблицаПредопределенных) Тогда
Возврат;
КонецЕсли;
Для Каждого Строка Из ТаблицаПредопределенных Цикл
КлючиХеша = ?(Строка.ЭтоГруппа, ДополнительныеПараметры.КлючиХешаГруппа, ДополнительныеПараметры.КлючиХешаЭлемент);
ЗаполнитьЗначенияСвойств(КлючиХеша, Строка);
Строка.ХешСумма = пбп_Переадресация.КонтрольнаяСуммаСтрокой(КлючиХеша, ХешФункция.MD5);
КонецЦикла;
КонецПроцедуры
// После удаления уже существующих элементов, остаются только актуальные значения
// для создания предопределенных элементов.
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ДополнительныеПараметры - Структура - см.пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов
//
// Возвращаемое значение:
// ТаблицаЗначений - Таблица с конфликтными элементами
//
Функция УдалитьИзТаблицыСуществующиеЭлементы(ТаблицаПредопределенных, ДополнительныеПараметры) Экспорт
ТаблицаКонфликтныхЭлементов = пбп_ПредопределенныеЗначенияПереопределяемый
.ТаблицаКонфликтныхЭлементов(ДополнительныеПараметры.Менеджер, ТаблицаПредопределенных.СкопироватьКолонки());
Если Не ЗначениеЗаполнено(ТаблицаПредопределенных) Тогда
Возврат ТаблицаКонфликтныхЭлементов;
КонецЕсли;
ПолноеИмяОбъекта = ИмяОбъектаМетаданных(ДополнительныеПараметры.ПолноеИмя);
ТаблицаПредопределенных.Сортировать("ЭтоГруппа УБЫВ, УровеньИерархии");
ОбработатьДублиИдентификаторов(ТаблицаПредопределенных, ТаблицаКонфликтныхЭлементов);
ИдентификаторыНастроек = ТаблицаПредопределенных.ВыгрузитьКолонку("ИдентификаторНастройки");
Запрос = Новый Запрос;
ТекстЗапроса =
"ВЫБРАТЬ
| пбп_ПредопределенныеЗначения.Ссылка КАК Ссылка,
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки КАК ИдентификаторНастройки,
| пбп_СостоянияПредопределенныхЭлементов.ХешСумма КАК ХешСумма,
| ЕСТЬNULL(пбп_СостоянияПредопределенныхЭлементов.РучноеИзменение, ЛОЖЬ) КАК РучноеИзменение,
| пбп_ПредопределенныеЗначения.ПометкаУдаления КАК ПометкаУдаления,
| пбп_СостоянияПредопределенныхЭлементов.ХешСумма ЕСТЬ NULL КАК ХешОтсутствует
|ИЗ
| %1 КАК пбп_ПредопределенныеЗначения
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.пбп_СостоянияПредопределенныхЭлементов КАК пбп_СостоянияПредопределенныхЭлементов
| ПО пбп_ПредопределенныеЗначения.Ссылка = пбп_СостоянияПредопределенныхЭлементов.Объект
|ГДЕ
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки В(&СписокИдентификаторов)";
Запрос.Текст = СтрШаблон(ТекстЗапроса, ПолноеИмяОбъекта);
Запрос.УстановитьПараметр("СписокИдентификаторов", ИдентификаторыНастроек);
ВыборкаДетальныеЗаписи = Запрос.Выполнить().Выбрать();
СтрокиДляУдаления = Новый Массив;
Для Каждого Строка Из ТаблицаПредопределенных Цикл
ВыборкаДетальныеЗаписи.Сбросить();
Если ВыборкаДетальныеЗаписи.НайтиСледующий(Строка.ИдентификаторНастройки, "ИдентификаторНастройки") Тогда
Если ВыборкаДетальныеЗаписи.РучноеИзменение Или ВыборкаДетальныеЗаписи.ХешСумма = Строка.ХешСумма Тогда
СтрокиДляУдаления.Добавить(Строка);
Иначе
ОбработатьСтроку(Строка, ВыборкаДетальныеЗаписи, ТаблицаКонфликтныхЭлементов, СтрокиДляУдаления);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для Каждого Строка Из СтрокиДляУдаления Цикл
ТаблицаПредопределенных.Удалить(Строка);
КонецЦикла;
Возврат ТаблицаКонфликтныхЭлементов;
КонецФункции
// Создание предопределенных значений на основании заполненной таблицы
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ДополнительныеПараметры - Структура - см.пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов
//
Процедура СоздатьОбновитьПредопределенныеЗначения(ТаблицаПредопределенных, ДополнительныеПараметры) Экспорт
Если Не ЗначениеЗаполнено(ТаблицаПредопределенных) Тогда
Возврат;
КонецЕсли;
ПолноеИмяОбъекта = ДополнительныеПараметры.ПолноеИмя;
МенеджерОбъекта = ДополнительныеПараметры.Менеджер;
ПолноеИмяОбъекта = ИмяОбъектаМетаданных(ПолноеИмяОбъекта);
Родители = Новый Соответствие;
Для Каждого СтрокаТаблицы Из ТаблицаПредопределенных Цикл
СтрокаТаблицы.Служебный_Иерархический = ДополнительныеПараметры.Иерархический;
СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов = ДополнительныеПараметры.ИерархияГруппИЭлементов;
ЭтоГруппа = СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов И СтрокаТаблицы.ЭтоГруппа;
КлючиХеша = ?(ЭтоГруппа, ДополнительныеПараметры.КлючиХешаГруппа, ДополнительныеПараметры.КлючиХешаЭлемент);
Если СтрокаТаблицы.Служебный_ОбновитьЭлемент Тогда
ОбновитьЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители);
ИначеЕсли СтрокаТаблицы.Служебный_УстановитьФлагРучноеИзменение Тогда
УстановитьФлагРучноеИзменение(СтрокаТаблицы.Служебный_ПредопределенныйЭлемент);
ИначеЕсли СтрокаТаблицы.Служебный_СоздатьЗаписьРегистра Тогда
СоздатьЗаписьСостоянияПредопределенногоЭлемента(
СтрокаТаблицы.Служебный_ПредопределенныйЭлемент, ЭтоГруппа, КлючиХеша);
Иначе
СоздатьЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Обновляет хеш элемента в регистре, устанавливая при этом ручное изменение.
//
// Параметры:
@ -430,303 +141,3 @@
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Процедура СоздатьЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители)
Если СтрокаТаблицы.Служебный_Иерархический И СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов
И СтрокаТаблицы.ЭтоГруппа Тогда
СоздатьПредопределеннуюГруппу(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители);
Иначе
СоздатьПредопределенныйЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители);
КонецЕсли;
КонецПроцедуры
Процедура СоздатьПредопределеннуюГруппу(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Группы)
НоваяГруппа = МенеджерОбъекта.СоздатьГруппу();
ЗаполнитьЗначенияСвойств(НоваяГруппа, СтрокаТаблицы, "Наименование,ИдентификаторНастройки");
ЗаполнитьЗначениеПоУмолчанию(МенеджерОбъекта, НоваяГруппа, Истина);
Если ЗначениеЗаполнено(СтрокаТаблицы.ИдентификаторРодитель) Тогда
Родитель = Группы.Получить(СтрокаТаблицы.ИдентификаторРодитель);
НоваяГруппа.Родитель = Родитель;
КонецЕсли;
Попытка
ЗаписатьЭлементИСвязанныеДанные(НоваяГруппа, КлючиХеша);
Исключение
пбп_Переадресация.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
Группы.Вставить(СтрокаТаблицы.ИдентификаторНастройки, НоваяГруппа.Ссылка);
КонецПроцедуры
Процедура СоздатьПредопределенныйЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители)
НовыйЭлемент = МенеджерОбъекта.СоздатьЭлемент();
ЗаполнитьЗначенияСвойств(НовыйЭлемент, СтрокаТаблицы, , "Родитель");
ЗаполнитьЗначениеПоУмолчанию(МенеджерОбъекта, НовыйЭлемент, СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов);
Если СтрокаТаблицы.Служебный_Иерархический И ЗначениеЗаполнено(СтрокаТаблицы.ИдентификаторРодитель) Тогда
Родитель = ?(ЗначениеЗаполнено(СтрокаТаблицы.Родитель),
СтрокаТаблицы.Родитель,
Родители[СтрокаТаблицы.ИдентификаторРодитель]);
НовыйЭлемент.Родитель = Родитель;
КонецЕсли;
Попытка
ЗаписатьЭлементИСвязанныеДанные(НовыйЭлемент, КлючиХеша);
Исключение
пбп_Переадресация.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
Если СтрокаТаблицы.Служебный_Иерархический И Не СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов Тогда
Родители.Вставить(СтрокаТаблицы.ИдентификаторНастройки, НовыйЭлемент.Ссылка);
КонецЕсли;
КонецПроцедуры
Процедура ОбновитьЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители)
Если Не ЗначениеЗаполнено(СтрокаТаблицы.Служебный_ПредопределенныйЭлемент) Тогда
Возврат;
КонецЕсли;
Элемент = СтрокаТаблицы.Служебный_ПредопределенныйЭлемент.ПолучитьОбъект();
Если Элемент.ПометкаУдаления Тогда
Элемент.УстановитьПометкуУдаления(Ложь, Ложь);
КонецЕсли;
РодительОтличается = Ложь;
Если СтрокаТаблицы.Служебный_Иерархический
И (Не ПустаяСтрока(СтрокаТаблицы.ИдентификаторРодитель) Или ЗначениеЗаполнено(Элемент.Родитель)) Тогда
НовыйРодитель = ?(ЗначениеЗаполнено(СтрокаТаблицы.Родитель),
СтрокаТаблицы.Родитель,
Родители[СтрокаТаблицы.ИдентификаторРодитель]);
РодительОтличается = Элемент.Родитель <> НовыйРодитель;
Элемент.Родитель = НовыйРодитель;
КонецЕсли;
Свойства = ЗаполняемыеИсключаемыеСвойства(СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов, Элемент.ЭтоГруппа);
ЗаполнитьЗначенияСвойств(Элемент, СтрокаТаблицы, Свойства.СписокСвойств, Свойства.ИсключаяСвойства);
ЗаполнитьЗначениеПоУмолчанию(МенеджерОбъекта, Элемент, СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов);
Попытка
ЗаписатьЭлементИСвязанныеДанные(Элемент, КлючиХеша, Истина);
СообщитьОбИзмененииЭлемента(Элемент);
Если РодительОтличается Тогда
СообщитьОбИзмененииРасположенияЭлемента(Элемент);
КонецЕсли;
Исключение
пбп_Переадресация.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ЗаполнитьЗначениеПоУмолчанию(МенеджерОбъекта, Элемент, ИерархияГруппИЭлементов = Ложь)
ПроверяемыйТип = ТипЗнч(МенеджерОбъекта);
Если ПроверяемыйТип = Тип("ПланВидовХарактеристикМенеджер.пбп_ПредопределенныеЗначения")
И Не (ИерархияГруппИЭлементов И Элемент.ЭтоГруппа) Тогда
Элемент.Значение = Элемент.ТипЗначения.ПривестиЗначение();
КонецЕсли;
КонецПроцедуры
Процедура УстановитьФлагРучноеИзменение(Элемент)
РегистрыСведений.пбп_СостоянияПредопределенныхЭлементов.ОбновитьФлагРучногоИзменения(Элемент, Истина);
КонецПроцедуры
Процедура ПометитьНаУдалениеВсеВложения(ИерархическаяВыборка, ТаблицаАктуальныхЭлементов)
Пока ИерархическаяВыборка.Следующий() Цикл
Строка = ТаблицаАктуальныхЭлементов.Найти(ИерархическаяВыборка.ИдентификаторНастройки, "ИдентификаторНастройки");
Если Строка = Неопределено Тогда
Элемент = ИерархическаяВыборка.Ссылка.ПолучитьОбъект();
Элемент.УстановитьПометкуУдаления(Истина, Истина);
СообщитьОПомеченномНаУдалениеЭлементе(Элемент);
Продолжить;
КонецЕсли;
СпособВыборки = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией;
Если ИерархическаяВыборка.ТипЗаписи() = ТипЗаписиЗапроса.ИтогПоИерархии Тогда
ДочерняяВыборка = ИерархическаяВыборка.Выбрать(СпособВыборки, ИерархическаяВыборка.Группировка());
Иначе
ДочерняяВыборка = ИерархическаяВыборка.Выбрать(СпособВыборки);
КонецЕсли;
ПометитьНаУдалениеВсеВложения(ДочерняяВыборка, ТаблицаАктуальныхЭлементов);
КонецЦикла;
КонецПроцедуры
Функция ПолноеИмяОбъектаПоУмолчанию()
Возврат "ПланВидовХарактеристик.пбп_ПредопределенныеЗначения";
КонецФункции
#Область СообщенияОСобытии
Процедура СообщитьОПомеченномНаУдалениеЭлементе(Элемент)
ТекстСообщения = НСтр("ru = 'Элемент ''%1'' помечен на удаление';
|en = 'The item ''%1'' is marked for deletion'");
Если ЗначениеЗаполнено(Элемент.Родитель) Тогда
ТекстСообщения = ТекстСообщения + НСтр("ru = ', включая все его подчиненные элементы.';
|en = ', including all its subordinate items.'");
КонецЕсли;
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Элемент.Ссылка);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения, Элемент);
КонецПроцедуры
Процедура СообщитьОбИзмененииРасположенияЭлемента(Элемент)
ТекстСообщения = НСтр("ru = 'Расположение элемента ''%1'' изменено. Текущее положение: ''%2''';
|en = 'The location of element ''%1'' has changed. Current position: ''%2'''");
Родитель = ?(ЗначениеЗаполнено(Элемент.Родитель), Элемент.Родитель, НСтр("ru = '''<корень>'''; en = '''<root>'''"));
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Элемент.Ссылка,
Родитель);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения, Элемент);
КонецПроцедуры
Процедура СообщитьОбИзмененииЭлемента(Элемент)
ТекстСообщения = НСтр("ru = 'Элемент ''%1'' успешно обновлен!';
|en = 'Item ''%1'' was successfully updated!'");
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Элемент.Ссылка);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения, Элемент);
КонецПроцедуры
Процедура СообщитьОДублированииИдентификаторов(Идентификатор)
ТекстСообщения = НСтр("ru = 'Идентификатор ''%1'' не уникален!';
|en = 'Identifier ''%1'' is not unique!'");
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Идентификатор);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения);
КонецПроцедуры
Процедура СообщитьОНезаполненностиИдентификатора(Наименование)
ТекстСообщения = НСтр("ru = 'Идентификатор ''%1'' не заполнен!';
|en = 'Identifier ''%1'' is not filled!'");
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Наименование);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения);
КонецПроцедуры
#КонецОбласти
Процедура ЗаписатьЭлементИСвязанныеДанные(Элемент, КлючиХеша, Обновление = Ложь)
Элемент.ДополнительныеСвойства.Вставить("РучноеИзменение", Ложь);
Элемент.Записать();
Если Обновление Тогда
Возврат;
КонецЕсли;
СоздатьЗаписьСостоянияПредопределенногоЭлемента(Элемент.Ссылка, Элемент.ЭтоГруппа, КлючиХеша);
КонецПроцедуры
Функция ИмяОбъектаМетаданных(ПолноеИмяОбъекта)
Если ПустаяСтрока(ПолноеИмяОбъекта) Тогда
Возврат ПолноеИмяОбъектаПоУмолчанию();
КонецЕсли;
Возврат ПолноеИмяОбъекта;
КонецФункции
Процедура ОбработатьСтроку(Строка, Выборка, ТаблицаКонфликтныхЭлементов, СтрокиДляУдаления)
Строка.Служебный_ПредопределенныйЭлемент = Выборка.Ссылка;
Если Выборка.ХешОтсутствует Тогда
Строка.Служебный_СоздатьЗаписьРегистра = Истина;
ИначеЕсли Выборка.ПометкаУдаления Тогда
Строка.Служебный_ОбновитьЭлемент = Истина;
Иначе
СтрокиДляУдаления.Добавить(Строка);
СтрокаКонфликт = ТаблицаКонфликтныхЭлементов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаКонфликт, Строка);
КонецЕсли;
КонецПроцедуры
Функция ЗаполняемыеИсключаемыеСвойства(ИерархияГруппИЭлементов, ЭтоГруппа = Ложь)
Свойства = Новый Структура("СписокСвойств,ИсключаяСвойства");
Если ИерархияГруппИЭлементов И ЭтоГруппа Тогда
Свойства.СписокСвойств = "Наименование,ИдентификаторНастройки";
Иначе
Свойства.ИсключаяСвойства = "Родитель";
КонецЕсли;
Возврат Свойства;
КонецФункции
Процедура ОбработатьДублиИдентификаторов(ТаблицаПредопределенных, ТаблицаКонфликтныхЭлементов)
Просмотренные = Новый Соответствие;
СтрокиДляУдаления = Новый Массив;
Для Каждого Строка Из ТаблицаПредопределенных Цикл
Если ПустаяСтрока(Строка.ИдентификаторНастройки) Тогда
СтрокиДляУдаления.Добавить(Строка);
СообщитьОНезаполненностиИдентификатора(Строка.Наименование);
Продолжить;
КонецЕсли;
Если Просмотренные[Строка.ИдентификаторНастройки] <> Неопределено Тогда
Просмотренные[Строка.ИдентификаторНастройки] = Просмотренные[Строка.ИдентификаторНастройки] + 1;
Иначе
Просмотренные.Вставить(Строка.ИдентификаторНастройки, 1);
КонецЕсли;
КонецЦикла;
Для Каждого Строка Из ТаблицаПредопределенных Цикл
Количество = Просмотренные[Строка.ИдентификаторНастройки];
Если Количество <> Неопределено И Количество > 1 Тогда
СтрокиДляУдаления.Добавить(Строка);
СтрокаКонфликт = ТаблицаКонфликтныхЭлементов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаКонфликт, Строка);
СтрокаКонфликт.Служебный_ДублированиеИдентификаторов = Истина;
СообщитьОДублированииИдентификаторов(Строка.ИдентификаторНастройки);
КонецЕсли;
КонецЦикла;
Для Каждого Строка Из СтрокиДляУдаления Цикл
ТаблицаПредопределенных.Удалить(Строка);
КонецЦикла;
КонецПроцедуры
#КонецОбласти

View File

@ -20,6 +20,298 @@
#Область СлужебныйПрограммныйИнтерфейс
// Обрабатывает таблицу предопределенных элементов. Операции включают в себя: установка пометок удаления
// на неиспользуемые элементы, отбор предопределенных значений, создание предопределенных элементов.
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// МенеджерОбъекта - СправочникМенеджер, ПланВидовХарактеристикМенеджер - менеджер объекта.
//
// Возвращаемое значение:
// ТаблицаЗначений - Таблица с конфликтными элементами
//
Функция ОбработатьПредопределенныеЗначения(ТаблицаПредопределенных, МенеджерОбъекта) Экспорт
Параметры = ДопПараметрыОбработкиПредопределенныхЭлементов(ТаблицаПредопределенных, МенеджерОбъекта);
ОбработатьНеиспользуемыеЭлементы(ТаблицаПредопределенных, Параметры.ПолноеИмя);
ЗаполнитьРодителейЭлементов(ТаблицаПредопределенных, Параметры);
ЗаполнитьКонтрольныеСуммыТаблицы(ТаблицаПредопределенных, Параметры);
ТаблицаКонфликтныхЭлементов = УдалитьИзТаблицыСуществующиеЭлементы(ТаблицаПредопределенных, Параметры);
СоздатьОбновитьПредопределенныеЗначения(ТаблицаПредопределенных, Параметры);
Возврат ТаблицаКонфликтныхЭлементов;
КонецФункции
// Подготавливает параметры необходимые для обработки предопределенных элементов
//
// Параметры:
// Таблица - ТаблицаЗначений - см. пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных.
// МенеджерОбъекта - СправочникМенеджер, ПланВидовХарактеристикМенеджер - менеджер объекта.
//
// Возвращаемое значение:
// Структура - Данные Менеджера объекта
// * Менеджер - СправочникМенеджер, ПланВидовХарактеристикМенеджер - менеджер объекта.
// * ПолноеИмя - Строка - Полное имя объекта метаданных.
// * Иерархический - Булево - Свойство объекта метаданных.
// * ИерархияГруппИЭлементов - Булево - Свойство объекта метаданных.
// * КлючиХешаЭлемент - Структура - Ключевые реквизиты для формирования хеша элемента.
// * КлючиХешаГруппа - Структура - Ключевые реквизиты для формирования хеша группы.
//
Функция ДопПараметрыОбработкиПредопределенныхЭлементов(Таблица, МенеджерОбъекта) Экспорт
Параметры = Новый Структура;
Параметры.Вставить("Менеджер", Неопределено);
Параметры.Вставить("ПолноеИмя", "");
Параметры.Вставить("Иерархический", Ложь);
Параметры.Вставить("ИерархияГруппИЭлементов", Ложь);
Параметры.Вставить("КлючиХешаЭлемент", Новый Структура);
Параметры.Вставить("КлючиХешаГруппа", Новый Структура);
Если Не пбп_ПредопределенныеЗначенияСлужебный.МенеджерВходитВПодсистемуПредопределенных(МенеджерОбъекта) Тогда
Возврат Параметры;
КонецЕсли;
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(МенеджерОбъекта));
Параметры = Новый Структура;
Параметры.Вставить("Менеджер", МенеджерОбъекта);
Параметры.Вставить("ПолноеИмя", ОбъектМетаданных.ПолноеИмя());
Параметры.Вставить("Иерархический", ОбъектМетаданных.Иерархический);
ИерархияГруппИЭлементов = ОбъектМетаданных.Иерархический;
Если Метаданные.Справочники.Содержит(ОбъектМетаданных) Тогда
ИерархияГруппИЭлементов =
ОбъектМетаданных.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов;
КонецЕсли;
Параметры.Вставить("ИерархияГруппИЭлементов", ИерархияГруппИЭлементов);
мКолонки = Новый Массив;
Для Каждого Колонка Из Таблица.Колонки Цикл
мКолонки.Добавить(Колонка.Имя);
КонецЦикла;
Параметры.Вставить("КлючиХешаЭлемент",
пбп_ПредопределенныеЗначения.КлючиХешаПредопределенногоЭлемента(мКолонки, Ложь));
Параметры.Вставить("КлючиХешаГруппа",
пбп_ПредопределенныеЗначения.КлючиХешаПредопределенногоЭлемента(мКолонки, Истина));
Возврат Параметры;
КонецФункции
// Получает все предопределенные элементы объекта, помечает на удаление те, которые удалены из кода.
// При установке пометки удаления для групп, также устанавливается для всех подчиенных элементов.
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ПолноеИмяОбъекта - Строка - Полное имя объекта метаданных.
//
Процедура ОбработатьНеиспользуемыеЭлементы(ТаблицаПредопределенных, ПолноеИмяОбъекта = "") Экспорт
ПолноеИмяОбъекта = ИмяОбъектаМетаданных(ПолноеИмяОбъекта);
ТаблицаПредопределенных.Индексы.Добавить("ИдентификаторНастройки");
Запрос = Новый Запрос;
ТекстЗапроса =
"ВЫБРАТЬ
| пбп_ПредопределенныеЗначения.Ссылка КАК Ссылка,
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки КАК ИдентификаторНастройки
|ИЗ
| %1 КАК пбп_ПредопределенныеЗначения
|ГДЕ
| НЕ пбп_ПредопределенныеЗначения.ПометкаУдаления
|
|УПОРЯДОЧИТЬ ПО
| Ссылка
|ИТОГИ ПО
| Ссылка ИЕРАРХИЯ";
Если пбп_ОбщегоНазначенияПовтИсп.ПолучитьЗначениеКонстанты("пбп_ИспользоватьПользовательскиеФункции") Тогда
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ГДЕ
| НЕ пбп_ПредопределенныеЗначения.ПометкаУдаления",
"ГДЕ
| НЕ пбп_ПредопределенныеЗначения.ПометкаУдаления
| И пбп_ПредопределенныеЗначения.ИдентификаторНастройки <> """"");
КонецЕсли;
Запрос.Текст = СтрШаблон(ТекстЗапроса, ПолноеИмяОбъекта);
Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ПометитьНаУдалениеВсеВложения(Выборка, ТаблицаПредопределенных);
КонецПроцедуры
// Заполняет существующих родителей предопределенных элементов
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ДополнительныеПараметры - Структура - см.пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов
//
Процедура ЗаполнитьРодителейЭлементов(ТаблицаПредопределенных, ДополнительныеПараметры) Экспорт
Идентификаторы = ТаблицаПредопределенных.ВыгрузитьКолонку("ИдентификаторРодитель");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| пбп_ПредопределенныеЗначения.Ссылка КАК Ссылка,
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки КАК ИдентификаторНастройки
|ИЗ
| %1 КАК пбп_ПредопределенныеЗначения
|ГДЕ
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки В(&ИдентификаторыРодитель)";
Запрос.Текст = СтрШаблон(Запрос.Текст, ДополнительныеПараметры.ПолноеИмя);
Запрос.УстановитьПараметр("ИдентификаторыРодитель", Идентификаторы);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Для Каждого Строка Из ТаблицаПредопределенных Цикл
ВыборкаДетальныеЗаписи.Сбросить();
Если ВыборкаДетальныеЗаписи.НайтиСледующий(Строка.ИдентификаторРодитель, "ИдентификаторНастройки") Тогда
Строка.Родитель = ВыборкаДетальныеЗаписи.Ссылка;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Заполняет хеш предопределенных элементов
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ДополнительныеПараметры - Структура - см.пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов
//
Процедура ЗаполнитьКонтрольныеСуммыТаблицы(ТаблицаПредопределенных, ДополнительныеПараметры) Экспорт
Если Не ЗначениеЗаполнено(ТаблицаПредопределенных) Тогда
Возврат;
КонецЕсли;
Для Каждого Строка Из ТаблицаПредопределенных Цикл
КлючиХеша = ?(Строка.ЭтоГруппа, ДополнительныеПараметры.КлючиХешаГруппа, ДополнительныеПараметры.КлючиХешаЭлемент);
ЗаполнитьЗначенияСвойств(КлючиХеша, Строка);
Строка.ХешСумма = пбп_Переадресация.КонтрольнаяСуммаСтрокой(КлючиХеша, ХешФункция.MD5);
КонецЦикла;
КонецПроцедуры
// После удаления уже существующих элементов, остаются только актуальные значения
// для создания предопределенных элементов.
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ДополнительныеПараметры - Структура - см.пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов
//
// Возвращаемое значение:
// ТаблицаЗначений - Таблица с конфликтными элементами
//
Функция УдалитьИзТаблицыСуществующиеЭлементы(ТаблицаПредопределенных, ДополнительныеПараметры) Экспорт
ТаблицаКонфликтныхЭлементов = пбп_ПредопределенныеЗначенияПереопределяемый
.ТаблицаКонфликтныхЭлементов(ДополнительныеПараметры.Менеджер, ТаблицаПредопределенных.СкопироватьКолонки());
Если Не ЗначениеЗаполнено(ТаблицаПредопределенных) Тогда
Возврат ТаблицаКонфликтныхЭлементов;
КонецЕсли;
ПолноеИмяОбъекта = ИмяОбъектаМетаданных(ДополнительныеПараметры.ПолноеИмя);
ТаблицаПредопределенных.Сортировать("ЭтоГруппа УБЫВ, УровеньИерархии");
ОбработатьДублиИдентификаторов(ТаблицаПредопределенных, ТаблицаКонфликтныхЭлементов);
ИдентификаторыНастроек = ТаблицаПредопределенных.ВыгрузитьКолонку("ИдентификаторНастройки");
Запрос = Новый Запрос;
ТекстЗапроса =
"ВЫБРАТЬ
| пбп_ПредопределенныеЗначения.Ссылка КАК Ссылка,
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки КАК ИдентификаторНастройки,
| пбп_СостоянияПредопределенныхЭлементов.ХешСумма КАК ХешСумма,
| ЕСТЬNULL(пбп_СостоянияПредопределенныхЭлементов.РучноеИзменение, ЛОЖЬ) КАК РучноеИзменение,
| пбп_ПредопределенныеЗначения.ПометкаУдаления КАК ПометкаУдаления,
| пбп_СостоянияПредопределенныхЭлементов.ХешСумма ЕСТЬ NULL КАК ХешОтсутствует
|ИЗ
| %1 КАК пбп_ПредопределенныеЗначения
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.пбп_СостоянияПредопределенныхЭлементов КАК пбп_СостоянияПредопределенныхЭлементов
| ПО пбп_ПредопределенныеЗначения.Ссылка = пбп_СостоянияПредопределенныхЭлементов.Объект
|ГДЕ
| пбп_ПредопределенныеЗначения.ИдентификаторНастройки В(&СписокИдентификаторов)";
Запрос.Текст = СтрШаблон(ТекстЗапроса, ПолноеИмяОбъекта);
Запрос.УстановитьПараметр("СписокИдентификаторов", ИдентификаторыНастроек);
ВыборкаДетальныеЗаписи = Запрос.Выполнить().Выбрать();
СтрокиДляУдаления = Новый Массив;
Для Каждого Строка Из ТаблицаПредопределенных Цикл
ВыборкаДетальныеЗаписи.Сбросить();
Если ВыборкаДетальныеЗаписи.НайтиСледующий(Строка.ИдентификаторНастройки, "ИдентификаторНастройки") Тогда
Если ВыборкаДетальныеЗаписи.РучноеИзменение Или ВыборкаДетальныеЗаписи.ХешСумма = Строка.ХешСумма Тогда
СтрокиДляУдаления.Добавить(Строка);
Иначе
ОбработатьСтроку(Строка, ВыборкаДетальныеЗаписи, ТаблицаКонфликтныхЭлементов, СтрокиДляУдаления);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для Каждого Строка Из СтрокиДляУдаления Цикл
ТаблицаПредопределенных.Удалить(Строка);
КонецЦикла;
Возврат ТаблицаКонфликтныхЭлементов;
КонецФункции
// Создание предопределенных значений на основании заполненной таблицы
//
// Параметры:
// ТаблицаПредопределенных - ТаблицаЗначений - см.пбп_ПредопределенныеЗначенияПереопределяемый.ТаблицаПредопределенных
// ДополнительныеПараметры - Структура - см.пбп_ПредопределенныеЗначения.ДопПараметрыОбработкиПредопределенныхЭлементов
//
Процедура СоздатьОбновитьПредопределенныеЗначения(ТаблицаПредопределенных, ДополнительныеПараметры) Экспорт
Если Не ЗначениеЗаполнено(ТаблицаПредопределенных) Тогда
Возврат;
КонецЕсли;
ПолноеИмяОбъекта = ДополнительныеПараметры.ПолноеИмя;
МенеджерОбъекта = ДополнительныеПараметры.Менеджер;
ПолноеИмяОбъекта = ИмяОбъектаМетаданных(ПолноеИмяОбъекта);
Родители = Новый Соответствие;
Для Каждого СтрокаТаблицы Из ТаблицаПредопределенных Цикл
СтрокаТаблицы.Служебный_Иерархический = ДополнительныеПараметры.Иерархический;
СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов = ДополнительныеПараметры.ИерархияГруппИЭлементов;
ЭтоГруппа = СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов И СтрокаТаблицы.ЭтоГруппа;
КлючиХеша = ?(ЭтоГруппа, ДополнительныеПараметры.КлючиХешаГруппа, ДополнительныеПараметры.КлючиХешаЭлемент);
Если СтрокаТаблицы.Служебный_ОбновитьЭлемент Тогда
ОбновитьЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители);
ИначеЕсли СтрокаТаблицы.Служебный_УстановитьФлагРучноеИзменение Тогда
УстановитьФлагРучноеИзменение(СтрокаТаблицы.Служебный_ПредопределенныйЭлемент);
ИначеЕсли СтрокаТаблицы.Служебный_СоздатьЗаписьРегистра Тогда
пбп_ПредопределенныеЗначения.СоздатьЗаписьСостоянияПредопределенногоЭлемента(
СтрокаТаблицы.Служебный_ПредопределенныйЭлемент, ЭтоГруппа, КлючиХеша);
Иначе
СоздатьЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция МенеджерВходитВПодсистемуПредопределенных(МенеджерОбъекта) Экспорт
Если МенеджерОбъекта = Неопределено
@ -37,4 +329,307 @@
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ИмяОбъектаМетаданных(ПолноеИмяОбъекта)
Если ПустаяСтрока(ПолноеИмяОбъекта) Тогда
Возврат ПолноеИмяОбъектаПоУмолчанию();
КонецЕсли;
Возврат ПолноеИмяОбъекта;
КонецФункции
Функция ПолноеИмяОбъектаПоУмолчанию()
Возврат "ПланВидовХарактеристик.пбп_ПредопределенныеЗначения";
КонецФункции
Процедура ПометитьНаУдалениеВсеВложения(ИерархическаяВыборка, ТаблицаАктуальныхЭлементов)
Пока ИерархическаяВыборка.Следующий() Цикл
Строка = ТаблицаАктуальныхЭлементов.Найти(ИерархическаяВыборка.ИдентификаторНастройки, "ИдентификаторНастройки");
Если Строка = Неопределено Тогда
Элемент = ИерархическаяВыборка.Ссылка.ПолучитьОбъект();
Элемент.УстановитьПометкуУдаления(Истина, Истина);
СообщитьОПомеченномНаУдалениеЭлементе(Элемент);
Продолжить;
КонецЕсли;
СпособВыборки = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией;
Если ИерархическаяВыборка.ТипЗаписи() = ТипЗаписиЗапроса.ИтогПоИерархии Тогда
ДочерняяВыборка = ИерархическаяВыборка.Выбрать(СпособВыборки, ИерархическаяВыборка.Группировка());
Иначе
ДочерняяВыборка = ИерархическаяВыборка.Выбрать(СпособВыборки);
КонецЕсли;
ПометитьНаУдалениеВсеВложения(ДочерняяВыборка, ТаблицаАктуальныхЭлементов);
КонецЦикла;
КонецПроцедуры
Процедура ОбработатьДублиИдентификаторов(ТаблицаПредопределенных, ТаблицаКонфликтныхЭлементов)
Просмотренные = Новый Соответствие;
СтрокиДляУдаления = Новый Массив;
Для Каждого Строка Из ТаблицаПредопределенных Цикл
Если ПустаяСтрока(Строка.ИдентификаторНастройки) Тогда
СтрокиДляУдаления.Добавить(Строка);
СообщитьОНезаполненностиИдентификатора(Строка.Наименование);
Продолжить;
КонецЕсли;
Если Просмотренные[Строка.ИдентификаторНастройки] <> Неопределено Тогда
Просмотренные[Строка.ИдентификаторНастройки] = Просмотренные[Строка.ИдентификаторНастройки] + 1;
Иначе
Просмотренные.Вставить(Строка.ИдентификаторНастройки, 1);
КонецЕсли;
КонецЦикла;
Для Каждого Строка Из ТаблицаПредопределенных Цикл
Количество = Просмотренные[Строка.ИдентификаторНастройки];
Если Количество <> Неопределено И Количество > 1 Тогда
СтрокиДляУдаления.Добавить(Строка);
СтрокаКонфликт = ТаблицаКонфликтныхЭлементов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаКонфликт, Строка);
СтрокаКонфликт.Служебный_ДублированиеИдентификаторов = Истина;
СообщитьОДублированииИдентификаторов(Строка.ИдентификаторНастройки);
КонецЕсли;
КонецЦикла;
Для Каждого Строка Из СтрокиДляУдаления Цикл
ТаблицаПредопределенных.Удалить(Строка);
КонецЦикла;
КонецПроцедуры
Процедура ОбработатьСтроку(Строка, Выборка, ТаблицаКонфликтныхЭлементов, СтрокиДляУдаления)
Строка.Служебный_ПредопределенныйЭлемент = Выборка.Ссылка;
Если Выборка.ХешОтсутствует Тогда
Строка.Служебный_СоздатьЗаписьРегистра = Истина;
ИначеЕсли Выборка.ПометкаУдаления Тогда
Строка.Служебный_ОбновитьЭлемент = Истина;
Иначе
СтрокиДляУдаления.Добавить(Строка);
СтрокаКонфликт = ТаблицаКонфликтныхЭлементов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаКонфликт, Строка);
КонецЕсли;
КонецПроцедуры
Процедура СоздатьЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители)
Если СтрокаТаблицы.Служебный_Иерархический И СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов
И СтрокаТаблицы.ЭтоГруппа Тогда
СоздатьПредопределеннуюГруппу(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители);
Иначе
СоздатьПредопределенныйЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители);
КонецЕсли;
КонецПроцедуры
Процедура СоздатьПредопределеннуюГруппу(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Группы)
НоваяГруппа = МенеджерОбъекта.СоздатьГруппу();
ЗаполнитьЗначенияСвойств(НоваяГруппа, СтрокаТаблицы, "Наименование,ИдентификаторНастройки");
ЗаполнитьЗначениеПоУмолчанию(МенеджерОбъекта, НоваяГруппа, Истина);
Если ЗначениеЗаполнено(СтрокаТаблицы.ИдентификаторРодитель) Тогда
Родитель = Группы.Получить(СтрокаТаблицы.ИдентификаторРодитель);
НоваяГруппа.Родитель = Родитель;
КонецЕсли;
Попытка
ЗаписатьЭлементИСвязанныеДанные(НоваяГруппа, КлючиХеша);
Исключение
пбп_Переадресация.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
Группы.Вставить(СтрокаТаблицы.ИдентификаторНастройки, НоваяГруппа.Ссылка);
КонецПроцедуры
Процедура СоздатьПредопределенныйЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители)
НовыйЭлемент = МенеджерОбъекта.СоздатьЭлемент();
ЗаполнитьЗначенияСвойств(НовыйЭлемент, СтрокаТаблицы, , "Родитель");
ЗаполнитьЗначениеПоУмолчанию(МенеджерОбъекта, НовыйЭлемент, СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов);
Если СтрокаТаблицы.Служебный_Иерархический И ЗначениеЗаполнено(СтрокаТаблицы.ИдентификаторРодитель) Тогда
Родитель = ?(ЗначениеЗаполнено(СтрокаТаблицы.Родитель),
СтрокаТаблицы.Родитель,
Родители[СтрокаТаблицы.ИдентификаторРодитель]);
НовыйЭлемент.Родитель = Родитель;
КонецЕсли;
Попытка
ЗаписатьЭлементИСвязанныеДанные(НовыйЭлемент, КлючиХеша);
Исключение
пбп_Переадресация.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
Если СтрокаТаблицы.Служебный_Иерархический И Не СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов Тогда
Родители.Вставить(СтрокаТаблицы.ИдентификаторНастройки, НовыйЭлемент.Ссылка);
КонецЕсли;
КонецПроцедуры
Процедура ОбновитьЭлемент(МенеджерОбъекта, СтрокаТаблицы, КлючиХеша, Родители)
Если Не ЗначениеЗаполнено(СтрокаТаблицы.Служебный_ПредопределенныйЭлемент) Тогда
Возврат;
КонецЕсли;
Элемент = СтрокаТаблицы.Служебный_ПредопределенныйЭлемент.ПолучитьОбъект();
Если Элемент.ПометкаУдаления Тогда
Элемент.УстановитьПометкуУдаления(Ложь, Ложь);
КонецЕсли;
РодительОтличается = Ложь;
Если СтрокаТаблицы.Служебный_Иерархический
И (Не ПустаяСтрока(СтрокаТаблицы.ИдентификаторРодитель) Или ЗначениеЗаполнено(Элемент.Родитель)) Тогда
НовыйРодитель = ?(ЗначениеЗаполнено(СтрокаТаблицы.Родитель),
СтрокаТаблицы.Родитель,
Родители[СтрокаТаблицы.ИдентификаторРодитель]);
РодительОтличается = Элемент.Родитель <> НовыйРодитель;
Элемент.Родитель = НовыйРодитель;
КонецЕсли;
Свойства = ЗаполняемыеИсключаемыеСвойства(СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов, Элемент.ЭтоГруппа);
ЗаполнитьЗначенияСвойств(Элемент, СтрокаТаблицы, Свойства.СписокСвойств, Свойства.ИсключаяСвойства);
ЗаполнитьЗначениеПоУмолчанию(МенеджерОбъекта, Элемент, СтрокаТаблицы.Служебный_ИерархияГруппИЭлементов);
Попытка
ЗаписатьЭлементИСвязанныеДанные(Элемент, КлючиХеша, Истина);
СообщитьОбИзмененииЭлемента(Элемент);
Если РодительОтличается Тогда
СообщитьОбИзмененииРасположенияЭлемента(Элемент);
КонецЕсли;
Исключение
пбп_Переадресация.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ЗаполнитьЗначениеПоУмолчанию(МенеджерОбъекта, Элемент, ИерархияГруппИЭлементов = Ложь)
ПроверяемыйТип = ТипЗнч(МенеджерОбъекта);
Если ПроверяемыйТип = Тип("ПланВидовХарактеристикМенеджер.пбп_ПредопределенныеЗначения")
И Не (ИерархияГруппИЭлементов И Элемент.ЭтоГруппа) Тогда
Элемент.Значение = Элемент.ТипЗначения.ПривестиЗначение();
КонецЕсли;
КонецПроцедуры
Процедура УстановитьФлагРучноеИзменение(Элемент)
РегистрыСведений.пбп_СостоянияПредопределенныхЭлементов.ОбновитьФлагРучногоИзменения(Элемент, Истина);
КонецПроцедуры
Процедура ЗаписатьЭлементИСвязанныеДанные(Элемент, КлючиХеша, Обновление = Ложь)
Элемент.ДополнительныеСвойства.Вставить("РучноеИзменение", Ложь);
Элемент.Записать();
Если Обновление Тогда
Возврат;
КонецЕсли;
пбп_ПредопределенныеЗначения.СоздатьЗаписьСостоянияПредопределенногоЭлемента(
Элемент.Ссылка,
Элемент.ЭтоГруппа,
КлючиХеша);
КонецПроцедуры
Функция ЗаполняемыеИсключаемыеСвойства(ИерархияГруппИЭлементов, ЭтоГруппа = Ложь)
Свойства = Новый Структура("СписокСвойств,ИсключаяСвойства");
Если ИерархияГруппИЭлементов И ЭтоГруппа Тогда
Свойства.СписокСвойств = "Наименование,ИдентификаторНастройки";
Иначе
Свойства.ИсключаяСвойства = "Родитель";
КонецЕсли;
Возврат Свойства;
КонецФункции
#Область СообщенияОСобытии
Процедура СообщитьОПомеченномНаУдалениеЭлементе(Элемент)
ТекстСообщения = НСтр("ru = 'Элемент ''%1'' помечен на удаление';
|en = 'The item ''%1'' is marked for deletion'");
Если ЗначениеЗаполнено(Элемент.Родитель) Тогда
ТекстСообщения = ТекстСообщения + НСтр("ru = ', включая все его подчиненные элементы.';
|en = ', including all its subordinate items.'");
КонецЕсли;
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Элемент.Ссылка);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения, Элемент);
КонецПроцедуры
Процедура СообщитьОДублированииИдентификаторов(Идентификатор)
ТекстСообщения = НСтр("ru = 'Идентификатор ''%1'' не уникален!';
|en = 'Identifier ''%1'' is not unique!'");
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Идентификатор);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения);
КонецПроцедуры
Процедура СообщитьОНезаполненностиИдентификатора(Наименование)
ТекстСообщения = НСтр("ru = 'Идентификатор ''%1'' не заполнен!';
|en = 'Identifier ''%1'' is not filled!'");
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Наименование);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения);
КонецПроцедуры
Процедура СообщитьОбИзмененииРасположенияЭлемента(Элемент)
ТекстСообщения = НСтр("ru = 'Расположение элемента ''%1'' изменено. Текущее положение: ''%2''';
|en = 'The location of element ''%1'' has changed. Current position: ''%2'''");
Родитель = ?(ЗначениеЗаполнено(Элемент.Родитель), Элемент.Родитель, НСтр("ru = '''<корень>'''; en = '''<root>'''"));
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Элемент.Ссылка,
Родитель);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения, Элемент);
КонецПроцедуры
Процедура СообщитьОбИзмененииЭлемента(Элемент)
ТекстСообщения = НСтр("ru = 'Элемент ''%1'' успешно обновлен!';
|en = 'Item ''%1'' was successfully updated!'");
ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстСообщения,
Элемент.Ссылка);
пбп_Переадресация.СообщитьПользователю(ТекстСообщения, Элемент);
КонецПроцедуры
#КонецОбласти
#КонецОбласти

View File

@ -57,7 +57,7 @@
<xr:Item xsi:type="xr:MDObjectRef">Role.ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок</xr:Item>
</DefaultRoles>
<Vendor>Первый БИТ</Vendor>
<Version>1.0.4.14</Version>
<Version>1.0.4.15</Version>
<UpdateCatalogAddress/>
<IncludeHelpInContents>false</IncludeHelpInContents>
<UseManagedFormInOrdinaryApplication>false</UseManagedFormInOrdinaryApplication>

View File

@ -38,6 +38,7 @@
<xr:Item xsi:type="xr:MDObjectRef">CommonModule.пбп_ПредопределенныеЗначенияСлужебныйКлиент</xr:Item>
<xr:Item xsi:type="xr:MDObjectRef">ScheduledJob.пбп_ЗаполнениеПредопределенныхЭлементов</xr:Item>
<xr:Item xsi:type="xr:MDObjectRef">Enum.пбп_ВидыОшибокПредопределенныхЭлементов</xr:Item>
<xr:Item xsi:type="xr:MDObjectRef">CommonModule.пбп_ПредопределенныеЗначенияСлужебный</xr:Item>
</Content>
</Properties>
<ChildObjects/>