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