RDT1C/DataProcessors/ирПоискДублейИЗаменаСсылок/Ext/ObjectModule.bsl
Администратор 1f8f6575bc .
2021-09-15 20:09:07 +03:00

1558 lines
125 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
Перем мПлатформа Экспорт;
Перем мСервисныйПроцессор Экспорт; // Для программного вызова из Интеграции
Перем мТаблицаБукв;
Перем мИскомыйОбъектПоискаДублей Экспорт;
Перем мСтруктураПоиска Экспорт;
Перем мБылиИсключения;
Перем мСуффиксСлужбеныхПолей Экспорт;
Перем мИмяПоляЦенность Экспорт;
Перем мИмяПоляКоличествоЭлементов Экспорт;
Перем мИмяПоляКоличествоСсылок Экспорт;
Перем мИмяПоляНомерГруппы Экспорт;
Перем мИмяПоляНеправильныеСсылки Экспорт;
Перем мИмяПоляПравильныйЭлемент Экспорт;
Перем мИмяПоляНеправильныйЭлемент Экспорт;
Перем мИмяПоляПравильныеДанные Экспорт;
Перем мИмяФлагаПравильныйЭлемент Экспорт;
Перем мИмяФлагаПравильныеДанные Экспорт;
Перем мИмяПоляИдентификатор Экспорт;
Перем мРезультатыПоиска Экспорт;
Перем мПоляСравнения Экспорт;
Перем мПутьКДаннымПоляНечеткогоСравнения Экспорт;
Перем мПредставления Экспорт;
Перем мСтруктураКлючаПоиска Экспорт;
Перем мИмяТипаСсылки Экспорт;
Функция НайтиДубли(Параметры) Экспорт
ИменаВозвращаемыхРеквизитов = "НайденныеГруппы, мРезультатыПоиска";
Результат = Новый Структура(ИменаВозвращаемыхРеквизитов);
ЗапросПоискаДублей = ирОбщий.ЗапросИзСтруктурыЛкс(Параметры.СтруктураЗапроса);
Если Параметры.ПоискПоПохожимСловам Тогда
НайтиПоПохожимСловам(ЗапросПоискаДублей, Параметры.ТекстИндексов, Параметры.ТекстУпорядочить);
Иначе
НайтиПоРавенствуРеквизитов(ЗапросПоискаДублей, Параметры.ТекстИндексов, Параметры.СтрокаПорядкаЦенности);
КонецЕсли;
ЗаполнитьЗначенияСвойств(Результат, ЭтотОбъект, ИменаВозвращаемыхРеквизитов);
Возврат Результат;
КонецФункции
Процедура НайтиПоПохожимСловам(ЗапросПоиска, ТекстИндексов, ТекстУпорядочить) Экспорт
РезультатПакета = ЗапросПоиска.ВыполнитьПакет();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИндексыИменРезультатов = мПлатформа.СтруктураРезультатаПакетногоЗапроса(ЗапросПоиска.Текст);
ПервичныеГруппы = РезультатПакета[ИндексыИменРезультатов.ФинальныеГруппы].Выгрузить();
ОбщаяТаблицаОбъекта = РезультатПакета[ИндексыИменРезультатов.ЭлементыФинальныхГрупп].Выгрузить();
#Если Сервер И Не Сервер Тогда
ПервичныеГруппы = Новый ТаблицаЗначений;
ОбщаяТаблицаОбъекта = Новый ТаблицаЗначений;
#КонецЕсли
мРезультатыПоиска = ОбщаяТаблицаОбъекта.СкопироватьКолонки();
ИмяПоляНечеткогоСравнения = ирОбщий.ИдентификаторИзПредставленияЛкс(мПутьКДаннымПоляНечеткогоСравнения);
ТаблицаСлов = мРезультатыПоиска.Скопировать();
ТаблицаСлов.Колонки.Добавить("СписокСлов");
МассивСтроковыхПолейСравнения = Новый Массив;
Для Каждого ЭлементСравнения Из мСтруктураКлючаПоиска Цикл
Если ПервичныеГруппы.Колонки[ЭлементСравнения.Ключ].ТипЗначения.СодержитТип(Тип("Строка")) Тогда
МассивСтроковыхПолейСравнения.Добавить(ЭлементСравнения.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаГруппы Из ПервичныеГруппы Цикл
ВосстановитьЗначенияСтрокВСтрокеРезультатаЗапроса(МассивСтроковыхПолейСравнения, СтрокаГруппы);
КонецЦикла;
ОбщаяТаблицаОбъекта.Индексы.Добавить(Сред(ТекстИндексов, 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;
мТаблицаБукв = Новый ТаблицаЗначений;
мТаблицаБукв.Колонки.Добавить("Позиция");
мТаблицаБукв.Колонки.Добавить("КолвоПропущенных");
мТаблицаБукв.Колонки.Добавить("ДлинаСлова");
мТаблицаБукв.Колонки.Добавить("ПропущеноНа");
мСуффиксСлужбеныхПолей = ирОбщий.СуффиксСлужебногоСвойстваЛкс(); // Для устранения пересечений с именами полей данных
мИмяПоляКоличествоСсылок = "КоличествоСсылок" + мСуффиксСлужбеныхПолей;
мИмяПоляЦенность = "ЦенностьДанных" + мСуффиксСлужбеныхПолей;
мИмяПоляКоличествоЭлементов = "КоличествоЭлементовВГруппе" + мСуффиксСлужбеныхПолей;
мИмяПоляИдентификатор = "Идентификатор" + мСуффиксСлужбеныхПолей;
мИмяПоляНомерГруппы = "НомерГруппы" + мСуффиксСлужбеныхПолей;
мИмяПоляКоличествоСсылок = "КоличествоСсылок" + мСуффиксСлужбеныхПолей;
мИмяПоляНеправильныеСсылки = "НеправильныеСсылки" + мСуффиксСлужбеныхПолей;
мИмяПоляНеправильныйЭлемент = "НеправильныйЭлемент" + мСуффиксСлужбеныхПолей;
мИмяПоляПравильныйЭлемент = "ПравильныйЭлемент" + мСуффиксСлужбеныхПолей;
мИмяПоляПравильныеДанные = "ПравильныеДанные" + мСуффиксСлужбеныхПолей;
мИмяФлагаПравильныйЭлемент = "ЭтоПравильныйЭлемент" + мСуффиксСлужбеныхПолей;
мИмяФлагаПравильныеДанные = "ЭтоПравильныеДанные" + мСуффиксСлужбеныхПолей;