mirror of
https://github.com/tormozit/RDT1C.git
synced 2025-12-16 20:54:11 +00:00
1558 lines
125 KiB
Plaintext
1558 lines
125 KiB
Plaintext
//ирПортативный Перем ирПортативный Экспорт;
|
||
//ирПортативный Перем ирОбщий Экспорт;
|
||
//ирПортативный Перем ирСервер Экспорт;
|
||
//ирПортативный Перем ирКэш Экспорт;
|
||
//ирПортативный Перем ирПривилегированный Экспорт;
|
||
|
||
Перем мПлатформа Экспорт;
|
||
Перем мСервисныйПроцессор Экспорт; // Для программного вызова из Интеграции
|
||
Перем мТаблицаБукв;
|
||
Перем мИскомыйОбъектПоискаДублей Экспорт;
|
||
Перем мСтруктураПоиска Экспорт;
|
||
Перем мБылиИсключения;
|
||
Перем мСуффиксСлужбеныхПолей Экспорт;
|
||
Перем мИмяПоляЦенность Экспорт;
|
||
Перем мИмяПоляКоличествоЭлементов Экспорт;
|
||
Перем мИмяПоляКоличествоСсылок Экспорт;
|
||
Перем мИмяПоляНомерГруппы Экспорт;
|
||
Перем мИмяПоляНеправильныеСсылки Экспорт;
|
||
Перем мИмяПоляПравильныйЭлемент Экспорт;
|
||
Перем мИмяПоляНеправильныйЭлемент Экспорт;
|
||
Перем мИмяПоляПравильныеДанные Экспорт;
|
||
Перем мИмяФлагаПравильныйЭлемент Экспорт;
|
||
Перем мИмяФлагаПравильныеДанные Экспорт;
|
||
Перем мИмяПоляИдентификатор Экспорт;
|
||
Перем мРезультатыПоиска Экспорт;
|
||
Перем мПоляСравнения Экспорт;
|
||
|
||
Перем мПутьКДаннымПоляНечеткогоСравнения Экспорт;
|
||
Перем мПредставления Экспорт;
|
||
Перем мСтруктураКлючаПоиска Экспорт;
|
||
Перем мИмяТипаСсылки Экспорт;
|
||
|
||
Функция НайтиДубли(Параметры) Экспорт
|
||
|
||
ИменаВозвращаемыхРеквизитов = "НайденныеГруппы, мРезультатыПоиска";
|
||
Результат = Новый Структура(ИменаВозвращаемыхРеквизитов);
|
||
ЗапросПоискаДублей = ирОбщий.ЗапросИзСтруктурыЛкс(Параметры.СтруктураЗапроса);
|
||
Если Параметры.ПоискПоПохожимСловам Тогда
|
||
НайтиПоПохожимСловам(ЗапросПоискаДублей, Параметры.ТекстИндексов, Параметры.ТекстУпорядочить);
|
||
Иначе
|
||
НайтиПоРавенствуРеквизитов(ЗапросПоискаДублей, Параметры.ТекстИндексов, Параметры.СтрокаПорядкаЦенности);
|
||
КонецЕсли;
|
||
ЗаполнитьЗначенияСвойств(Результат, ЭтотОбъект, ИменаВозвращаемыхРеквизитов);
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Процедура НайтиПоПохожимСловам(ЗапросПоиска, ТекстИндексов, ТекстУпорядочить) Экспорт
|
||
|
||
РезультатПакета = ЗапросПоиска.ВыполнитьПакет();
|
||
#Если Сервер И Не Сервер Тогда
|
||
мПлатформа = Обработки.ирПлатформа.Создать();
|
||
#КонецЕсли
|
||
ИндексыИменРезультатов = мПлатформа.СтруктураРезультатаПакетногоЗапроса(ЗапросПоиска.Текст);
|
||
ПервичныеГруппы = РезультатПакета[ИндексыИменРезультатов.ФинальныеГруппы].Выгрузить();
|
||
ОбщаяТаблицаОбъекта = РезультатПакета[ИндексыИменРезультатов.ЭлементыФинальныхГрупп].Выгрузить();
|
||
#Если Сервер И Не Сервер Тогда
|
||
ПервичныеГруппы = Новый ТаблицаЗначений;
|
||
ОбщаяТаблицаОбъекта = Новый ТаблицаЗначений;
|
||
#КонецЕсли
|
||
мРезультатыПоиска = ОбщаяТаблицаОбъекта.СкопироватьКолонки();
|
||
ИмяПоляНечеткогоСравнения = ирОбщий.ИдентификаторИзПредставленияЛкс(мПутьКДаннымПоляНечеткогоСравнения);
|
||
ТаблицаСлов = мРезультатыПоиска.Скопировать();
|
||
ТаблицаСлов.Колонки.Добавить("СписокСлов");
|
||
МассивСтроковыхПолейСравнения = Новый Массив;
|
||
Для Каждого ЭлементСравнения Из мСтруктураКлючаПоиска Цикл
|
||
Если ПервичныеГруппы.Колонки[ЭлементСравнения.Ключ].ТипЗначения.СодержитТип(Тип("Строка")) Тогда
|
||
МассивСтроковыхПолейСравнения.Добавить(ЭлементСравнения.Ключ);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Для Каждого СтрокаГруппы Из ПервичныеГруппы Цикл
|
||
ВосстановитьЗначенияСтрокВСтрокеРезультатаЗапроса(МассивСтроковыхПолейСравнения, СтрокаГруппы);
|
||
КонецЦикла;
|
||
ОбщаяТаблицаОбъекта.Индексы.Добавить(Сред(ТекстИндексов, 2));
|
||
|
||
НомерГруппы = 1;
|
||
ДобавитьОбщиеКолонкиВРезультатыПоиска();
|
||
НечеткоеСравнениеСлов = мПлатформа.ПолучитьОбъектВнешнейКомпонентыИзМакета("FuzzySearch", "AddIn.FuzzySearch.FuzzyStringMatchExtension", "FuzzySearch");
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ПервичныеГруппы.Количество(), "Первичные группы элементов");
|
||
КлючПоиска = Новый Структура(Сред(ТекстИндексов, 2));
|
||
ПорогПохожести = 0.49 + 0.5 * Макс(0, (70 - ДопустимоеРазличиеСлов) / 70);
|
||
Для Каждого ПервичнаяГруппа Из ПервичныеГруппы Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
ЗаполнитьЗначенияСвойств(КлючПоиска, ПервичнаяГруппа);
|
||
ТаблицаОбъекта = ОбщаяТаблицаОбъекта.Скопировать(КлючПоиска);
|
||
//Если НечеткоеСравнениеСлов <> Неопределено Тогда
|
||
СчетчикОбработанныхСтрок = 0;
|
||
// Сначала обработаем пустые строки, т.к. внешняя компонента их не видит
|
||
СтрокиПустыхСтрок = ТаблицаОбъекта.НайтиСтроки(Новый Структура(ИмяПоляНечеткогоСравнения, ""));
|
||
Если СтрокиПустыхСтрок.Количество() > 0 Тогда
|
||
СтрокаЛевого = СтрокиПустыхСтрок[0];
|
||
СтрокиПустыхСтрок.Удалить(0);
|
||
НачальноеКоличество = СтрокиПустыхСтрок.Количество();
|
||
ГруппаПустая = Истина;
|
||
Для Счетчик = 1 По НачальноеКоличество Цикл
|
||
СтрокаПравого = СтрокиПустыхСтрок[НачальноеКоличество - Счетчик];
|
||
ПодобратьЭлементыГруппыПоПохожимСловам(ГруппаПустая, НомерГруппы, СтрокаЛевого, СтрокаПравого, СчетчикОбработанныхСтрок, ТаблицаОбъекта);
|
||
КонецЦикла;
|
||
ТаблицаОбъекта.Удалить(СтрокаЛевого);
|
||
Если Не ГруппаПустая Тогда
|
||
НомерГруппы = НомерГруппы + 1;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ИндикаторПохожих = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаОбъекта.Количество(), "Поиск похожих слов");
|
||
// Теперь обработаем все оставшиеся (непустые) строки
|
||
Пока ТаблицаОбъекта.Количество() > 1 Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторПохожих, СчетчикОбработанныхСтрок);
|
||
СтрокаЛевого = ТаблицаОбъекта[0];
|
||
ЛевоеЗначение = СтрокаЛевого[ИмяПоляНечеткогоСравнения];
|
||
ГруппаПустая = Истина;
|
||
|
||
//ЛеваяДистанция = НечеткоеСравнениеСлов.Сравнить(ЛевоеЗначение, ЛевоеЗначение);
|
||
//НачальноеКоличество = ТаблицаОбъекта.Количество();
|
||
//Для СчетчикТаблицаОбъектов = 1 По НачальноеКоличество - 1 Цикл
|
||
// СтрокаПравого = ТаблицаОбъекта[НачальноеКоличество - СчетчикТаблицаОбъектов];
|
||
// ПравоеЗначение = СтрокаПравого[ИмяПоляНечеткогоСравнения];
|
||
// ПраваяДистанция = НечеткоеСравнениеСлов.Сравнить(ПравоеЗначение, ПравоеЗначение);
|
||
// Если ЛеваяДистанция > ПраваяДистанция Тогда
|
||
// БазоваяДистанция = ЛеваяДистанция;
|
||
// Иначе
|
||
// БазоваяДистанция = ПраваяДистанция;
|
||
// КонецЕсли;
|
||
// Если БазоваяДистанция > 0 Тогда
|
||
// Дистанция = НечеткоеСравнениеСлов.Сравнить(ЛевоеЗначение, ПравоеЗначение);
|
||
// Если Дистанция / БазоваяДистанция >= ПорогПохожести Тогда
|
||
// ПодобратьЭлементыГруппыПоПохожимСловам(ГруппаПустая, НомерГруппы, СтрокаЛевого, СтрокаПравого, СчетчикОбработанныхСтрок, ТаблицаОбъекта);
|
||
// КонецЕсли;
|
||
// Иначе
|
||
// // нет буквенных символов
|
||
// КонецЕсли;
|
||
//КонецЦикла;
|
||
МассивСтрок = ТаблицаОбъекта.ВыгрузитьКолонку(ИмяПоляНечеткогоСравнения);
|
||
МассивСтрок.Удалить(0);
|
||
РазделительСтрок = "~";
|
||
СтрокаИзМассива = ирОбщий.СтрСоединитьЛкс(МассивСтрок, РазделительСтрок);
|
||
// Параметры 4-5-6:
|
||
//SmallStringLength – число, определяющее максимальную длину небольших строк(для них процент совпадения при поиске отличается от сравнения более длинных строк)
|
||
//SmallStringMatch – минимальный процент совпадения для небольших строк.
|
||
//Match – минимальный процент совпадения для больших строк.
|
||
// Создаем компоненту каждый раз, т.к. у нее внутри что то засоряется и повторный вызов возвращает некорректный результат https://partners.v8.1c.ru/forum/t/1429261/m/1643666
|
||
//НечеткоеСравнениеСлов = мПлатформа.ПолучитьОбъектВнешнейКомпонентыИзМакета("FuzzySearch", "AddIn.FuzzySearch.FuzzyStringMatchExtension", "FuzzySearch");
|
||
//ИндексыНайденныхСовпадений = НечеткоеСравнениеСлов.StringSearch(Нрег(ЛевоеЗначение), Нрег(СтрокаИзМассива), РазделительСтрок, 10, Макс(0, Цел(ПорогПохожести * 100) - 10), Цел(ПорогПохожести * 100));
|
||
ИндексыНайденныхСовпадений = НечеткоеСравнениеСлов.StringSearch(ЛевоеЗначение, СтрокаИзМассива, РазделительСтрок, 10, Макс(0, Цел(ПорогПохожести * 100) - 10), Цел(ПорогПохожести * 100));
|
||
ИндексыПохожихСлов = ирОбщий.СтрРазделитьЛкс(ИндексыНайденныхСовпадений, ",",, Ложь);
|
||
НачальноеКоличество = ИндексыПохожихСлов.Количество();
|
||
Для Счетчик = 1 По НачальноеКоличество Цикл
|
||
ИндексПохожегоСлова = ИндексыПохожихСлов[НачальноеКоличество - Счетчик];
|
||
СтрокаПравого = ТаблицаОбъекта[Число(ИндексПохожегоСлова) + 1];
|
||
ПодобратьЭлементыГруппыПоПохожимСловам(ГруппаПустая, НомерГруппы, СтрокаЛевого, СтрокаПравого, СчетчикОбработанныхСтрок, ТаблицаОбъекта);
|
||
КонецЦикла;
|
||
|
||
Если Не ГруппаПустая Тогда
|
||
НомерГруппы = НомерГруппы + 1;
|
||
КонецЕсли;
|
||
СчетчикОбработанныхСтрок = СчетчикОбработанныхСтрок + 1;
|
||
ТаблицаОбъекта.Удалить(0);
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
//Иначе
|
||
// ирОбщий.СообщитьЛкс("Не удалось подключить внешнюю компоненту " + ИмяВнешнейКомпоненты + " для сравнения строк. Используем простое сравнение строк по словам.");
|
||
// ТаблицаСлов.Очистить();
|
||
// СписокСлов = Новый СписокЗначений;
|
||
// СтрокаПорядкаЦенности = ирОбщий.ВыражениеПорядкаКомпоновкиНаЯзыкеЗапросовЛкс(КомпоновщикЦенности.Настройки.Порядок);
|
||
// Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаОбъекта.Количество(), "Разбивка строк на слова");
|
||
// Счетчик = 1;
|
||
// Для Каждого СтрокаСсылки ИЗ ТаблицаОбъекта Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// Если СтрокаПорядкаЦенности <> "" Тогда
|
||
// СтрокаСсылки[мИмяПоляЦенность] = Счетчик;
|
||
// КонецЕсли;
|
||
// ЗначениеРеквизита = СтрокаСсылки[ИмяПоляНечеткогоСравнения];
|
||
// СписокСлов = ПолучитьСписокСлов(ЗначениеРеквизита);
|
||
// НовСтр = ТаблицаСлов.Добавить();
|
||
// ЗаполнитьЗначенияСвойств(НовСтр, СтрокаСсылки);
|
||
// НовСтр.СписокСлов = СписокСлов.Скопировать();
|
||
// Счетчик = Счетчик + 1;
|
||
// КонецЦикла;
|
||
// ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
// ТаблицаОбъекта = 0;
|
||
// Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаСлов.Количество(), "Анализ значений реквизита");
|
||
// Пока ТаблицаСлов.Количество() > 0 Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ОбрабатываемаяСтрока = ТаблицаСлов[0];
|
||
// ФильтрГруппыРавенства = Новый Структура(ТекстИндексов);
|
||
// ЗаполнитьЗначенияСвойств(ФильтрГруппыРавенства, ОбрабатываемаяСтрока);
|
||
// Если ФильтрГруппыРавенства.Количество() > 0 Тогда
|
||
// СтрокиГруппыРавенства = ТаблицаСлов.НайтиСтроки(ФильтрГруппыРавенства);
|
||
// Иначе
|
||
// СтрокиГруппыРавенства = ТаблицаСлов;
|
||
// КонецЕсли;
|
||
// КоличествоСтрок = СтрокиГруппыРавенства.Количество();
|
||
// СписокСтрок = Новый СписокЗначений;
|
||
// СписокСтрок.Добавить(ОбрабатываемаяСтрока);
|
||
// ТекущийСписокСлов = ОбрабатываемаяСтрока.СписокСлов.Скопировать();
|
||
//
|
||
// Для индекс = 1 по КоличествоСтрок - 1 Цикл
|
||
// СтрокаСравнения = СтрокиГруппыРавенства[индекс];
|
||
// Если СтрокаСравнения = ОбрабатываемаяСтрока Тогда
|
||
// Продолжить;
|
||
// КонецЕсли;
|
||
// //ЭтоНоваяГруппа = Ложь;
|
||
// //Для Каждого ПолеСравнения Из мСтруктураКлючаПоиска Цикл
|
||
// // ИмяПоляСравнения = ПолеСравнения.Ключ;
|
||
// // Если СтрокаСравнения[ИмяПоляСравнения] = ОбрабатываемаяСтрока[ИмяПоляСравнения] Тогда
|
||
// // ЭтоНоваяГруппа = Истина;
|
||
// // Прервать;
|
||
// // КонецЕсли;
|
||
// //КонецЦикла;
|
||
// //Если Не ЭтоНоваяГруппа Тогда
|
||
// // Продолжить;
|
||
// //КонецЕсли;
|
||
// СписокСловСравнения = СтрокаСравнения.СписокСлов.Скопировать();
|
||
// СписокНеНайденных = Новый СписокЗначений;
|
||
//
|
||
// ОдинаковыхСлов = 0;
|
||
// Для Каждого Слово Из ТекущийСписокСлов Цикл
|
||
// ЭлементСпискаСравнения = СписокСловСравнения.НайтиПоЗначению(Слово.Значение);
|
||
// Если ЭлементСпискаСравнения = Неопределено Тогда
|
||
// СписокНеНайденных.Добавить(Слово.Значение);
|
||
// Иначе
|
||
// СписокСловСравнения.Удалить(ЭлементСпискаСравнения);
|
||
// ОдинаковыхСлов = ОдинаковыхСлов + 1;
|
||
// КонецЕсли;
|
||
// КонецЦикла;
|
||
// Если СписокНеНайденных.Количество()=0 И СписокСловСравнения.Количество()=0 Тогда
|
||
// ЕстьОтличия = Ложь;
|
||
// Иначе
|
||
// ЕСли ОдинаковыхСлов > 0 Тогда
|
||
// ЕстьОтличия = АнализРазличийВСловах(СписокНеНайденных, СписокСловСравнения, ТекущийСписокСлов, ОдинаковыхСлов, ДопустимоеРазличиеСлов);
|
||
// Иначе
|
||
// ЕстьОтличия = Истина;
|
||
// КонецЕсли;
|
||
// КонецЕсли;
|
||
// Если НЕ ЕстьОтличия Тогда
|
||
// СписокСтрок.Добавить(СтрокаСравнения);
|
||
// КонецЕсли;
|
||
// КонецЦикла;
|
||
// Для Каждого СтрокаИзСписка ИЗ СписокСтрок Цикл
|
||
// Если СписокСтрок.Количество() > 1 Тогда
|
||
// СтрокаРезультата = мРезультатыПоиска.Добавить();
|
||
// ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтрокаИзСписка.Значение);
|
||
// СтрокаРезультата[мИмяПоляНомерГруппы] = НомерГруппы;
|
||
// Иначе
|
||
// НомерГруппы = НомерГруппы - 1;
|
||
// КонецЕсли;
|
||
// ТаблицаСлов.Удалить(СтрокаИзСписка.Значение);
|
||
// КонецЦикла;
|
||
// НомерГруппы = НомерГруппы + 1;
|
||
// КонецЦикла;
|
||
// ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
//КонецЕсли;
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
НайденныеГруппы = ПервичныеГруппы.СкопироватьКолонки();
|
||
ирОбщий.СкопироватьКолонкиКоллекцииЛкс(мРезультатыПоиска, НайденныеГруппы,, ИмяПоляНечеткогоСравнения);
|
||
НастроитьКолонкиНайденныхГрупп(ТекстИндексов);
|
||
Если мРезультатыПоиска.Количество() > 0 Тогда
|
||
мРезультатыПоиска.Сортировать(мИмяПоляНомерГруппы + " УБЫВ");
|
||
СтруктураПоиска = Новый Структура;
|
||
ВсегоГрупп = мРезультатыПоиска[0][мИмяПоляНомерГруппы];
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ВсегоГрупп, "Обработка результатов");
|
||
Для Индекс = 1 по ВсегоГрупп Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
СтруктураПоиска.Вставить(мИмяПоляНомерГруппы, ВсегоГрупп - Индекс + 1);
|
||
МассивСтрок = мРезультатыПоиска.НайтиСтроки(СтруктураПоиска);
|
||
СтрокаГруппы = НайденныеГруппы.Добавить();
|
||
//ЗаполнитьЗначенияСвойств(СтрокаГруппы, МассивСтрок[0],, мИмяПоляПравильныеДанные + "," + мИмяПоляПравильныйЭлемент);
|
||
ЗаполнитьЗначенияСвойств(СтрокаГруппы, МассивСтрок[0]);
|
||
СтрокаГруппы[мИмяПоляКоличествоЭлементов] = МассивСтрок.Количество();
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
НайденныеГруппы.Сортировать(ТекстУпорядочить);
|
||
КонецЕсли;
|
||
НастроитьСлужебныеКолонкиРезультатовПоиска();
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ПодобратьЭлементыГруппыПоПохожимСловам(ГруппаПустая, Знач НомерГруппы, Знач СтрокаЛевого, СтрокаПравого, СчетчикОбработанныхСтрок, Знач ТаблицаОбъекта)
|
||
|
||
Если ГруппаПустая Тогда
|
||
СтрокаРезультата = мРезультатыПоиска.Добавить();
|
||
ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтрокаЛевого);
|
||
СтрокаРезультата[мИмяПоляНомерГруппы] = НомерГруппы;
|
||
КонецЕсли;
|
||
СтрокаРезультата = мРезультатыПоиска.Добавить();
|
||
ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтрокаПравого);
|
||
СтрокаРезультата[мИмяПоляНомерГруппы] = НомерГруппы;
|
||
ТаблицаОбъекта.Удалить(СтрокаПравого);
|
||
СчетчикОбработанныхСтрок = СчетчикОбработанныхСтрок + 1;
|
||
ГруппаПустая = Ложь;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура НайтиПоРавенствуРеквизитов(ЗапросПоиска, ТекстИндексов, СтрокаПорядкаЦенности = "") Экспорт
|
||
|
||
РезультатПакета = ЗапросПоиска.ВыполнитьПакет();
|
||
#Если Сервер И Не Сервер Тогда
|
||
мПлатформа = Обработки.ирПлатформа.Создать();
|
||
#КонецЕсли
|
||
ИндексыИменРезультатов = мПлатформа.СтруктураРезультатаПакетногоЗапроса(ЗапросПоиска.Текст);
|
||
мРезультатыПоиска = РезультатПакета[ИндексыИменРезультатов.ЭлементыФинальныхГрупп].Выгрузить();
|
||
#Если Сервер И Не Сервер Тогда
|
||
мРезультатыПоиска = Новый ТаблицаЗначений;
|
||
#КонецЕсли
|
||
Если РежимПроизвольногоЗапроса Тогда
|
||
КопияРезультатов = мРезультатыПоиска.Скопировать(, "Ссылка");
|
||
КопияРезультатов.Свернуть("Ссылка");
|
||
Если КопияРезультатов.Количество() <> мРезультатыПоиска.Количество() Тогда
|
||
ирОбщий.СообщитьЛкс("Обнаружены повторяющиеся ссылки в результатах поиска дублей. Рекомендуется исправить произвольный запрос для выдачи только уникальных ссылок.", СтатусСообщения.Внимание);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если ИндексыИменРезультатов.Свойство("СмешанныеПравильные") Тогда
|
||
СмешанныеПравильные = РезультатПакета[ИндексыИменРезультатов.СмешанныеПравильные].Выгрузить()[0][0];
|
||
Если СмешанныеПравильные > 0 Тогда
|
||
ирОбщий.СообщитьЛкс("Проигнорировано " + СмешанныеПравильные + " групп, чьи правильные элементы одновременно являются неправильными в других группах.");
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если ИндексыИменРезультатов.Свойство("НеуникальныеНеправильные") Тогда
|
||
НеуникальныеНеправильные = РезультатПакета[ИндексыИменРезультатов.НеуникальныеНеправильные].Выгрузить()[0][0];
|
||
Если НеуникальныеНеправильные > 0 Тогда
|
||
ирОбщий.СообщитьЛкс("Проигнорировано " + НеуникальныеНеправильные + " неправильных элементов, попавших одновременно в несколько групп");
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
НайденныеГруппы = РезультатПакета[ИндексыИменРезультатов.ФинальныеГруппы].Выгрузить();
|
||
#Если Сервер И Не Сервер Тогда
|
||
НайденныеГруппы = Новый ТаблицаЗначений;
|
||
#КонецЕсли
|
||
Если НайденныеГруппы.Колонки.Найти(мИмяПоляПравильныйЭлемент) <> Неопределено Тогда
|
||
КлючПоиска = Новый Структура(мИмяПоляПравильныйЭлемент);
|
||
Иначе
|
||
КлючПоиска = мСтруктураКлючаПоиска;
|
||
КонецЕсли;
|
||
НастроитьКолонкиНайденныхГрупп(ТекстИндексов);
|
||
МассивСтроковыхПолейСравнения = Новый Массив;
|
||
Для Каждого ЭлементСравнения Из КлючПоиска Цикл
|
||
ТипЗначенияПоля = НайденныеГруппы.Колонки[ЭлементСравнения.Ключ].ТипЗначения;
|
||
Если Истина
|
||
И ТипЗначенияПоля.СодержитТип(Тип("Строка"))
|
||
И ТипЗначенияПоля.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная
|
||
Тогда
|
||
МассивСтроковыхПолейСравнения.Добавить(ЭлементСравнения.Ключ);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
НомерГруппы = 1;
|
||
Для Каждого СтрокаГруппы Из НайденныеГруппы Цикл
|
||
ВосстановитьЗначенияСтрокВСтрокеРезультатаЗапроса(МассивСтроковыхПолейСравнения, СтрокаГруппы);
|
||
СтрокаГруппы[мИмяПоляНомерГруппы] = НомерГруппы;
|
||
НомерГруппы = НомерГруппы + 1;
|
||
КонецЦикла;
|
||
|
||
ДобавитьОбщиеКолонкиВРезультатыПоиска();
|
||
Счетчик = 1;
|
||
Для Каждого СтрокаПоиска ИЗ мРезультатыПоиска Цикл
|
||
ЗаполнитьЗначенияСвойств(КлючПоиска, СтрокаПоиска);
|
||
// 7тч783тгшпт
|
||
Если СтрокаПорядкаЦенности <> "" Тогда
|
||
СтрокаПоиска[мИмяПоляЦенность] = Счетчик;
|
||
КонецЕсли;
|
||
ВосстановитьЗначенияСтрокВСтрокеРезультатаЗапроса(МассивСтроковыхПолейСравнения, КлючПоиска);
|
||
СтрокаПоиска[мИмяПоляНомерГруппы] = НайденныеГруппы.НайтиСтроки(КлючПоиска)[0][мИмяПоляНомерГруппы];
|
||
ЗаполнитьЗначенияСвойств(СтрокаПоиска, КлючПоиска);
|
||
Счетчик = Счетчик + 1;
|
||
КонецЦикла;
|
||
|
||
//Если мРезультатыПоиска.Количество() > 0 Тогда
|
||
// ВывестиГруппу(НайденныеГруппы[0]);
|
||
//КонецЕсли;
|
||
НастроитьСлужебныеКолонкиРезультатовПоиска();
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура НастроитьКолонкиНайденныхГрупп(Знач ТекстИндексов)
|
||
|
||
НайденныеГруппы.Колонки.Удалить("Пустышка");
|
||
НайденныеГруппы.Колонки.Вставить(0, мИмяПоляНомерГруппы);
|
||
НайденныеГруппы.Индексы.Добавить(Сред(ТекстИндексов, 2));
|
||
НайденныеГруппы.Индексы.Добавить(мИмяПоляНомерГруппы);
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ВосстановитьЗначенияСтрокВСтрокеРезультатаЗапроса(Знач МассивСтроковыхПолейСравнения, Знач СтрокаГруппы)
|
||
|
||
Для Каждого СтроковоеПоле Из МассивСтроковыхПолейСравнения Цикл
|
||
ЗначениеПоля = НРег(СокрП(СтрокаГруппы[СтроковоеПоле]));
|
||
// Заменим неразрывный пробел на нормальный
|
||
ЗначениеПоля = СтрЗаменить(ЗначениеПоля, Символ(10 * 16), " ");
|
||
Если УчитыватьПравыеПробелыСтрок Тогда
|
||
// Удалим служебный символ "_" в конце строки
|
||
ЗначениеПоля = Лев(ЗначениеПоля, СтрДлина(ЗначениеПоля) - 1);
|
||
КонецЕсли;
|
||
СтрокаГруппы[СтроковоеПоле] = ЗначениеПоля;
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура НастроитьСлужебныеКолонкиРезультатовПоиска() Экспорт
|
||
|
||
НайденныеГруппы.Колонки.Добавить(мИмяПоляНеправильныеСсылки, Новый ОписаниеТипов("Число"), мПредставления[мИмяПоляНеправильныеСсылки]);
|
||
Если НайденныеГруппы.Колонки.Найти(мИмяПоляПравильныйЭлемент) = Неопределено Тогда
|
||
НайденныеГруппы.Колонки.Добавить(мИмяПоляПравильныйЭлемент, Новый ОписаниеТипов(мИмяТипаСсылки), мПредставления[мИмяПоляПравильныйЭлемент]);
|
||
КонецЕсли;
|
||
НайденныеГруппы.Колонки.Добавить(мИмяПоляПравильныеДанные, Новый ОписаниеТипов(мИмяТипаСсылки), мПредставления[мИмяПоляПравильныеДанные]);
|
||
НайденныеГруппы.Колонки[мИмяПоляКоличествоЭлементов].Заголовок = мПредставления[мИмяПоляПравильныеДанные];
|
||
НайденныеГруппы.Колонки[мИмяПоляНомерГруппы].Заголовок = мПредставления[мИмяПоляНомерГруппы];
|
||
//мРезультатыПоиска.Колонки[мИмяПоляКоличествоЭлементов].Заголовок = мПредставления[мИмяПоляПравильныеДанные];
|
||
мРезультатыПоиска.Колонки[мИмяПоляЦенность].Заголовок = мПредставления[мИмяПоляЦенность];
|
||
мРезультатыПоиска.Колонки[мИмяПоляНомерГруппы].Заголовок = мПредставления[мИмяПоляНомерГруппы];
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ДобавитьОбщиеКолонкиВРезультатыПоиска() Экспорт
|
||
|
||
мРезультатыПоиска.Колонки.Добавить(мИмяПоляНомерГруппы, , мПредставления[мИмяПоляНомерГруппы]);
|
||
Если мРезультатыПоиска.Колонки.Найти(мИмяФлагаПравильныйЭлемент) = Неопределено Тогда
|
||
мРезультатыПоиска.Колонки.Добавить(мИмяФлагаПравильныйЭлемент, Новый ОписаниеТипов("Булево"), мПредставления[мИмяФлагаПравильныйЭлемент]);
|
||
КонецЕсли;
|
||
мРезультатыПоиска.Колонки.Добавить(мИмяФлагаПравильныеДанные, Новый ОписаниеТипов("Булево"), мПредставления[мИмяФлагаПравильныеДанные]);
|
||
мРезультатыПоиска.Колонки.Добавить(мИмяПоляКоличествоСсылок, , мПредставления[мИмяПоляКоличествоСсылок]);
|
||
мРезультатыПоиска.Колонки.Добавить(мИмяПоляИдентификатор, , мПредставления[мИмяПоляИдентификатор]);
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
Функция ЭтоБукваЛкс(Символ)
|
||
|
||
Код = КодСимвола(Символ);
|
||
|
||
Если (Код<=47) ИЛИ (Код>=58 И Код<=64) ИЛИ (Код>=91 И Код<=96) ИЛИ (Код>=123 И Код<=126) Тогда
|
||
Возврат Ложь;
|
||
Иначе
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
Функция АнализРазличийВСловах(Список1, Список2, ПолныйСписок, ОдинаковыхСлов, ДопустимоеРазличиеСлов) Экспорт
|
||
|
||
Если Ложь
|
||
Или Список1.Количество() = ПолныйСписок.Количество()
|
||
Или Список2.Количество() = ПолныйСписок.Количество()
|
||
Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
|
||
Если ПолныйСписок.Количество() = 0 Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
|
||
Если Список1.Количество() = Список2.Количество() Тогда
|
||
ЕстьОтличия = ПроверитьСловаНаОтличие(Список1, Список2, ДопустимоеРазличиеСлов);
|
||
ЕСли НЕ ЕстьОтличия Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ЦелоеСлово = "";
|
||
Для Каждого Слово ИЗ ПолныйСписок Цикл
|
||
ЦелоеСлово = ЦелоеСлово + Слово.Значение;
|
||
КонецЦикла;
|
||
Слово1 = "";
|
||
Для Каждого Слово ИЗ Список1 Цикл
|
||
Слово1 = Слово1 + Слово.Значение;
|
||
КонецЦикла;
|
||
Слово2 = "";
|
||
Для Каждого Слово ИЗ Список2 Цикл
|
||
Слово2 = Слово2 + Слово.Значение;
|
||
КонецЦикла;
|
||
|
||
Если Истина
|
||
И Окр(СтрДлина(Слово1)/СтрДлина(ЦелоеСлово)*100) < ДопустимоеРазличиеСлов
|
||
И Окр(СтрДлина(Слово2)/СтрДлина(ЦелоеСлово)*100) < ДопустимоеРазличиеСлов
|
||
Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция СравнитьСлова(Слово1, Слово2, ДопустимоеРазличиеСлов)
|
||
мТаблицаБукв.Очистить();
|
||
ТаблицаБуквПустая = Истина;
|
||
|
||
ЕСли СтрДлина(Слово1)<=СтрДлина(Слово2) Тогда
|
||
Слово = ВРЕГ(Слово1);
|
||
ИскомоеСлово = ВРЕГ(Слово2);
|
||
Иначе
|
||
Слово = ВРЕГ(Слово2);
|
||
ИскомоеСлово = ВРЕГ(Слово1);
|
||
КонецЕсли;
|
||
|
||
Для индекс = 1 по СтрДлина(Слово) Цикл
|
||
Символ = Сред(Слово, индекс, 1);
|
||
ЕСли ТаблицаБуквПустая Тогда
|
||
поз = Найти(ИскомоеСлово, Символ);
|
||
поправка = 0;
|
||
Пока поз>0 Цикл
|
||
ТаблицаБуквПустая = Ложь;
|
||
НовСтр = мТаблицаБукв.Добавить();
|
||
НовСтр.Позиция = поз + поправка;
|
||
НовСтр.ДлинаСлова = 1;
|
||
НовСтр.КолвоПропущенных = 0;
|
||
поправка = поправка + поз;
|
||
поз = Найти(Сред(ИскомоеСлово, поправка+1), Символ);
|
||
КонецЦикла;
|
||
Иначе
|
||
Для Каждого Вхождение ИЗ мТаблицаБукв Цикл
|
||
Если Сред(ИскомоеСлово, Вхождение.Позиция + Вхождение.ДлинаСлова, 1) = Символ Тогда
|
||
Вхождение.ДлинаСлова = Вхождение.ДлинаСлова + 1;
|
||
ИначеЕсли Сред(Слово, Вхождение.Позиция + Вхождение.ДлинаСлова - Вхождение.КолвоПропущенных, 1) = Вхождение.ПропущеноНа Тогда
|
||
Вхождение.ПропущеноНа = "";
|
||
Вхождение.ДлинаСлова = Вхождение.ДлинаСлова + 1;
|
||
Если Сред(ИскомоеСлово, Вхождение.Позиция + Вхождение.ДлинаСлова, 1) = Символ Тогда
|
||
Вхождение.ДлинаСлова = Вхождение.ДлинаСлова + 1;
|
||
Иначе
|
||
Вхождение.КолвоПропущенных = Вхождение.КолвоПропущенных + 1;
|
||
КонецЕсли;
|
||
Иначе
|
||
ЕСли Окр((Вхождение.КолвоПропущенных + 1) / СтрДлина(ИскомоеСлово) * 100)<=ДопустимоеРазличиеСлов Тогда
|
||
Вхождение.КолвоПропущенных = Вхождение.КолвоПропущенных + 1;
|
||
Вхождение.ДлинаСлова = Вхождение.ДлинаСлова + 1;
|
||
Вхождение.ПропущеноНа = Символ;
|
||
Иначе
|
||
Вхождение.КолвоПропущенных = Вхождение.КолвоПропущенных + 1;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
ЕСли ТаблицаБуквПустая Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
|
||
мТаблицаБукв.Сортировать("ДлинаСлова УБЫВ, КолвоПропущенных ВОЗР");
|
||
|
||
СовпалоСимволов = мТаблицаБукв[0].ДлинаСлова - мТаблицаБукв[0].КолвоПропущенных;
|
||
|
||
Возврат (Окр(СовпалоСимволов / СтрДлина(ИскомоеСлово) * 100) >= (100 - ДопустимоеРазличиеСлов));
|
||
|
||
КонецФункции
|
||
|
||
Функция ПроверитьСловаНаОтличие(СписокСлов1, СписокСлов2, ДопустимоеРазличиеСлов) Экспорт
|
||
|
||
СписокРазличающихсяСлов = Новый СписокЗначений;
|
||
Для Каждого Слово1 ИЗ СписокСлов1 Цикл
|
||
ЕстьПара = Ложь;
|
||
Для Каждого Слово2 Из СписокСлов2 Цикл
|
||
Если СравнитьСлова(Слово1.Значение, Слово2.Значение, ДопустимоеРазличиеСлов) Тогда
|
||
ЕстьПара = Истина;
|
||
СписокСлов2.Удалить(Слово2);
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ЕСли НЕ ЕстьПара Тогда
|
||
СписокРазличающихсяСлов.Добавить(Слово1.Значение);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
СписокСлов1 = СписокРазличающихсяСлов;
|
||
Возврат Не (СписокСлов1.Количество() = 0 И СписокСлов2.Количество() = 0)
|
||
|
||
КонецФункции
|
||
|
||
Функция ПолучитьСписокСлов(ЗначениеРеквизита) Экспорт
|
||
|
||
СписокСлов = Новый СписокЗначений;
|
||
Слово = "";
|
||
Для индекс = 1 по СтрДлина(ЗначениеРеквизита) Цикл
|
||
Символ = Сред(ЗначениеРеквизита, индекс, 1);
|
||
Если ЭтоБукваЛкс(Символ) Тогда
|
||
Слово = Слово + Символ;
|
||
Иначе
|
||
Если Слово<>"" Тогда
|
||
СписокСлов.Добавить(ВРЕГ(Слово));
|
||
Слово = "";
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если Слово<>"" Тогда
|
||
СписокСлов.Добавить(ВРЕГ(Слово));
|
||
КонецЕсли;
|
||
СписокСлов.СортироватьПоЗначению();
|
||
Возврат СписокСлов;
|
||
|
||
КонецФункции // ()
|
||
|
||
// Заменяемые - Соответствие, Массив строк таблицы
|
||
// ТаблицаСсылающихсяОбъектов - ТаблицаЗначений, *Неопределено - таблица ссылающихся объектов возвращаемая методом НайтиПоСсылкам или ее часть
|
||
// ЗамещениеВсегда - Число - замещение в ключах независимых регистров сведений, 1 - замещать, 0 - спрашивать (на клиенте) или пропускать
|
||
//
|
||
Функция ВыполнитьЗаменуЭлементов(Параметры) Экспорт
|
||
|
||
СоответствиеЗамен = Параметры.СоответствиеЗамен;
|
||
ТаблицаСсылающихсяОбъектов = Параметры.НайденныеСсылки;
|
||
ЗаголовокИндикации = "";
|
||
//Если ТранзакцияАктивна() Тогда
|
||
// ВызватьИсключение "Замена ссылок не допускается в общей транзакции";
|
||
//КонецЕсли;
|
||
мБылиИсключения = Ложь;
|
||
СтруктураКоллизий = Новый Структура;
|
||
ИзмененныеПроведенныеДокументы.Очистить();
|
||
Если ТаблицаСсылающихсяОбъектов = Неопределено Тогда
|
||
СписокСсылок = Новый Массив;
|
||
Для Каждого КлючИЗначение Из СоответствиеЗамен Цикл
|
||
СписокСсылок.Добавить(КлючИЗначение.Ключ);
|
||
КонецЦикла;
|
||
ТаблицаСсылающихсяОбъектов = НайтиПоСсылкам(СписокСсылок);
|
||
ирОбщий.ПеревестиКолонкиНайтиПоСсылкамЛкс(ТаблицаСсылающихсяОбъектов);
|
||
КонецЕсли;
|
||
РодителиПравильных = Новый Соответствие;
|
||
Для Каждого КлючИЗначение Из СоответствиеЗамен Цикл
|
||
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючИЗначение.Значение));
|
||
Если ОбъектМД <> Неопределено Тогда
|
||
Если ирОбщий.ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМД) Тогда
|
||
МассивРодителей = Новый Массив;
|
||
Родитель = КлючИЗначение.Значение;
|
||
Если ТипЗнч(Родитель) = Тип("Структура") Тогда
|
||
Родитель = Родитель.Значение;
|
||
КонецЕсли;
|
||
Пока ЗначениеЗаполнено(Родитель) Цикл
|
||
МассивРодителей.Добавить(Родитель);
|
||
Родитель = Родитель.Родитель;
|
||
КонецЦикла;
|
||
РодителиПравильных[КлючИЗначение.Значение] = МассивРодителей;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если ТаблицаСсылающихсяОбъектов.Количество() > 0 Тогда
|
||
Если Не ЗначениеЗаполнено(ЗаголовокИндикации) Тогда
|
||
ЗаголовокИндикации = "Замена ссылок";
|
||
КонецЕсли;
|
||
СтрокаГруппировок = "Метаданные,Данные";
|
||
СсылающиесяОбъекты = ТаблицаСсылающихсяОбъектов.Скопировать(, СтрокаГруппировок);
|
||
СсылающиесяОбъекты.Индексы.Добавить(СтрокаГруппировок);
|
||
ИменаКлючевыхКолонок = "Данные";
|
||
ТаблицаСсылающихсяОбъектов.Индексы.Добавить(ИменаКлючевыхКолонок);
|
||
СсылающиесяОбъекты.Свернуть(СтрокаГруппировок);
|
||
СсылающиесяОбъекты.Сортировать(СтрокаГруппировок);
|
||
КлючПоиска = Новый Структура(ИменаКлючевыхКолонок);
|
||
ТранзакцииРазрешены = Истина;
|
||
#Если Сервер И Не Сервер Тогда
|
||
ЗагрузитьРезультатОбработкиОбъекта();
|
||
ирОбщий.ПодборИОбработкаОбъектов_ОбработатьПорциюОбъектовЛкс();
|
||
#КонецЕсли
|
||
СтруктураПотоков = ирОбщий.НоваяСтруктураМногопоточнойОбработкиЛкс("ЗаменитьСсылкиВОбъектеБД", ЭтотОбъект, "ЗагрузитьРезультатОбработкиОбъекта",
|
||
КоличествоОбъектовВПорции, ВыполнятьНаСервере, КоличествоПотоков);
|
||
Если СтруктураПотоков.ФактическоеКоличествоПотоков > 1 Тогда
|
||
ЗаголовокИндикации = ЗаголовокИндикации + " " + СтруктураПотоков.ФактическоеКоличествоПотоков + " потоков";
|
||
КонецЕсли;
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
Индикатор = мСервисныйПроцессор.ПолучитьИндикаторПроцесса(СсылающиесяОбъекты.Количество(), ЗаголовокИндикации);
|
||
Иначе
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СсылающиесяОбъекты.Количество(), ЗаголовокИндикации);
|
||
КонецЕсли;
|
||
Если СтруктураПотоков.ФактическоеКоличествоПотоков = 1 И ОбщаяТранзакция Тогда
|
||
НачатьТранзакцию();
|
||
КонецЕсли;
|
||
Попытка
|
||
Для Каждого ОписаниеОбъекта Из СсылающиесяОбъекты Цикл
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
мСервисныйПроцессор.ОбновитьИндикатор(Индикатор);
|
||
Иначе
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
КонецЕсли;
|
||
ОписаниеОбъекта = ирОбщий.СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(ОписаниеОбъекта);
|
||
ЗаполнитьЗначенияСвойств(КлючПоиска, ОписаниеОбъекта);
|
||
СсылкиВОбъектеНаНеправильныеЭлементы = ТаблицаСсылающихсяОбъектов.НайтиСтроки(КлючПоиска);
|
||
НеправильныеСсылкиВОбъекте = Новый Массив;
|
||
Для Каждого СтрокаНеправильнойСсылки Из СсылкиВОбъектеНаНеправильныеЭлементы Цикл
|
||
НеправильныеСсылкиВОбъекте.Добавить(СтрокаНеправильнойСсылки.Ссылка);
|
||
КонецЦикла;
|
||
ПараметрыОбработкиОбъекта = Новый Структура;
|
||
ПараметрыОбработкиОбъекта.Вставить("Заменяемые", СоответствиеЗамен);
|
||
ПараметрыОбработкиОбъекта.Вставить("ТранзакцииРазрешены", ТранзакцииРазрешены);
|
||
ПараметрыОбработкиОбъекта.Вставить("НеправильныеСсылкиВОбъекте", НеправильныеСсылкиВОбъекте);
|
||
ПараметрыОбработкиОбъекта.Вставить("ОписаниеОбъекта", ОписаниеОбъекта);
|
||
ПараметрыОбработкиОбъекта.Вставить("РодителиПравильных", РодителиПравильных);
|
||
ирОбщий.ДобавитьОбъектВОчередьМногопоточнойОбработкиЛкс(СтруктураПотоков, ПараметрыОбработкиОбъекта);
|
||
КонецЦикла;
|
||
ирОбщий.ОжидатьЗавершенияВсехПотоковОбработкиЛкс(СтруктураПотоков);
|
||
Если СтруктураПотоков.ФактическоеКоличествоПотоков = 1 И ОбщаяТранзакция Тогда
|
||
ЗафиксироватьТранзакцию();
|
||
КонецЕсли;
|
||
Исключение
|
||
Если СтруктураПотоков.ФактическоеКоличествоПотоков = 1 И ОбщаяТранзакция Тогда
|
||
ОтменитьТранзакцию();
|
||
КонецЕсли;
|
||
ВызватьИсключение;
|
||
КонецПопытки;
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
мСервисныйПроцессор.ОсвободитьИндикаторПроцесса(Индикатор, Истина);
|
||
Иначе
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс(Индикатор, Истина);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
//МассивЭлементовКУдалению = Новый Массив;
|
||
//Для Каждого ЭлементТаблицыРегистра Из СтруктураКоллизий Цикл
|
||
// Если ЭлементТаблицыРегистра.Значение.Количество() = 0 Тогда
|
||
// МассивЭлементовКУдалению.Добавить(ЭлементТаблицыРегистра.Ключ);
|
||
// КонецЕсли;
|
||
//КонецЦикла;
|
||
//Для Каждого ЭлементКУдалению Из МассивЭлементовКУдалению Цикл
|
||
// СтруктураКоллизий.Удалить(ЭлементКУдалению);
|
||
//КонецЦикла;
|
||
//Если СтруктураКоллизий.Количество() > 0 Тогда
|
||
// Если ЗамещениеВсегда = 1 Тогда
|
||
// ЗамещатьВЭтотРаз = Истина;
|
||
// Иначе
|
||
// #Если Клиент Тогда
|
||
// ФормаЗамещенияВНезависимыхРегистрахСведений = ПолучитьФорму("ФормаЗамещенияВНезависимыхРегистрахСведений");
|
||
// ФормаЗамещенияВНезависимыхРегистрахСведений.КодВсегда = ЗамещениеВсегда;
|
||
// ФормаЗамещенияВНезависимыхРегистрахСведений.СтруктураКоллизий = СтруктураКоллизий;
|
||
// ФормаЗамещенияВНезависимыхРегистрахСведений.ОткрытьМодально();
|
||
// ЗамещениеВсегда = ФормаЗамещенияВНезависимыхРегистрахСведений.КодВсегда;
|
||
// ЗамещатьВЭтотРаз = ФормаЗамещенияВНезависимыхРегистрахСведений.РезультатФормы;
|
||
// #Иначе
|
||
// ЗамещатьВЭтотРаз = Ложь;
|
||
// #КонецЕсли
|
||
// КонецЕсли;
|
||
// Если ЗамещатьВЭтотРаз Тогда
|
||
// Для Каждого ЭлементРегистра Из СтруктураКоллизий Цикл
|
||
// Для Каждого СтрокаЗаписи Из ЭлементРегистра.Значение Цикл
|
||
// Если СтрокаЗаписи.Заменить Тогда
|
||
// СтрокаЗаписи.МенеджерЗамены.Записать();
|
||
// КонецЕсли;
|
||
// СтрокаЗаписи.МенеджерОригинала.Удалить();
|
||
// КонецЦикла;
|
||
// КонецЦикла;
|
||
// КонецЕсли;
|
||
//КонецЕсли;
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("ИзмененныеПроведенныеДокументы", ИзмененныеПроведенныеДокументы.Выгрузить());
|
||
Результат.Вставить("СоответствиеЗамен", Параметры.СоответствиеЗамен);
|
||
Результат.Вставить("ОбработкаПоГруппам", Параметры.ОбработкаПоГруппам);
|
||
Результат.Вставить("БезОшибок", Не мБылиИсключения);
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ДобавитьОбъектВОчередьОбработки(Знач Заменяемые, Знач НеправильныеСсылкиВОбъекте, Знач РодителиПравильных, Знач ТранзакцииРазрешены, Знач ОписаниеОбъекта, СтруктураПотоков)
|
||
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗагрузитьРезультатОбработкиОбъекта(Знач РезультатОбработки, _БылиИсключения) Экспорт
|
||
|
||
Если РезультатОбработки.БылиИсключения Тогда
|
||
мБылиИсключения = РезультатОбработки.БылиИсключения;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ЗаменитьСсылкиВОбъектеБД(ПараметрыОбработкиОбъекта) Экспорт
|
||
|
||
Заменяемые = ПараметрыОбработкиОбъекта.Заменяемые;
|
||
НеправильныеСсылкиВОбъекте = ПараметрыОбработкиОбъекта.НеправильныеСсылкиВОбъекте;
|
||
РодителиПравильных = ПараметрыОбработкиОбъекта.РодителиПравильных;
|
||
ТранзакцииРазрешены = ПараметрыОбработкиОбъекта.ТранзакцииРазрешены;
|
||
ОписаниеОбъекта = ПараметрыОбработкиОбъекта.ОписаниеОбъекта;
|
||
|
||
БылиИсключения = Ложь;
|
||
Если ТипЗнч(ОписаниеОбъекта.Метаданные) = Тип("Строка") Тогда
|
||
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ОписаниеОбъекта.Метаданные);
|
||
Иначе
|
||
ОбъектМД = ОписаниеОбъекта.Метаданные;
|
||
КонецЕсли;
|
||
Если ТипЗнч(ОписаниеОбъекта.Данные) = Тип("Строка") Тогда
|
||
ОбъектСодержащийСсылку = ЗначениеИзСтрокиВнутр(ОписаниеОбъекта.Данные);
|
||
Иначе
|
||
ОбъектСодержащийСсылку = ОписаниеОбъекта.Данные;
|
||
КонецЕсли;
|
||
Если КомментироватьЗаменуСсылок Тогда
|
||
ирОбщий.СообщитьЛкс("Обрабатывается " + ОбъектСодержащийСсылку);
|
||
КонецЕсли;
|
||
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
|
||
ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяМД);
|
||
ОбъектИзменен = Ложь;
|
||
Если ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда
|
||
Если ТранзакцииРазрешены Тогда
|
||
НачатьТранзакцию();
|
||
КонецЕсли;
|
||
Попытка
|
||
ирОбщий.ЗаблокироватьСсылкуВТранзакцииЛкс(ОбъектСодержащийСсылку, Истина);
|
||
СтруктураОбъектаБД = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяМД, ОбъектСодержащийСсылку);
|
||
Если СтруктураОбъектаБД.Методы <> Неопределено Тогда
|
||
Для Каждого НеправильнаяСсылка Из НеправильныеСсылкиВОбъекте Цикл
|
||
ОбъектИзменен = ЗаменитьЗначениеВОбъектеБДЛкс(СтруктураОбъектаБД, НеправильнаяСсылка, Заменяемые[НеправильнаяСсылка], РодителиПравильных[Заменяемые[НеправильнаяСсылка]]) Или ОбъектИзменен;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
ЗаписатьОбъектЕслиИзменен(СтруктураОбъектаБД, БылиИсключения, ОбъектИзменен, ОбъектМД);
|
||
Если ТранзакцииРазрешены Тогда
|
||
ЗафиксироватьТранзакцию();
|
||
КонецЕсли;
|
||
Исключение
|
||
Если ТранзакцииРазрешены Тогда
|
||
ОтменитьТранзакцию();
|
||
КонецЕсли;
|
||
БылиИсключения = Истина;
|
||
Если ОбщаяТранзакция Тогда
|
||
ВызватьИсключение;
|
||
КонецЕсли;
|
||
ирОбщий.СообщитьЛкс("Ошибка обработки ссылающегося объекта " + ирОбщий.XMLКлючОбъектаБДЛкс(ОбъектСодержащийСсылку) + ": " + ОписаниеОшибки(), СтатусСообщения.Внимание);
|
||
КонецПопытки;
|
||
Если Не БылиИсключения Тогда
|
||
Если Метаданные.Документы.Содержит(ОбъектМД) Тогда
|
||
КоличествоСтрокПоРегистрам = ирОбщий.ПрочитатьДвиженияДокументаПакетноЛкс(ОбъектСодержащийСсылку,, Истина);
|
||
Для Каждого Движение ИЗ ОбъектМД.Движения Цикл
|
||
ПолноеИмяМД = Движение.ПолноеИмя();
|
||
Если КоличествоСтрокПоРегистрам[ПолноеИмяМД] > 0 Тогда
|
||
ИмяТаблицыРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
|
||
ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыРегистра);
|
||
СтруктураНаборЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыРегистра, Новый Структура(ИмяПоляОтбора, ОбъектСодержащийСсылку),, Ложь);
|
||
БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(СтруктураНаборЗаписей, Заменяемые, НеправильныеСсылкиВОбъекте, ТранзакцииРазрешены);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Для Каждого Последовательность ИЗ Метаданные.Последовательности Цикл
|
||
Если Последовательность.Документы.Содержит(ОбъектМД) Тогда
|
||
ПолноеИмяМД = Последовательность.ПолноеИмя();
|
||
Если КоличествоСтрокПоРегистрам[ПолноеИмяМД] > 0 Тогда
|
||
ИмяТаблицыРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
|
||
ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыРегистра);
|
||
СтруктураНаборЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыРегистра, Новый Структура(ИмяПоляОтбора, ОбъектСодержащийСсылку),, Ложь);
|
||
БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(СтруктураНаборЗаписей, Заменяемые, НеправильныеСсылкиВОбъекте, ТранзакцииРазрешены);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ИначеЕсли ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда
|
||
Если ТранзакцииРазрешены Тогда
|
||
НачатьТранзакцию();
|
||
КонецЕсли;
|
||
Попытка
|
||
СтруктураОбъектаБД = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяМД,,, Ложь);
|
||
ирОбщий.ЗаблокироватьКонстантуЛкс(СтруктураОбъектаБД, Истина);
|
||
СтруктураОбъектаБД.Методы.Прочитать();
|
||
НовоеЗначение = Заменяемые[СтруктураОбъектаБД.Данные.Значение];
|
||
Если НовоеЗначение <> Неопределено Тогда
|
||
СтруктураОбъектаБД.Данные.Значение = НовоеЗначение;
|
||
ОбъектИзменен = Истина;
|
||
ЗаписатьОбъектЕслиИзменен(СтруктураОбъектаБД, БылиИсключения, ОбъектИзменен, ОбъектМД);
|
||
КонецЕсли;
|
||
Если ТранзакцииРазрешены Тогда
|
||
ЗафиксироватьТранзакцию();
|
||
КонецЕсли;
|
||
Исключение
|
||
Если ТранзакцииРазрешены Тогда
|
||
ОтменитьТранзакцию();
|
||
КонецЕсли;
|
||
БылиИсключения = Истина;
|
||
Если ОбщаяТранзакция Тогда
|
||
ВызватьИсключение;
|
||
КонецЕсли;
|
||
ирОбщий.СообщитьЛкс("Ошибка обработки ссылающегося объекта " + ирОбщий.XMLКлючОбъектаБДЛкс(СтруктураОбъектаБД) + ": " + ОписаниеОшибки(), СтатусСообщения.Внимание);
|
||
КонецПопытки;
|
||
ИначеЕсли ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) Тогда
|
||
ИмяТаблицыРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
|
||
СтруктураКлючаЗаписи = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыРегистра);
|
||
ЗаполнитьЗначенияСвойств(СтруктураКлючаЗаписи, ОбъектСодержащийСсылку);
|
||
//МассивИзмененныхИзмерений = Новый Массив;
|
||
//МенеджерЗаписи = РегистрыСведений[ОбъектМД.Имя].СоздатьМенеджерЗаписи();
|
||
//КоллизийныйМенеджерЗаписи = РегистрыСведений[ОбъектМД.Имя].СоздатьМенеджерЗаписи();
|
||
//Если ТранзакцииРазрешены Тогда
|
||
// НачатьТранзакцию();
|
||
//КонецЕсли;
|
||
//Попытка
|
||
// БылаКоллизия = Ложь;
|
||
// ЗаполнитьЗначенияСвойств(МенеджерЗаписи, ОбъектСодержащийСсылку);
|
||
// ЗаполнитьЗначенияСвойств(КоллизийныйМенеджерЗаписи, ОбъектСодержащийСсылку);
|
||
// ирОбщий.ЗаблокироватьРегистрПоМенеджеруЗаписиЛкс(МенеджерЗаписи, Истина);
|
||
// КоллизийныйМенеджерЗаписи.Прочитать();
|
||
// Если КоллизийныйМенеджерЗаписи.Выбран() Тогда
|
||
// ПоляТаблицыБД = ирОбщий.ПоляТаблицыМДЛкс(ПолноеИмяМД,,,, Ложь);
|
||
// ОбъектИзменен = ВыполнитьЗаменуВСтрокеНабораЗаписей(КоллизийныйМенеджерЗаписи, Заменяемые, ПоляТаблицыБД);
|
||
// Если Не БылиИсключения И ОбъектИзменен Тогда
|
||
// Для каждого МетаИзмерение Из ОбъектМД.Измерения Цикл
|
||
// Если КоллизийныйМенеджерЗаписи[МетаИзмерение.Имя] <> ОбъектСодержащийСсылку[МетаИзмерение.Имя] Тогда
|
||
// МассивИзмененныхИзмерений.Добавить(МетаИзмерение.Имя);
|
||
// КонецЕсли;
|
||
// КонецЦикла;
|
||
// Если МассивИзмененныхИзмерений.Количество() > 0 Тогда
|
||
// ЗаполнитьЗначенияСвойств(СтруктураКлючаЗаписи, КоллизийныйМенеджерЗаписи);
|
||
// ирОбщий.ЗаблокироватьРегистрПоМенеджеруЗаписиЛкс(КоллизийныйМенеджерЗаписи, Истина);
|
||
// КоллизийныйМенеджерЗаписи.Прочитать();
|
||
// Если КоллизийныйМенеджерЗаписи.Выбран() Тогда
|
||
// МенеджерЗаписи.Прочитать();
|
||
// МассивКоллекцийРеквизитов = Новый Массив;
|
||
// МассивКоллекцийРеквизитов.Добавить(ОбъектМД.Ресурсы);
|
||
// МассивКоллекцийРеквизитов.Добавить(ОбъектМД.Реквизиты);
|
||
// Если Не СтруктураКоллизий.Свойство(ОбъектМД.Имя) Тогда
|
||
// ТаблицаЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ОбъектМД.ПолноеИмя(),,, Ложь, ОбъектыНаСервере).Методы.Выгрузить();
|
||
// ТаблицаЗаписей.Колонки.Добавить("МенеджерЗамены");
|
||
// ТаблицаЗаписей.Колонки.Добавить("МенеджерОригинала");
|
||
// Для Каждого КоллекцияРеквизитов Из МассивКоллекцийРеквизитов Цикл
|
||
// Для Каждого МетаРеквизит Из КоллекцияРеквизитов Цикл
|
||
// ИмяКолонки = МетаРеквизит.Имя;
|
||
// ПредставлениеКолонки = МетаРеквизит.Представление();
|
||
// КолонкаОригинала = ТаблицаЗаписей.Колонки[ИмяКолонки];
|
||
// КолонкаОригинала.Имя = "Оригинал" + ИмяКолонки;
|
||
// КолонкаОригинала.Заголовок = "Оригинал: " + ПредставлениеКолонки;
|
||
// КолонкаЗамены = ТаблицаЗаписей.Колонки.Вставить(ТаблицаЗаписей.Колонки.Индекс(КолонкаОригинала),
|
||
// "Замена" + ИмяКолонки, , "Замена: " + ПредставлениеКолонки);
|
||
// ЗаполнитьЗначенияСвойств(КолонкаЗамены, КолонкаОригинала, , "Имя, Заголовок");
|
||
// КонецЦикла;
|
||
// КонецЦикла;
|
||
// ТаблицаЗаписей.Колонки.Вставить(0, "Заменить", Новый ОписаниеТипов("Булево"), "Заменить");
|
||
// СтруктураКоллизий.Вставить(ОбъектМД.Имя, ТаблицаЗаписей);
|
||
// КонецЕсли;
|
||
// НоваяКоллизийнаяЗапись = СтруктураКоллизий[ОбъектМД.Имя].Добавить();
|
||
// Для Каждого КоллекцияРеквизитов Из МассивКоллекцийРеквизитов Цикл
|
||
// Для Каждого МетаРеквизит Из КоллекцияРеквизитов Цикл
|
||
// ИмяКолонки = МетаРеквизит.Имя;
|
||
// ЗначениеРеквизита = МенеджерЗаписи[ИмяКолонки];
|
||
// НоваяКоллизийнаяЗапись["Оригинал" + ИмяКолонки] = КоллизийныйМенеджерЗаписи[ИмяКолонки];
|
||
// ЗаменаЗначения = Заменяемые[ЗначениеРеквизита];
|
||
// Если ЗаменаЗначения <> Неопределено Тогда
|
||
// НоваяКоллизийнаяЗапись["Замена" + ИмяКолонки] = ЗаменаЗначения;
|
||
// Иначе
|
||
// НоваяКоллизийнаяЗапись["Замена" + ИмяКолонки] = ЗначениеРеквизита;
|
||
// КонецЕсли;
|
||
// КоллизийныйМенеджерЗаписи[ИмяКолонки] = НоваяКоллизийнаяЗапись["Замена" + ИмяКолонки];
|
||
// Если НоваяКоллизийнаяЗапись["Оригинал" + ИмяКолонки] <> НоваяКоллизийнаяЗапись["Замена" + ИмяКолонки] Тогда
|
||
// БылаКоллизия = Истина;
|
||
// КонецЕсли;
|
||
// КонецЦикла;
|
||
// КонецЦикла;
|
||
// Если БылаКоллизия И ЗамещениеВсегда <> 1 Тогда
|
||
// ЗаполнитьЗначенияСвойств(НоваяКоллизийнаяЗапись, КоллизийныйМенеджерЗаписи);
|
||
// Для Каждого ИмяКолонки Из МассивИзмененныхИзмерений Цикл
|
||
// НоваяКоллизийнаяЗапись[ИмяКолонки] = МенеджерЗаписи[ИмяКолонки];
|
||
// КонецЦикла;
|
||
// НоваяКоллизийнаяЗапись.МенеджерЗамены = КоллизийныйМенеджерЗаписи;
|
||
// НоваяКоллизийнаяЗапись.МенеджерОригинала = МенеджерЗаписи;
|
||
// Иначе
|
||
// СтруктураКоллизий[ОбъектМД.Имя].Удалить(НоваяКоллизийнаяЗапись);
|
||
// МенеджерЗаписи.Удалить();
|
||
// БылаКоллизия = Истина;
|
||
// КонецЕсли;
|
||
// КонецЕсли;
|
||
// КонецЕсли;
|
||
// КонецЕсли;
|
||
// КонецЕсли;
|
||
// Если БылаКоллизия Тогда
|
||
// БылиИсключения = Ложь;
|
||
// Иначе
|
||
// БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(МенеджерЗаписи, Заменяемые, НеправильныеСсылкиВОбъекте);
|
||
// КонецЕсли;
|
||
// Если ТранзакцииРазрешены Тогда
|
||
// ЗафиксироватьТранзакцию();
|
||
// КонецЕсли;
|
||
//Исключение
|
||
// Если ТранзакцииРазрешены Тогда
|
||
// ОтменитьТранзакцию();
|
||
// КонецЕсли;
|
||
// БылиИсключения = Истина;
|
||
// Если ОбщаяТранзакция Тогда
|
||
// ВызватьИсключение;
|
||
// КонецЕсли;
|
||
// НаборЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыРегистра, СтруктураКлючаЗаписи,, Ложь, ОбъектыНаСервере);
|
||
// ирОбщий.СообщитьЛкс("Ошибка обработки ссылающегося объекта " + ирОбщий.ПолучитьXMLКлючОбъектаБДЛкс(НаборЗаписей) + ": " + ОписаниеОшибки(), СтатусСообщения.Внимание);
|
||
//КонецПопытки;
|
||
НаборЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыРегистра, СтруктураКлючаЗаписи,, Ложь);
|
||
БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(НаборЗаписей, Заменяемые, НеправильныеСсылкиВОбъекте);
|
||
Иначе
|
||
БылиИсключения = Истина;
|
||
ирОбщий.СообщитьЛкс("Замена ссылок в объектах типа " + ОбъектМД.ПолноеИмя() + " не поддерживается");
|
||
КонецЕсли;
|
||
РезультатОбработки = Новый Структура("БылиИсключения", БылиИсключения);
|
||
Возврат РезультатОбработки;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ЗаписатьОбъектЕслиИзменен(СтруктураОбъектБД, БылиИсключения, ОбъектИзменен, ОбъектМД)
|
||
|
||
Если ирОбщий.ЛиТипОбъектаБДЛкс(ирОбщий.ТипОбъектаБДЛкс(СтруктураОбъектБД)) Тогда
|
||
//Если Объект.Модифицированность() Тогда
|
||
Если ОбъектИзменен Тогда
|
||
Попытка
|
||
ирОбщий.ЗаписатьОбъектЛкс(СтруктураОбъектБД.Методы);
|
||
//Если ОтключатьКонтрольЗаписи Тогда
|
||
// ЗаписьЖурналаРегистрации("Запись с флагом Загрузка", УровеньЖурналаРегистрации.Информация, ОбъектМД,
|
||
// ОбъектСодержащийСсылку, "");
|
||
//КонецЕсли;
|
||
Исключение
|
||
ирОбщий.СообщитьЛкс(ОписаниеОшибки(), СтатусСообщения.Важное);
|
||
БылиИсключения = Истина;
|
||
ОбъектИзменен = Ложь;
|
||
КонецПопытки;
|
||
Если Истина
|
||
И ОбъектИзменен
|
||
И Метаданные.Документы.Содержит(ОбъектМД)
|
||
И ОбъектМД.Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить
|
||
И СтруктураОбъектБД.Данные.Проведен
|
||
Тогда
|
||
СтрокаДляДокумента = ИзмененныеПроведенныеДокументы.Добавить();
|
||
СтрокаДляДокумента.ДатаДокумента = СтруктураОбъектБД.Данные.Дата;
|
||
СтрокаДляДокумента.ТипДокумента = ОбъектМД.Имя;
|
||
СтрокаДляДокумента.Документ = СтруктураОбъектБД.Данные.Ссылка;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Ищет все экземпляры значения ЧтоЗаменять в объекте и заменяет их на НаЧтоЗаменять
|
||
Функция ЗаменитьЗначениеВОбъектеБДЛкс(СтруктураОбъектаБД, ЧтоЗаменять, НаЧтоЗаменять, РодителиПравильного = Неопределено)
|
||
|
||
ОбъектМД = Метаданные.НайтиПоТипу(ирОбщий.ТипОбъектаБДЛкс(СтруктураОбъектаБД));
|
||
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
|
||
ПоляТаблицыБД = ирОбщий.ПоляТаблицыМДЛкс(ПолноеИмяМД,,,, Ложь);
|
||
#Если Сервер И Не Сервер Тогда
|
||
ПоляТаблицыБД = НайтиПоСсылкам().Колонки;
|
||
#КонецЕсли
|
||
ОбъектИзменен = Ложь;
|
||
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
|
||
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
|
||
ТабличнаяЧасть = СтруктураОбъектаБД.Данные[ПолеТаблицыБД.Имя];
|
||
ПоляТаблицыТЧ = ирОбщий.ПоляТаблицыБДЛкс(ПолноеИмяМД + "." + ПолеТаблицыБД.Имя);
|
||
Если ТипЗнч(ТабличнаяЧасть) = Тип("ТаблицаЗначений") Тогда
|
||
КолонкиТЧ = ТабличнаяЧасть.СкопироватьКолонки();
|
||
Иначе
|
||
КолонкиТЧ = ТабличнаяЧасть.ВыгрузитьКолонки();
|
||
КонецЕсли;
|
||
Для Каждого КолонкаТЧ Из КолонкиТЧ.Колонки Цикл
|
||
ИмяРеквизита = КолонкаТЧ.Имя;
|
||
Если КолонкаТЧ.ТипЗначения.СодержитТип(ТипЗнч(ЧтоЗаменять)) Тогда
|
||
СтрокиТабЧасти = ТабличнаяЧасть.НайтиСтроки(Новый Структура(ИмяРеквизита, ЧтоЗаменять));
|
||
Для Каждого СтрокаТабЧасти Из СтрокиТабЧасти Цикл
|
||
ОбъектИзменен = ЗаменитьЗначениеРеквизитаСПроверкойВозможности(СтрокаТабЧасти, ИмяРеквизита, НаЧтоЗаменять, ПоляТаблицыТЧ) Или ОбъектИзменен;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Иначе
|
||
ИмяРеквизита = "" + ПолеТаблицыБД.Имя;
|
||
Если ирОбщий.СтрокиРавныЛкс(ИмяРеквизита, "Ссылка") Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(ТипЗнч(ЧтоЗаменять)) И СтруктураОбъектаБД.Данные[ИмяРеквизита] = ЧтоЗаменять Тогда
|
||
Если Истина
|
||
И РодителиПравильного <> Неопределено
|
||
И ирОбщий.СтрокиРавныЛкс(ПолеТаблицыБД.Имя, "Родитель")
|
||
И РодителиПравильного.Найти(СтруктураОбъектаБД.Данные.Ссылка) <> Неопределено
|
||
Тогда
|
||
// Вместо зацикливания уровней иерархии поднимаем до ближайшего корректного родителя
|
||
лНаЧтоЗаменять = ЧтоЗаменять.Родитель;
|
||
Пока РодителиПравильного.Найти(лНаЧтоЗаменять) <> Неопределено Цикл
|
||
лНаЧтоЗаменять = лНаЧтоЗаменять.Родитель;
|
||
КонецЦикла;
|
||
ирОбщий.СообщитьЛкс("Родитель объекта """ + СтруктураОбъектаБД.Данные.Ссылка + """ был заменен на """ + лНаЧтоЗаменять + """ для избежания зацикливания уровней");
|
||
Иначе
|
||
лНаЧтоЗаменять = НаЧтоЗаменять;
|
||
КонецЕсли;
|
||
ОбъектИзменен = ЗаменитьЗначениеРеквизитаСПроверкойВозможности(СтруктураОбъектаБД.Данные, ИмяРеквизита, лНаЧтоЗаменять, ПоляТаблицыБД) Или ОбъектИзменен;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Возврат ОбъектИзменен;
|
||
|
||
КонецФункции
|
||
|
||
// Результат - Булево - была ли выполнена замена
|
||
Функция ЗаменитьЗначениеРеквизитаСПроверкойВозможности(СтрокаТаблицы, ИмяРеквизита, НаЧтоЗаменять, ПоляТаблицыБД)
|
||
|
||
ОбъектНеИзменен = Истина;
|
||
ПолнаяЗаменаВозможна = ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицы, ИмяРеквизита, НаЧтоЗаменять, ПоляТаблицыБД, , Истина);
|
||
Если ПолнаяЗаменаВозможна Тогда
|
||
ОбъектНеИзменен = ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицы, ИмяРеквизита, НаЧтоЗаменять, ПоляТаблицыБД, , Ложь);
|
||
КонецЕсли;
|
||
Возврат Не ОбъектНеИзменен;
|
||
|
||
КонецФункции
|
||
|
||
// Результат - Булево
|
||
// Если ТолькоПроверитьВозможность = Истина, то содержит успешность полной замены
|
||
// Если ТолькоПроверитьВозможность = Ложь, то содержит факт отсутствия изменения объекта
|
||
Функция ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицыБД, ИмяРеквизита, Знач НаЧтоЗаменять, ПоляТаблицыБД, ПравилаЗаменыЗависимых = Неопределено,
|
||
ТолькоПроверитьВозможность = Истина, ИмяРеквизитаОтбора = "Ссылка", ИсключитьЗависимое = "", ИсключитьВлияющее = "")
|
||
|
||
Результат = Истина;
|
||
Если ТипЗнч(НаЧтоЗаменять) = Тип("Структура") Тогда
|
||
ПравилаЗаменыЗависимых = НаЧтоЗаменять.ПравилаЗависимых;
|
||
НаЧтоЗаменять = НаЧтоЗаменять.Значение;
|
||
КонецЕсли;
|
||
ЧтоЗаменять = СтрокаТаблицыБД[ИмяРеквизита];
|
||
Если ТипЗнч(ЧтоЗаменять) = Тип("ЭлементОтбора") Тогда
|
||
ЧтоЗаменять = ЧтоЗаменять.Значение;
|
||
КонецЕсли;
|
||
Если ЧтоЗаменять = НаЧтоЗаменять Тогда
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
Если ПравилаЗаменыЗависимых <> Неопределено Тогда
|
||
ПолеТаблицы = ПоляТаблицыБД.Найти(ИмяРеквизита, "Имя");
|
||
ДанныеДляПоискаСвязейПоВладельцу = Неопределено;
|
||
Если ОпределятьСвязьПоВладельцуПоДанным Тогда
|
||
ДанныеДляПоискаСвязейПоВладельцу = СтрокаТаблицыБД;
|
||
КонецЕсли;
|
||
Если ПолеТаблицы.Метаданные <> Неопределено Тогда
|
||
СвязиПараметровВыбора = Новый Массив(ПолеТаблицы.Метаданные.СвязиПараметровВыбора);
|
||
Если ОпределятьСвязьПоВладельцуПоДанным Тогда
|
||
Попытка
|
||
ЗначениеВладельца = ЧтоЗаменять.Владелец;
|
||
Исключение
|
||
ЗначениеВладельца = Неопределено;
|
||
КонецПопытки;
|
||
Если ЗначениеЗаполнено(ЗначениеВладельца) Тогда
|
||
Для Каждого ПолеТаблицыБДВладельца Из ПоляТаблицыБД Цикл
|
||
Попытка
|
||
ЗначениеПоляВладельца = ДанныеДляПоискаСвязейПоВладельцу[ПолеТаблицыБДВладельца.Имя];
|
||
Исключение
|
||
// Ссылка у строки ТЧ
|
||
Продолжить;
|
||
КонецПопытки;
|
||
Если ТипЗнч(ЗначениеПоляВладельца) = Тип("ЭлементОтбора") Тогда
|
||
ЗначениеПоляВладельца = ЗначениеПоляВладельца.Значение;
|
||
КонецЕсли;
|
||
Если ЗначениеПоляВладельца = ЗначениеВладельца Тогда
|
||
СвязиПараметровВыбора.Добавить(Новый Структура("Имя, ПутьКДанным", "Отбор.Владелец", ПолеТаблицыБДВладельца.Имя));
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
УжеОбработанныеРеквизиты = Новый Структура;
|
||
Для Каждого СвязьПараметровВыбора Из СвязиПараметровВыбора Цикл
|
||
ИмяРеквизитаСодежащегоВлияющее = СвязьПараметровВыбора.ПутьКДанным;
|
||
ИмяРеквизитаСодежащегоВлияющее = ирОбщий.ПоследнийФрагментЛкс(ИмяРеквизитаСодежащегоВлияющее);
|
||
Если ИсключитьВлияющее = ИмяРеквизитаСодежащегоВлияющее Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ИмяРеквизитаОтбора = СтрЗаменить(СвязьПараметровВыбора.Имя, "Отбор.", "");
|
||
Если УжеОбработанныеРеквизиты.Свойство(ИмяРеквизитаОтбора) Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
УжеОбработанныеРеквизиты.Вставить(ИмяРеквизитаОтбора);
|
||
ВлияющееЗначениеЧтоЗаменять = ЧтоЗаменять[ИмяРеквизитаОтбора];
|
||
ВлияющееЗначениеНаЧтоЗаменять = НаЧтоЗаменять[ИмяРеквизитаОтбора];
|
||
Если ВлияющееЗначениеЧтоЗаменять <> ВлияющееЗначениеНаЧтоЗаменять Тогда
|
||
Результат = ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицыБД, ИмяРеквизитаСодежащегоВлияющее, ВлияющееЗначениеНаЧтоЗаменять, ПоляТаблицыБД,
|
||
ПравилаЗаменыЗависимых, ТолькоПроверитьВозможность, ИмяРеквизитаОтбора, ИмяРеквизита) И Результат;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
ЗависимыеРеквизиты = ПолучитьЗависимыеРеквизитыМД(ПоляТаблицыБД, ИмяРеквизита, ДанныеДляПоискаСвязейПоВладельцу);
|
||
Для Каждого КлючИЗначение Из ЗависимыеРеквизиты Цикл
|
||
Если ИсключитьЗависимое = КлючИЗначение.Ключ Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ЗависимоеЗначение = СтрокаТаблицыБД[КлючИЗначение.Ключ];
|
||
Если ТипЗнч(ЗависимоеЗначение) = Тип("ЭлементОтбора") Тогда
|
||
ЗависимоеЗначение = ЗависимоеЗначение.Значение;
|
||
КонецЕсли;
|
||
Если Не ЗначениеЗаполнено(ЗависимоеЗначение) Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
КлючПоискаПравила = Новый Структура("ПутьКДаннымВлияющего, ТипЗначения, ЧтоЗаменять, ЗависимоеВлияющее, ВлияющееЧтоЗаменять",
|
||
ИмяРеквизитаОтбора, Новый (ТипЗнч(ЗависимоеЗначение)), ЗависимоеЗначение, КлючИЗначение.Значение, ЧтоЗаменять);
|
||
ПравилаЗаменыЗависимого = ПравилаЗаменыЗависимых.НайтиСтроки(КлючПоискаПравила);
|
||
Если ПравилаЗаменыЗависимого.Количество() > 0 Тогда
|
||
ПравилоЗаменыЗависимого = ПравилаЗаменыЗависимого[0];
|
||
Если ПравилоЗаменыЗависимого.Пометка Тогда
|
||
Результат = ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицыБД, КлючИЗначение.Ключ, ПравилоЗаменыЗависимого.НаЧтоЗаменять, ПоляТаблицыБД,
|
||
ПравилаЗаменыЗависимых, ТолькоПроверитьВозможность, ПравилоЗаменыЗависимого.ЗависимоеВлияющее,, ИмяРеквизита) И Результат;
|
||
Иначе
|
||
Результат = Ложь;
|
||
КонецЕсли;
|
||
Иначе
|
||
ПравилоЗаменыЗависимого = ПравилаЗаменыЗависимых.Добавить();
|
||
ЗаполнитьЗначенияСвойств(ПравилоЗаменыЗависимого, КлючПоискаПравила);
|
||
Результат = Ложь;
|
||
КонецЕсли;
|
||
ПравилоЗаменыЗависимого.НайденоСтрок = ПравилоЗаменыЗависимого.НайденоСтрок + 1;
|
||
ПравилоЗаменыЗависимого.Требуется = Истина;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Если Не ТолькоПроверитьВозможность Тогда
|
||
Если ТипЗнч(СтрокаТаблицыБД[ИмяРеквизита]) = Тип("ЭлементОтбора") Тогда
|
||
Результат = Не ирОбщий.БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(СтрокаТаблицыБД[ИмяРеквизита].Значение, НаЧтоЗаменять) И Результат;
|
||
Иначе
|
||
Результат = Не ирОбщий.БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(СтрокаТаблицыБД[ИмяРеквизита], НаЧтоЗаменять) И Результат;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Функция ВыполнитьЗаменуВНабореЗаписей(НаборЗаписейИлиМенеджерЗаписи, Заменяемые, НеправильныеСсылкиВОбъекте, Блокировать = Истина)
|
||
|
||
ОбъектМД = Метаданные.НайтиПоТипу(ирОбщий.ТипОбъектаБДЛкс(НаборЗаписейИлиМенеджерЗаписи));
|
||
ИмяТаблицыРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ОбъектМД.ПолноеИмя());
|
||
Если ирОбщий.ЛиМенеджерЗаписиРегистраЛкс(НаборЗаписейИлиМенеджерЗаписи) Тогда
|
||
СтруктураКлючаЗаписи = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыРегистра);
|
||
ЗаполнитьЗначенияСвойств(СтруктураКлючаЗаписи, НаборЗаписейИлиМенеджерЗаписи);
|
||
СтруктураНабораЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыРегистра, СтруктураКлючаЗаписи,, Ложь);
|
||
Иначе
|
||
СтруктураНабораЗаписей = НаборЗаписейИлиМенеджерЗаписи;
|
||
КонецЕсли;
|
||
Если Блокировать Тогда
|
||
НачатьТранзакцию();
|
||
КонецЕсли;
|
||
Попытка
|
||
Если Блокировать Тогда
|
||
ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(СтруктураНабораЗаписей.Методы, Истина);
|
||
КонецЕсли;
|
||
ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ИмяТаблицыРегистра);
|
||
СтруктураНабораЗаписей.Методы.Прочитать();
|
||
Если СтруктураНабораЗаписей.Данные.Количество() = 0 Тогда
|
||
Если Блокировать Тогда
|
||
ЗафиксироватьТранзакцию();
|
||
КонецЕсли;
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
ПоляТаблицыБД = ирОбщий.ПоляТаблицыМДЛкс(ОбъектМД,,,, Ложь);
|
||
#Если Сервер И Не Сервер Тогда
|
||
ПоляТаблицыБД = НайтиПоСсылкам().Колонки;
|
||
#КонецЕсли
|
||
|
||
// Старый пустой набор нужен для очистки строк по старому отбору в случае изменения отбора набора
|
||
СтруктураСтарогоНабора = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыРегистра, СтруктураКлючаЗаписи,, Ложь);
|
||
ирОбщий.СкопироватьОтборПостроителяЛкс(СтруктураСтарогоНабора.Методы.Отбор, СтруктураНабораЗаписей.Методы.Отбор, Ложь);
|
||
ОтборИзменен = Ложь;
|
||
Для Каждого ЭлементОтбора Из СтруктураНабораЗаписей.Методы.Отбор Цикл
|
||
ЗначениеПоля = ЭлементОтбора.Значение;
|
||
НаЧтоЗаменять = Заменяемые[ЗначениеПоля];
|
||
Если НаЧтоЗаменять = Неопределено Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ОтборИзменен = ЗаменитьЗначениеРеквизитаСПроверкойВозможности(СтруктураНабораЗаписей.Методы.Отбор, ЭлементОтбора.Имя, НаЧтоЗаменять, ПоляТаблицыБД) Или ОтборИзменен;
|
||
КонецЦикла;
|
||
|
||
ОбъектИзменен = ОтборИзменен; // Антибаг платформы 8.2. При изменении реквизитов строк набора записей для регистра бухгалтерии не взводится модифицированность
|
||
ЭтоРегистрБухгалтерии = ирОбщий.ПервыйФрагментЛкс(ИмяТаблицыРегистра) = "РегистрБухгалтерии";
|
||
Если ЭтоРегистрБухгалтерии Тогда
|
||
ТаблицаНабора = СтруктураНабораЗаписей.Методы.Выгрузить();
|
||
Иначе
|
||
ТаблицаНабора = СтруктураНабораЗаписей.Данные;
|
||
КонецЕсли;
|
||
Для Каждого СтрокаНабора Из ТаблицаНабора Цикл
|
||
ОбъектИзменен = ВыполнитьЗаменуВСтрокеНабораЗаписей(СтрокаНабора, Заменяемые, ПоляТаблицыБД) Или ОбъектИзменен;
|
||
#Если Клиент Тогда
|
||
ОбработкаПрерыванияПользователя();
|
||
#КонецЕсли
|
||
КонецЦикла;
|
||
Если ЭтоРегистрБухгалтерии Тогда
|
||
СтруктураНабораЗаписей.Методы.Загрузить(ТаблицаНабора);
|
||
//ирОбщий.НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(СтруктураНабораЗаписей.Методы); //Теперь это делается в ирОбщий.ЗаписатьОбъектЛкс()
|
||
ИначеЕсли ТипТаблицы = "РегистрСведений" И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
|
||
// Избавимся от неуникальных строк набора
|
||
Если СтруктураНабораЗаписей.Данные.Количество() > 1 Тогда
|
||
СтруктураКлюча = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыРегистра,,, Ложь);
|
||
СтрокаПолейКлюча = "";
|
||
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
|
||
СтрокаПолейКлюча = СтрокаПолейКлюча + "," + КлючИЗначение.Ключ;
|
||
КонецЦикла;
|
||
СтрокаПолейКлюча = Сред(СтрокаПолейКлюча, 2);
|
||
НеуникальныеКлючи = ирОбщий.НеуникальныеКлючиТаблицыЛкс(СтруктураНабораЗаписей.Данные, СтрокаПолейКлюча);
|
||
Если НеуникальныеКлючи.Количество() > 0 Тогда
|
||
ТаблицаНабора = СтруктураНабораЗаписей.Методы.Выгрузить();
|
||
Для Каждого НеуникальныйКлюч Из НеуникальныеКлючи Цикл
|
||
СтрокиНеуникальногоКлюча = ТаблицаНабора.НайтиСтроки(НеуникальныйКлюч);
|
||
Для ИндексУдаляемойСтроки = 0 По СтрокиНеуникальногоКлюча.Количество() - 2 Цикл
|
||
ТаблицаНабора.Удалить(СтрокиНеуникальногоКлюча[ИндексУдаляемойСтроки]);
|
||
КонецЦикла;
|
||
ПредставлениеСтруктуры = ирОбщий.ПолучитьПредставлениеСтруктурыЛкс(НеуникальныйКлюч);
|
||
ирОбщий.СообщитьЛкс("Замещены неуникальные строки регистра сведений " + ОбъектМД.Имя + " по ключу " + ПредставлениеСтруктуры);
|
||
КонецЦикла;
|
||
СтруктураНабораЗаписей.Методы.Загрузить(ТаблицаНабора);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если ОбъектИзменен Тогда
|
||
Если ОтборИзменен Тогда
|
||
ирОбщий.ЗаписатьОбъектЛкс(СтруктураСтарогоНабора.Методы);
|
||
КонецЕсли;
|
||
ирОбщий.ЗаписатьОбъектЛкс(СтруктураНабораЗаписей.Методы);
|
||
КонецЕсли;
|
||
Если ТипТаблицы = "РегистрРасчета" Тогда
|
||
Для Каждого Перерасчет Из ОбъектМД.Перерасчеты Цикл
|
||
#Если Сервер И Не Сервер Тогда
|
||
Перерасчет = Метаданные.РегистрыРасчета.УправленческиеУдержания.Перерасчеты[0];
|
||
#КонецЕсли
|
||
ИмяТаблицыПерерасчета = ирКэш.ИмяТаблицыИзМетаданныхЛкс(Перерасчет.ПолноеИмя());
|
||
СтруктураНабораЗаписейПерерасчета = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыПерерасчета,,, Ложь);
|
||
СтруктураНабораЗаписейПерерасчета.Методы.Отбор[0].Установить(СтруктураНабораЗаписей.Методы.Отбор[0].Значение);
|
||
БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(СтруктураНабораЗаписейПерерасчета, Заменяемые, НеправильныеСсылкиВОбъекте, Ложь);
|
||
Если БылиИсключения Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Если Блокировать Тогда
|
||
ЗафиксироватьТранзакцию();
|
||
КонецЕсли;
|
||
Исключение
|
||
Если Блокировать Тогда
|
||
ОтменитьТранзакцию();
|
||
КонецЕсли;
|
||
Если ОбщаяТранзакция Тогда
|
||
ВызватьИсключение;
|
||
КонецЕсли;
|
||
ирОбщий.СообщитьЛкс("Ошибка обработки ссылающегося объекта " + ирОбщий.XMLКлючОбъектаБДЛкс(СтруктураНабораЗаписей.Методы) + ": " + ОписаниеОшибки(), СтатусСообщения.Внимание);
|
||
Возврат Ложь;
|
||
КонецПопытки;
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция ВыполнитьЗаменуВСтрокеНабораЗаписей(СтрокаНабора, Заменяемые, ПоляТаблицыБД)
|
||
|
||
ОбъектИзменен = Ложь;
|
||
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
|
||
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
//Если Не Поле.Поле Тогда // было для полей построителя запроса
|
||
// // Антибаг платформы. Зачем то добавляются лишние поля в доступные поля, не свойственные по признаку наличия корресподнеции
|
||
// // у бухгалтерских таблиц.
|
||
// Продолжить;
|
||
//КонецЕсли;
|
||
//ИмяПоля = Поле.Имя;
|
||
ИмяПоля = ПолеТаблицыБД.Имя;
|
||
ЗначениеПоля = СтрокаНабора[ИмяПоля];
|
||
НаЧтоЗаменять = Заменяемые[ЗначениеПоля];
|
||
Если НаЧтоЗаменять = Неопределено Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ОбъектИзменен = ЗаменитьЗначениеРеквизитаСПроверкойВозможности(СтрокаНабора, ИмяПоля, НаЧтоЗаменять, ПоляТаблицыБД) Или ОбъектИзменен;
|
||
КонецЦикла;
|
||
Возврат ОбъектИзменен;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПолучитьЗависимыеРеквизитыМД(ПоляТаблицы, ИмяРеквизита, ДанныеДляПоискаСвязейПоВладельцу = Неопределено) Экспорт
|
||
|
||
Результат = Новый Структура;
|
||
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
|
||
Если ПолеТаблицы.Метаданные = Неопределено Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Для Каждого СвязьПараметровВыбора Из ПолеТаблицы.Метаданные.СвязиПараметровВыбора Цикл
|
||
ИмяРеквизитаСодежащегоВлияющее = СвязьПараметровВыбора.ПутьКДанным;
|
||
//Если Найти(ИмяРеквизитаСодежащегоВлияющее, ОбъектМД.Имя + ".") = 1 Тогда
|
||
// // Это строка ТЧ
|
||
ИмяРеквизитаСодежащегоВлияющее = ирОбщий.ПоследнийФрагментЛкс(ИмяРеквизитаСодежащегоВлияющее);
|
||
//КонецЕсли;
|
||
Если ИмяРеквизитаСодежащегоВлияющее = ИмяРеквизита Тогда
|
||
ИмяРеквизитаОтбора = СтрЗаменить(СвязьПараметровВыбора.Имя, "Отбор.", "");
|
||
Результат.Вставить(ПолеТаблицы.Имя, ИмяРеквизитаОтбора);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если ДанныеДляПоискаСвязейПоВладельцу <> Неопределено Тогда
|
||
Попытка
|
||
ЗначениеВладельца = ДанныеДляПоискаСвязейПоВладельцу[ПолеТаблицы.Имя].Владелец;
|
||
Исключение
|
||
ЗначениеВладельца = Неопределено;
|
||
КонецПопытки;
|
||
Если ЗначениеВладельца <> Неопределено Тогда
|
||
Если ЗначениеВладельца = ДанныеДляПоискаСвязейПоВладельцу[ИмяРеквизита] Тогда
|
||
Результат.Вставить(ПолеТаблицы.Имя, "Владелец");
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОбработатьНеправильныйОбъектПослеЗамены(УдаляемаяСсылка, НепосредственноеУдаление = Ложь, СсылкаДляЗаменыДанных = Неопределено) Экспорт
|
||
|
||
#Если Сервер И Не Сервер Тогда
|
||
УдаляемаяСсылка = Справочники.ирАлгоритмы.ПустаяСсылка();
|
||
#КонецЕсли
|
||
ПолноеИмяМД = УдаляемаяСсылка.Метаданные().ПолноеИмя();
|
||
СтруктураНеправильногоОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяМД, УдаляемаяСсылка);
|
||
ОбъектУдалили = СтруктураНеправильногоОбъекта.Методы.ЭтоНовый();
|
||
Если Не ОбъектУдалили Тогда
|
||
КорневойТип = ирОбщий.КорневойТипКонфигурацииЛкс(УдаляемаяСсылка);
|
||
НачатьТранзакцию();
|
||
Попытка
|
||
ПредставлениеОбъекта = "" + УдаляемаяСсылка;
|
||
Если СсылкаДляЗаменыДанных <> Неопределено Тогда
|
||
СтруктураПравильногоОбъектаСНеправильнымиДанными = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяМД, СсылкаДляЗаменыДанных);
|
||
СтандартнаяОбработка = Истина;
|
||
Если ЗначениеЗаполнено(ОбработкаЗаменыДанных) Тогда
|
||
ТекстАлгоритма = "ПравильныйОбъект = _П0; НеправильныйОбъект = _П1; СтандартнаяОбработка = _П2; " + ОбработкаЗаменыДанных + "; _П2 = СтандартнаяОбработка;";
|
||
ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритма,,, СтруктураПравильногоОбъектаСНеправильнымиДанными.Данные, СтруктураНеправильногоОбъекта.Данные, СтандартнаяОбработка);
|
||
КонецЕсли;
|
||
Если СтандартнаяОбработка Тогда
|
||
Если ТипЗнч(СтруктураНеправильногоОбъекта.Данные) = Тип("Структура") Тогда
|
||
СтруктураПравильногоОбъектаСНеправильнымиДанными.Методы.Ссылка = УдаляемаяСсылка;
|
||
СтруктураНеправильногоОбъекта.Методы.Ссылка = СсылкаДляЗаменыДанных;
|
||
СтруктураПравильногоОбъекта = СтруктураНеправильногоОбъекта;
|
||
СтруктураНеправильногоОбъекта = СтруктураПравильногоОбъектаСНеправильнымиДанными;
|
||
Иначе
|
||
ПравильныйОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураНеправильногоОбъекта.Данные);
|
||
ПравильныйОбъектXDTO.Ref = СсылкаДляЗаменыДанных;
|
||
ПравильныйОбъект = СериализаторXDTO.ПрочитатьXDTO(ПравильныйОбъектXDTO);
|
||
СтруктураПравильногоОбъекта = Новый Структура("Методы, Данные", ПравильныйОбъект, ПравильныйОбъект);
|
||
КонецЕсли;
|
||
Если Истина
|
||
И Не ирОбщий.РежимСовместимостиМеньше8_3_4Лкс()
|
||
И ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип)
|
||
И (Ложь
|
||
Или Не НепосредственноеУдаление
|
||
Или (Истина
|
||
И НепосредственноеУдаление
|
||
И Не ЗначениеЗаполнено(СтруктураПравильногоОбъекта.Данные.ИмяПредопределенныхДанных)))
|
||
Тогда
|
||
СтруктураПравильногоОбъекта.Данные.ИмяПредопределенныхДанных = СтруктураПравильногоОбъектаСНеправильнымиДанными.Данные.ИмяПредопределенныхДанных;
|
||
КонецЕсли;
|
||
СтруктураПравильногоОбъекта.Данные.ПометкаУдаления = Ложь;
|
||
ПравильныйОбъект = СтруктураПравильногоОбъекта.Методы;
|
||
Иначе
|
||
ПравильныйОбъект = СтруктураПравильногоОбъектаСНеправильнымиДанными;
|
||
КонецЕсли;
|
||
ирОбщий.ЗаписатьОбъектЛкс(ПравильныйОбъект, , , , Истина);
|
||
КонецЕсли;
|
||
Если НепосредственноеУдаление Тогда
|
||
ирОбщий.УдалитьОбъектЛкс(СтруктураНеправильногоОбъекта.Методы);
|
||
ОбъектУдалили = Истина;
|
||
ирОбщий.СообщитьЛкс("Удалили """ + ПредставлениеОбъекта + """");
|
||
Иначе
|
||
ирОбщий.УстановитьПометкуУдаленияОбъектаЛкс(СтруктураНеправильногоОбъекта.Методы, , Истина);
|
||
ирОбщий.СообщитьЛкс("Установили пометку удаления """ + ПредставлениеОбъекта + """");
|
||
КонецЕсли;
|
||
ЗафиксироватьТранзакцию();
|
||
Исключение
|
||
ирОбщий.СообщитьЛкс("Обработка неправильного """ + ПредставлениеОбъекта + """: " + ОписаниеОшибки());
|
||
ОтменитьТранзакцию();
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
Возврат ОбъектУдалили;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ОбработатьПравильныйОбъектПослеЗамены(ПравильнаяСсылка, СнятьПометкуУдаления = Ложь, Перезаписать = Ложь) Экспорт
|
||
|
||
Если Истина
|
||
И Не СнятьПометкуУдаления
|
||
И Не Перезаписать
|
||
Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
ПолноеИмяМД = ПравильнаяСсылка.Метаданные().ПолноеИмя();
|
||
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяМД, ПравильнаяСсылка);
|
||
Попытка
|
||
Если СнятьПометкуУдаления Тогда
|
||
СтруктураОбъекта.Данные.ПометкаУдаления = Ложь;
|
||
ирОбщий.СообщитьЛкс("Сняли пометку удаления """ + ПравильнаяСсылка + """");
|
||
КонецЕсли;
|
||
ирОбщий.ЗаписатьОбъектЛкс(СтруктураОбъекта.Методы);
|
||
Исключение
|
||
ирОбщий.СообщитьЛкс("Обработка правильного """ + ПравильнаяСсылка + """: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
|
||
КонецПопытки;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ПолучитьСсылочныеИзмеренияРегистраЛкс(НаборЗаписей, МетаРегистр) Экспорт
|
||
|
||
ПоляТаблицы = НаборЗаписей.ВыгрузитьКолонки();
|
||
Результат = Новый Структура;
|
||
Для Каждого МетаИзмерение Из МетаРегистр.Измерения Цикл
|
||
ПолеТаблицы = ПоляТаблицы.Найти(МетаИзмерение.Имя);
|
||
Если ПолеТаблицы = Неопределено Тогда
|
||
// Например, небалансовое измерение регистра бухгалтерии
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Для Каждого Тип Из МетаИзмерение.Тип.Типы() Цикл
|
||
Если Найти(XMLТип(Тип).ИмяТипа, "Ref.") > 0 Тогда
|
||
Результат.Вставить(МетаИзмерение.Имя, МетаИзмерение.Тип);
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Процедура _ЗаблокироватьРегистрПоОтборуИИзмерениямПередЗаменой(НаборЗаписей, НайденныеВОбъектеНеправильныеСсылки) Экспорт
|
||
|
||
Если ирОбщий.ЗапретитьУправляемуюБлокировку() Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
Блокировка = Новый БлокировкаДанных;
|
||
ОбъектМД = НаборЗаписей.Метаданные();
|
||
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
|
||
ИмяТаблицыРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
|
||
ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ИмяТаблицыРегистра);
|
||
|
||
// По регистратору
|
||
Если Ложь
|
||
Или Не ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
|
||
Или ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
|
||
Тогда
|
||
ПространствоБлокировок = ПолноеИмяМД + ".НаборЗаписей";
|
||
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
|
||
ЭлементБлокировки.УстановитьЗначение("Регистратор", НаборЗаписей.Отбор.Регистратор.Значение);
|
||
КонецЕсли;
|
||
|
||
// По измерениям блокируем все возможные диапазоны. В большинстве случаев при замене ссылок такие блокировки будут неоправданными
|
||
ПространствоБлокировок = ПолноеИмяМД;
|
||
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
|
||
СсылочныеИзмерения = ПолучитьСсылочныеИзмеренияРегистраЛкс(НаборЗаписей, ОбъектМД);
|
||
Для Каждого КлючЗначение Из СсылочныеИзмерения Цикл
|
||
ИмяИзмерения = КлючЗначение.Ключ;
|
||
ТипИзмерения = КлючЗначение.Значение;
|
||
Для Каждого НеправильнаяСсылка Из НайденныеВОбъектеНеправильныеСсылки Цикл
|
||
Если ТипИзмерения.СодержитТип(ТипЗнч(НеправильнаяСсылка)) Тогда
|
||
Блокировка.Добавить(ПространствоБлокировок).УстановитьЗначение(ИмяИзмерения, НеправильнаяСсылка);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
|
||
Блокировка.Заблокировать();
|
||
|
||
КонецПроцедуры
|
||
|
||
//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
|
||
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
|
||
//ирПортативный #Если Клиент Тогда
|
||
//ирПортативный Контейнер = Новый Структура();
|
||
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
|
||
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
|
||
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
|
||
//ирПортативный ирПортативный.Открыть();
|
||
//ирПортативный КонецЕсли;
|
||
//ирПортативный #Иначе
|
||
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
|
||
//ирПортативный #КонецЕсли
|
||
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
|
||
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
|
||
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
|
||
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");
|
||
|
||
мПлатформа = ирКэш.Получить();
|
||
ЭтотОбъект.КоличествоПотоков = 1;
|
||
ЭтотОбъект.КоличествоОбъектовВПорции = 10;
|
||
мТаблицаБукв = Новый ТаблицаЗначений;
|
||
мТаблицаБукв.Колонки.Добавить("Позиция");
|
||
мТаблицаБукв.Колонки.Добавить("КолвоПропущенных");
|
||
мТаблицаБукв.Колонки.Добавить("ДлинаСлова");
|
||
мТаблицаБукв.Колонки.Добавить("ПропущеноНа");
|
||
мСуффиксСлужбеныхПолей = ирОбщий.СуффиксСлужебногоСвойстваЛкс(); // Для устранения пересечений с именами полей данных
|
||
мИмяПоляКоличествоСсылок = "КоличествоСсылок" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляЦенность = "ЦенностьДанных" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляКоличествоЭлементов = "КоличествоЭлементовВГруппе" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляИдентификатор = "Идентификатор" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляНомерГруппы = "НомерГруппы" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляКоличествоСсылок = "КоличествоСсылок" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляНеправильныеСсылки = "НеправильныеСсылки" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляНеправильныйЭлемент = "НеправильныйЭлемент" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляПравильныйЭлемент = "ПравильныйЭлемент" + мСуффиксСлужбеныхПолей;
|
||
мИмяПоляПравильныеДанные = "ПравильныеДанные" + мСуффиксСлужбеныхПолей;
|
||
мИмяФлагаПравильныйЭлемент = "ЭтоПравильныйЭлемент" + мСуффиксСлужбеныхПолей;
|
||
мИмяФлагаПравильныеДанные = "ЭтоПравильныеДанные" + мСуффиксСлужбеныхПолей;
|