RDT1C/DataProcessors/ирПоискДублейИЗаменаСсылок/Ext/ObjectModule.bsl
Администратор e2082add8d Консоль запросов
*Исправлена ошибка команды "Структура формы"
    Административная регистрация com-компонент
        +Добавлена кнопка "Запустить от имени администратора"
        *Исправлено выполнение административной регистрации под пользователем домена, являющимся локальным администратором
    Общее
        *Устранены проблемы с антивирусным ПО путем возврата к использованию старой версии утилиты hstart
    Подбор и обработка объектов
        +В схему компоновки добавлены поля-функции ТИПЗНАЧЕНИЯ() от полей составных типов

3.78
    Консоль запросов
        *Устранено ошибочное использование параметров в фигурных скобках при наличии параметра с типом "Выражение СКД"
        +В подменю "Вставка" для поля текста запроса добавлена команда "Ссылка из буфера"
        *Исправлено вычисление значений параметров для вложенных компоновок из макета компоновки
        *Исправлено некорректное извлечение вычисляемых параметров из макета компоновки
    Конструктор запроса
        +Добавлена поддержка типа запроса TRUNCATE TABLE
        +Для запроса типа WQL при двойном клике на доступном поле доступной таблицы поле теперь добавляется в выбранные поля
    Анализ журнала регистрации
        +Реализованы команды сортировки для списков значений отбора
        *Исправлено долгое обновление табличного поля отбора с большими списками
    Динамический список
        *В командую панель возвращены все стандартные кнопки
        *При открытии с установкой таблицы фокус ввода теперь устанавливается в табличное поле
    Редактор объекта БД
        *Инструмент "Поиск ссылок на объект" перенесен сюда в виде закладки
        +Добавлена поддержка перечислений и точек маршрута
    Интерфейсная панель
        *Исправлены ошибки при обработке веток не метаданных
    Общее
        +Обновлено внутренне описание платформы от версии 8.3.9
        *Исправлены ошибки при открытии ссылок в режиме совместимости 8.1
        *Обеспечена компипяция в режиме совместимости 8.3.9
        *Кнопка открытия настроек справочника Алгоритмы перенесена с общей панели инструментов в формы списка справочника
    Различные значения колонки
        *Исправлены ошибки при обработке булевых колонок
    Консоль кода
        +В подменю "Вставка" добавлена команда "Ссылка из буфера"
    Поиск дублей и замена ссылок
        *Исправлен учет равенства реквизитов при поиске по похожим словам
    Структура хранения БД
        *Исправлена ошибка при нажатии "Показать индекс" в контекстном меню таблицы "Наборы полей" на закладке "Индексы"
    Поиск ссылок на объект
        *Перенесен в инструмент "Редактор объекта БД" в виде закладки

3.77
    Общее
        *Элевация оставлена только в форме административной регистрации COM-компонент, в настройке техножурнала и при изменении параметров служб сервера 1С
        *Элевация теперь используется только если у учетной записи Windows есть административные права
        *Улучшены сообщения пользователю при проблемах регистрации COM компонент
        *Открытие формы объекта по двойному клику на ячейках табличных полей теперь выполняется без получения объекта
        *Улучшена установка ширины динамически добавляемых колонок табличных полей
    Административная регистрация COM компонент
        +Добавлены кнопки "Снять флажки" и "Установить флажки"
    Редактор объекта БД
        *Исправлено распознавание ссылки документа по представлению в поле выбора объекта
        *Исправлено переключение режима редактирования независимого регистра при изменении отбора командами "снять все" и "установить все"
    Динамический список
        *При открытии редактора объекта БД для добавления в независимый регистр сведений теперь включаются все элементы отбора
    Консоль запросов
        *Устранена ошибочная доступность для изменения флажков в коллекции результата запроса
        *Исправлена ошибка загрузки результата WQL запроса

3.76
    Управление службами сервера 1С
        *Улучшена диагностика ошибок
        +Добавлена элевация при изменении параметров служб
    Динамический список
        *Устранено свежее скрытие колонки со стандартной картинкой
    Интерфейсная панель
        +Добавлены перечисления
    Консоль запросов
        *Исправлена ошибка загрузки пустого результата запроса MSSQL
    Редактор констант
        +Включение функциональных опций теперь изменяет только булевы константы и не выполняет их запись
        *Реализован пропуск ошибок записи констант
    Конструктор запросов
        *Устранена ошибочная виртуальная таблица 1С ЗадачиПоИсполнителю  у задачи без адресации
    Редактор объекта БД
        *Флажок "Очищать по отбору чтения" теперь становится доступным только если в считанном наборе записей были строки
        +В режиме менеджера записи регистра сведений реализовано удаление
        *Исправлена свежая ошибка параметризованного открытия строки независимого регистра сведений
    Общее
        *Исправлена ошибка нажатия "Запустить обычное приложение" в тонком клиенте из формы "Невозможно выполнить действие"
2016-12-04 00:30:12 +03:00

1218 lines
87 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.

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
Перем мПлатформа Экспорт;
Перем мСервисныйПроцессор Экспорт; // Для программного вызова из Интеграции
Перем ТаблицаБукв;
Перем мИскомыйОбъектПоискаДублей Экспорт;
Перем мСтруктураПоиска Экспорт;
Функция ЭтоБуква (Символ)
Код = КодСимвола(Символ);
Если (Код<=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);
Если ЭтоБуква(Символ) Тогда
Слово = Слово + Символ;
Иначе
Если Слово<>"" Тогда
СписокСлов.Добавить(ВРЕГ(Слово));
Слово = "";
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Слово<>"" Тогда
СписокСлов.Добавить(ВРЕГ(Слово));
КонецЕсли;
СписокСлов.СортироватьПоЗначению();
Возврат СписокСлов;
КонецФункции // ()
Функция _НайтиДубли(ИскомыйОбъект, СтруктураПоиска) Экспорт
мИскомыйОбъектПоискаДублей = ИскомыйОбъект;
мСтруктураПоиска = СтруктураПоиска;
НайденныеОбъекты = Новый ТаблицаЗначений;
НайденныеОбъекты.Колонки.Добавить("Ссылка");
ИмяСправочника = ИскомыйОбъект.Метаданные().Имя;
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ Разрешенные
| Ссылка*
|Из Справочник." + ИмяСправочника + " КАК Спр
|Где Не Спр.ЭтоГруппа";
Реквизиты = "";
СтрокаГде = "";
ВЗапросеТолькоРавенство = Истина;
МетаданныеОбъекта = ИскомыйОбъект.Метаданные();
МетаданныеРеквизитов = МетаданныеОбъекта.Реквизиты;
СтруктураИсходныхРеквизитов = Новый Структура;
Для каждого КлючИЗначение Из СтруктураПоиска Цикл
ИмяРеквизита = КлючИЗначение.Ключ;
СтепеньСхожести = КлючИЗначение.Значение;
ЗначениеРеквизита = ИскомыйОбъект[ИмяРеквизита];
МетаданныеРеквизита = МетаданныеРеквизитов.Найти(ИмяРеквизита);
ПредставлениеРеквизита = ?(МетаданныеРеквизита = Неопределено, ИмяРеквизита, Строка(МетаданныеРеквизита));
СтруктураИсходногоРеквизита = Новый Структура("ЗначениеРеквизита,СтепеньСхожести,СписокСлов"
,ЗначениеРеквизита,СтепеньСхожести,ПолучитьСписокСлов(ЗначениеРеквизита));
СтруктураИсходныхРеквизитов.Вставить(ИмяРеквизита,СтруктураИсходногоРеквизита);
Если Не МетаданныеРеквизита = Неопределено Тогда
ТипРеквизита = МетаданныеРеквизита.Тип;
ИначеЕсли ИмяРеквизита = "Код" Тогда
Если МетаданныеОбъекта.ТипКода = Метаданные.СвойстваОбъектов.ТипКодаСправочника.Строка Тогда
ТипРеквизита = Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(МетаданныеОбъекта.ДлинаКода));
Иначе
ТипРеквизита = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(МетаданныеОбъекта.ДлинаКода));
КонецЕсли;
ИначеЕсли ИмяРеквизита = "Наименование" Тогда
ТипРеквизита = Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(МетаданныеОбъекта.ДлинаНаименования));
Иначе
ТипРеквизита = Неопределено;
КонецЕсли;
НайденныеОбъекты.Колонки.Добавить(ИмяРеквизита, ТипРеквизита, ПредставлениеРеквизита);
НайденныеОбъекты.Колонки.Добавить(ИмяРеквизита+"_Флаг");
Реквизиты = Реквизиты+",
| "+ ИмяРеквизита;
Если ЗначениеЗаполнено(ЗначениеРеквизита) Тогда
Если СтепеньСхожести = "=" Тогда
ЗнакСравнения = ?(Не МетаданныеРеквизита = Неопределено И МетаданныеРеквизита.Тип.СодержитТип(Тип("Строка")) и МетаданныеРеквизита.Тип.КвалификаторыСтроки.Длина = 0,"Подобно","=");
СтрокаГде = ?(СтрокаГде = "", "",СтрокаГде +" или ")+"Спр."+ИмяРеквизита +" " +ЗнакСравнения+ " &"+ИмяРеквизита;
Запрос.УстановитьПараметр(""+ИмяРеквизита,ЗначениеРеквизита);
ИначеЕсли Не СтепеньСхожести = Неопределено Тогда
ВЗапросеТолькоРавенство = Ложь;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Запрос.Текст = СтрЗаменить(Запрос.Текст, "*", Реквизиты);
Если ВЗапросеТолькоРавенство Тогда
Запрос.Текст = Запрос.Текст + Символы.ПС + " И("+СтрокаГде+")";
КонецЕсли;
ТаблицаСправочника = Запрос.Выполнить().Выгрузить();
Для каждого Строка Из ТаблицаСправочника Цикл
СтруктураНайденных = Новый Структура;
Для каждого КлючИЗначение Из СтруктураИсходныхРеквизитов Цикл
СтепеньСхожести = КлючИЗначение.Значение.СтепеньСхожести;
Если СтепеньСхожести = "=" Тогда
ИмяРеквизита = КлючИЗначение.Ключ;
ЗначениеРеквизита = КлючИЗначение.Значение.ЗначениеРеквизита;
//Поиск по равному значению
Если ЗначениеРеквизита = Строка[ИмяРеквизита] Тогда
СтруктураНайденных.Вставить(ИмяРеквизита);
КонецЕсли;
ИначеЕсли Не СтепеньСхожести = Неопределено Тогда
ИмяРеквизита = КлючИЗначение.Ключ;
//Поиск по похожим словам
СписокИскомыхСлов = КлючИЗначение.Значение.СписокСлов.Скопировать();
СписокНайденыхСлов = ПолучитьСписокСлов(Строка[ИмяРеквизита]);
Если Не ПроверитьСловаНаОтличие(СписокИскомыхСлов,СписокНайденыхСлов,СтепеньСхожести) Тогда
СтруктураНайденных.Вставить(ИмяРеквизита);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не СтруктураНайденных.Количество()=0 Тогда
НоваяСтрока = НайденныеОбъекты.Добавить();
НоваяСтрока.Ссылка = Строка.Ссылка;
Для каждого КлючИЗначение Из СтруктураПоиска Цикл
ИмяРеквизита = КлючИЗначение.Ключ;
НоваяСтрока[ИмяРеквизита] = Строка[ИмяРеквизита];
НоваяСтрока[ИмяРеквизита+"_Флаг"] = СтруктураНайденных.Свойство(ИмяРеквизита);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Возврат НайденныеОбъекты;
КонецФункции // ()
// Заменяемые - Соответствие, Массив строк таблицы
// ТаблицаСсылающихсяОбъектов - ТаблицаЗначений, *Неопределено - таблица ссылающихся объектов возвращаемая методом НайтиПоСсылкам или ее часть
// ЗамещениеВсегда - Число - замещение к ключах независимых регистров сведений, 1 - замещать, 0 - спрашивать (на клиенте) или пропускать
//
Функция ВыполнитьЗаменуЭлементов(Заменяемые, ТаблицаСсылающихсяОбъектов = Неопределено, Знач ЗаголовокИндикации = "", ЗамещениеВсегда = 0) Экспорт
//Если ТранзакцияАктивна() Тогда
// ВызватьИсключение "Замена ссылок не допускается в общей транзакции";
//КонецЕсли;
БылиИсключения = Ложь;
Параметры = Новый Структура;
Параметры.Вставить("Объект", Неопределено);
СтруктураКоллизий = Новый Структура;
ИзмененныеПроведенныеДокументы.Очистить();
Если ТаблицаСсылающихсяОбъектов = Неопределено Тогда
СписокСсылок = Новый Массив;
Для Каждого КлючИЗначение Из Заменяемые Цикл
СписокСсылок.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
ТаблицаСсылающихсяОбъектов = НайтиПоСсылкам(СписокСсылок);
КонецЕсли;
РодителиПравильных = Новый Соответствие;
Для Каждого КлючИЗначение Из Заменяемые Цикл
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючИЗначение.Ключ));
Если ОбъектМД = Неопределено Тогда
ВызватьИсключение "Не найден объект метаданных по типу";
КонецЕсли;
Если ирОбщий.ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМД) Тогда
МассивРодителей = Новый Массив;
Родитель = КлючИЗначение.Значение;
Если ТипЗнч(Родитель) = Тип("Структура") Тогда
Родитель = Родитель.Значение;
КонецЕсли;
Пока ЗначениеЗаполнено(Родитель) Цикл
МассивРодителей.Добавить(Родитель);
Родитель = Родитель.Родитель;
КонецЦикла;
РодителиПравильных[КлючИЗначение.Значение] = МассивРодителей;
КонецЕсли;
КонецЦикла;
Если ТаблицаСсылающихсяОбъектов.Количество() > 0 Тогда
Если Не ЗначениеЗаполнено(ЗаголовокИндикации) Тогда
ЗаголовокИндикации = "Замена ссылок";
КонецЕсли;
СтрокаГруппировок = "Метаданные,Данные";
Если ТипЗнч(ТаблицаСсылающихсяОбъектов) = Тип("ТаблицаЗначений") Тогда
СсылающиесяОбъекты = ТаблицаСсылающихсяОбъектов.Скопировать(, СтрокаГруппировок);
Иначе
СсылающиесяОбъекты = ТаблицаСсылающихсяОбъектов.Выгрузить(, СтрокаГруппировок);
КонецЕсли;
СсылающиесяОбъекты.Индексы.Добавить(СтрокаГруппировок);
СсылающиесяОбъекты.Свернуть(СтрокаГруппировок);
СсылающиесяОбъекты.Сортировать(СтрокаГруппировок);
КлючПоиска = Новый Структура("Данные");
Если мСервисныйПроцессор <> Неопределено Тогда
Индикатор = мСервисныйПроцессор.ПолучитьИндикаторПроцесса(СсылающиесяОбъекты.Количество(), ЗаголовокИндикации);
Иначе
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СсылающиесяОбъекты.Количество(), ЗаголовокИндикации);
КонецЕсли;
ТранзакцииРазрешены = Истина;
Если Истина
И ЗаписьНаСервере
И ирКэш.ЛиПортативныйРежимЛкс()
И Не ирПортативный.ЛиСерверныйМодульДоступенЛкс(Ложь)
И ирПортативный.ЭмуляцияЗаписиНаСервере
Тогда
Сообщить("В режиме эмуляции записи на сервере транзакции не поддерживаются");
ТранзакцииРазрешены = Ложь;
ОбщаяТранзакция = Ложь;
КонецЕсли;
Если ОбщаяТранзакция Тогда
НачатьТранзакцию();
КонецЕсли;
Попытка
Для Каждого ОписаниеОбъекта Из СсылающиесяОбъекты Цикл
Если мСервисныйПроцессор <> Неопределено Тогда
мСервисныйПроцессор.ОбновитьИндикатор(Индикатор);
Иначе
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
ОбъектИзменен = Ложь;
Если ТипЗнч(ОписаниеОбъекта.Данные) = Тип("Строка") Тогда
ОбъектСодержащийСсылку = ЗначениеИзСтрокиВнутр(ОписаниеОбъекта.Данные);
Иначе
ОбъектСодержащийСсылку = ОписаниеОбъекта.Данные;
КонецЕсли;
Если ТипЗнч(ОписаниеОбъекта.Метаданные) = Тип("Строка") Тогда
//ОбъектМД = Метаданные.НайтиПоПолномуИмени(ОписаниеОбъекта.Метаданные);
ОбъектМД = мПлатформа.ПолучитьОбъектМДПоПолномуИмени(ОписаниеОбъекта.Метаданные);
Иначе
ОбъектМД = ОписаниеОбъекта.Метаданные;
КонецЕсли;
Если КомментироватьЗаменуСсылок Тогда
Сообщить("Обрабатывается " + ОбъектСодержащийСсылку);
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмяМД);
ЗаполнитьЗначенияСвойств(КлючПоиска, ОписаниеОбъекта);
СсылкиВОбъектеНаНеправильныеЭлементы = ТаблицаСсылающихсяОбъектов.НайтиСтроки(КлючПоиска);
НеправильныеСсылкиВОбъекте = Новый Массив;
Для Каждого СтрокаНеправильнойСсылки Из СсылкиВОбъектеНаНеправильныеЭлементы Цикл
НеправильныеСсылкиВОбъекте.Добавить(СтрокаНеправильнойСсылки.Ссылка);
КонецЦикла;
Если ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда
Если ТранзакцииРазрешены Тогда
НачатьТранзакцию();
КонецЕсли;
Попытка
ирОбщий.ЗаблокироватьСсылкуВТранзакцииЛкс(ОбъектСодержащийСсылку, Истина);
ОбъектБД = ОбъектСодержащийСсылку.ПолучитьОбъект();
Если ОбъектБД <> Неопределено Тогда
Для Каждого НеправильнаяСсылка Из НеправильныеСсылкиВОбъекте Цикл
ОбъектИзменен = ЗаменитьЗначениеВОбъектеБДЛкс(ОбъектБД, НеправильнаяСсылка, Заменяемые[НеправильнаяСсылка], РодителиПравильных[Заменяемые[НеправильнаяСсылка]]) Или ОбъектИзменен;
КонецЦикла;
КонецЕсли;
ЗаписатьОбъектЕслиИзменен(ОбъектБД, БылиИсключения, ОбъектИзменен, ОбъектМД);
Если ТранзакцииРазрешены Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Исключение
Если ТранзакцииРазрешены Тогда
ОтменитьТранзакцию();
КонецЕсли;
БылиИсключения = Истина;
Если ОбщаяТранзакция Тогда
ВызватьИсключение;
КонецЕсли;
Сообщить("Ошибка обработки ссылающегося объекта " + ирОбщий.ПолучитьXMLКлючОбъектаБДЛкс(ОбъектСодержащийСсылку) + ": " + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Если Не БылиИсключения Тогда
Если Метаданные.Документы.Содержит(ОбъектМД) Тогда
Для Каждого Движение ИЗ ОбъектМД.Движения Цикл
НаборЗаписей = Новый (СтрЗаменить(Движение.ПолноеИмя(), ".", "НаборЗаписей."));
НаборЗаписей.Отбор.Регистратор.Установить(ОбъектСодержащийСсылку);
БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(НаборЗаписей, Заменяемые, НеправильныеСсылкиВОбъекте, ТранзакцииРазрешены);
КонецЦикла;
Для Каждого Последовательность ИЗ Метаданные.Последовательности Цикл
Если Последовательность.Документы.Содержит(ОбъектМД) Тогда
НаборЗаписей = Новый (СтрЗаменить(Последовательность.ПолноеИмя(), ".", "НаборЗаписей."));
НаборЗаписей.Отбор.Регистратор.Установить(ОбъектСодержащийСсылку);
БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(НаборЗаписей, Заменяемые, НеправильныеСсылкиВОбъекте, ТранзакцииРазрешены);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда
Если ТранзакцииРазрешены Тогда
НачатьТранзакцию();
КонецЕсли;
Попытка
ОбъектБД = Константы[ОбъектМД.Имя].СоздатьМенеджерЗначения();
ирОбщий.ЗаблокироватьКонстантуЛкс(ОбъектБД, Истина);
ОбъектБД.Прочитать();
НовоеЗначение = Заменяемые[ОбъектБД.Значение];
Если НовоеЗначение <> Неопределено Тогда
ОбъектБД.Значение = НовоеЗначение;
ОбъектИзменен = Истина;
КонецЕсли;
Если ТранзакцииРазрешены Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Исключение
Если ТранзакцииРазрешены Тогда
ОтменитьТранзакцию();
КонецЕсли;
БылиИсключения = Истина;
Если ОбщаяТранзакция Тогда
ВызватьИсключение;
КонецЕсли;
Сообщить("Ошибка обработки ссылающегося объекта " + ирОбщий.ПолучитьXMLКлючОбъектаБДЛкс(ОбъектБД) + ": " + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
ИначеЕсли ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) Тогда
МассивИзмененныхИзмерений = Новый Массив;
МенеджерЗаписи = РегистрыСведений[ОбъектМД.Имя].СоздатьМенеджерЗаписи();
КоллизийныйМенеджерЗаписи = РегистрыСведений[ОбъектМД.Имя].СоздатьМенеджерЗаписи();
Если ТранзакцииРазрешены Тогда
НачатьТранзакцию();
КонецЕсли;
Попытка
БылаКоллизия = Ложь;
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, ОбъектСодержащийСсылку);
ЗаполнитьЗначенияСвойств(КоллизийныйМенеджерЗаписи, ОбъектСодержащийСсылку);
ИмяТаблицыРегистра = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ОбъектМД);
НаборЗаписей = ирОбщий.ПолучитьНаборЗаписейПоКлючуЛкс(ИмяТаблицыРегистра, ОбъектСодержащийСсылку);
ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина);
КоллизийныйМенеджерЗаписи.Прочитать();
Если КоллизийныйМенеджерЗаписи.Выбран() Тогда
ПоляТаблицыБД = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ПолноеИмяМД);
ОбъектИзменен = ВыполнитьЗаменуВСтрокеНабораЗаписей(КоллизийныйМенеджерЗаписи, Заменяемые, ПоляТаблицыБД);
Если Не БылиИсключения И ОбъектИзменен Тогда
Для каждого МетаИзмерение Из ОбъектМД.Измерения Цикл
Если КоллизийныйМенеджерЗаписи[МетаИзмерение.Имя] <> ОбъектСодержащийСсылку[МетаИзмерение.Имя] Тогда
МассивИзмененныхИзмерений.Добавить(МетаИзмерение.Имя);
КонецЕсли;
КонецЦикла;
Если МассивИзмененныхИзмерений.Количество() > 0 Тогда
НаборЗаписей = ирОбщий.ПолучитьНаборЗаписейПоКлючуЛкс(ИмяТаблицыРегистра, КоллизийныйМенеджерЗаписи);
ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина);
КоллизийныйМенеджерЗаписи.Прочитать();
Если КоллизийныйМенеджерЗаписи.Выбран() Тогда
МенеджерЗаписи.Прочитать();
МассивКоллекцийРеквизитов = Новый Массив;
МассивКоллекцийРеквизитов.Добавить(ОбъектМД.Ресурсы);
МассивКоллекцийРеквизитов.Добавить(ОбъектМД.Реквизиты);
Если Не СтруктураКоллизий.Свойство(ОбъектМД.Имя) Тогда
ТаблицаЗаписей = РегистрыСведений[ОбъектМД.Имя].СоздатьНаборЗаписей().Выгрузить();
ТаблицаЗаписей.Колонки.Добавить("МенеджерЗамены");
ТаблицаЗаписей.Колонки.Добавить("МенеджерОригинала");
Для Каждого КоллекцияРеквизитов Из МассивКоллекцийРеквизитов Цикл
Для Каждого МетаРеквизит Из КоллекцияРеквизитов Цикл
ИмяКолонки = МетаРеквизит.Имя;
ПредставлениеКолонки = МетаРеквизит.Представление();
КолонкаОригинала = ТаблицаЗаписей.Колонки[ИмяКолонки];
КолонкаОригинала.Имя = "Оригинал" + ИмяКолонки;
КолонкаОригинала.Заголовок = "Оригинал: " + ПредставлениеКолонки;
КолонкаЗамены = ТаблицаЗаписей.Колонки.Вставить(ТаблицаЗаписей.Колонки.Индекс(КолонкаОригинала),
"Замена" + ИмяКолонки, , "Замена: " + ПредставлениеКолонки);
ЗаполнитьЗначенияСвойств(КолонкаЗамены, КолонкаОригинала, , "Имя, Заголовок");
КонецЦикла;
КонецЦикла;
ТаблицаЗаписей.Колонки.Вставить(0, "Заменить", Новый ОписаниеТипов("Булево"), "Заменить");
СтруктураКоллизий.Вставить(ОбъектМД.Имя, ТаблицаЗаписей);
КонецЕсли;
НоваяКоллизийнаяЗапись = СтруктураКоллизий[ОбъектМД.Имя].Добавить();
Для Каждого КоллекцияРеквизитов Из МассивКоллекцийРеквизитов Цикл
Для Каждого МетаРеквизит Из КоллекцияРеквизитов Цикл
ИмяКолонки = МетаРеквизит.Имя;
ЗначениеРеквизита = МенеджерЗаписи[ИмяКолонки];
НоваяКоллизийнаяЗапись["Оригинал" + ИмяКолонки] = КоллизийныйМенеджерЗаписи[ИмяКолонки];
ЗаменаЗначения = Заменяемые[ЗначениеРеквизита];
Если ЗаменаЗначения <> Неопределено Тогда
НоваяКоллизийнаяЗапись["Замена" + ИмяКолонки] = ЗаменаЗначения;
Иначе
НоваяКоллизийнаяЗапись["Замена" + ИмяКолонки] = ЗначениеРеквизита;
КонецЕсли;
КоллизийныйМенеджерЗаписи[ИмяКолонки] = НоваяКоллизийнаяЗапись["Замена" + ИмяКолонки];
Если НоваяКоллизийнаяЗапись["Оригинал" + ИмяКолонки] <> НоваяКоллизийнаяЗапись["Замена" + ИмяКолонки] Тогда
БылаКоллизия = Истина;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если БылаКоллизия И ЗамещениеВсегда <> 1 Тогда
ЗаполнитьЗначенияСвойств(НоваяКоллизийнаяЗапись, КоллизийныйМенеджерЗаписи);
Для Каждого ИмяКолонки Из МассивИзмененныхИзмерений Цикл
НоваяКоллизийнаяЗапись[ИмяКолонки] = МенеджерЗаписи[ИмяКолонки];
КонецЦикла;
НоваяКоллизийнаяЗапись.МенеджерЗамены = КоллизийныйМенеджерЗаписи;
НоваяКоллизийнаяЗапись.МенеджерОригинала = МенеджерЗаписи;
Иначе
СтруктураКоллизий[ОбъектМД.Имя].Удалить(НоваяКоллизийнаяЗапись);
МенеджерЗаписи.Удалить();
БылаКоллизия = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если БылаКоллизия Тогда
БылиИсключения = Ложь;
Иначе
БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(МенеджерЗаписи, Заменяемые, НеправильныеСсылкиВОбъекте);
КонецЕсли;
Если ТранзакцииРазрешены Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Исключение
Если ТранзакцииРазрешены Тогда
ОтменитьТранзакцию();
КонецЕсли;
БылиИсключения = Истина;
Если ОбщаяТранзакция Тогда
ВызватьИсключение;
КонецЕсли;
Сообщить("Ошибка обработки ссылающегося объекта " + ирОбщий.ПолучитьXMLКлючОбъектаБДЛкс(НаборЗаписей) + ": " + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Иначе
БылиИсключения = Истина;
Сообщить("Замена ссылок в объектах типа " + ОбъектМД.ПолноеИмя() + " не поддерживается");
КонецЕсли;
КонецЦикла;
Если ОбщаяТранзакция Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Исключение
Если ОбщаяТранзакция Тогда
ОтменитьТранзакцию();
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Если мСервисныйПроцессор <> Неопределено Тогда
мСервисныйПроцессор.ОсвободитьИндикаторПроцесса(Индикатор, Истина);
Иначе
ирОбщий.ОсвободитьИндикаторПроцессаЛкс(Индикатор, Истина);
КонецЕсли;
КонецЕсли;
МассивЭлементовКУдалению = Новый Массив;
Для Каждого ЭлементТаблицыРегистра Из СтруктураКоллизий Цикл
Если ЭлементТаблицыРегистра.Значение.Количество() = 0 Тогда
МассивЭлементовКУдалению.Добавить(ЭлементТаблицыРегистра.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого ЭлементКУдалению Из МассивЭлементовКУдалению Цикл
СтруктураКоллизий.Удалить(ЭлементКУдалению);
КонецЦикла;
Если СтруктураКоллизий.Количество() > 0 Тогда
Если ЗамещениеВсегда = 1 Тогда
ЗамещатьВЭтотРаз = Истина;
Иначе
#Если Клиент Тогда
ФормаЗамещенияВНезависимыхРегистрахСведений = ПолучитьФорму("ФормаЗамещенияВНезависимыхРегистрахСведений");
ФормаЗамещенияВНезависимыхРегистрахСведений.КодВсегда = ЗамещениеВсегда;
ФормаЗамещенияВНезависимыхРегистрахСведений.СтруктураКоллизий = СтруктураКоллизий;
ФормаЗамещенияВНезависимыхРегистрахСведений.ОткрытьМодально();
ЗамещениеВсегда = ФормаЗамещенияВНезависимыхРегистрахСведений.КодВсегда;
ЗамещатьВЭтотРаз = ФормаЗамещенияВНезависимыхРегистрахСведений.РезультатФормы;
#Иначе
ЗамещатьВЭтотРаз = Ложь;
#КонецЕсли
КонецЕсли;
Если ЗамещатьВЭтотРаз Тогда
Для Каждого ЭлементРегистра Из СтруктураКоллизий Цикл
Для Каждого СтрокаЗаписи Из ЭлементРегистра.Значение Цикл
Если СтрокаЗаписи.Заменить Тогда
СтрокаЗаписи.МенеджерЗамены.Записать();
КонецЕсли;
СтрокаЗаписи.МенеджерОригинала.Удалить();
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Не БылиИсключения;
КонецФункции
Процедура ЗаписатьОбъектЕслиИзменен(ОбъектБД, БылиИсключения, ОбъектИзменен, ОбъектМД)
Если ОбъектБД <> Неопределено Тогда
//Если Объект.Модифицированность() Тогда
Если ОбъектИзменен Тогда
Попытка
ирОбщий.ЗаписатьОбъектЛкс(ОбъектБД, ЗаписьНаСервере,,, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
//Если ОтключатьКонтрольЗаписи Тогда
// ЗаписьЖурналаРегистрации("Запись с флагом Загрузка", УровеньЖурналаРегистрации.Информация, ОбъектМД,
// ОбъектСодержащийСсылку, "");
//КонецЕсли;
Исключение
Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
БылиИсключения = Истина;
ОбъектИзменен = Ложь;
КонецПопытки;
Если Истина
И ОбъектИзменен
И Метаданные.Документы.Содержит(ОбъектМД)
И ОбъектМД.Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить
И ОбъектБД.Проведен
Тогда
СтрокаДляДокумента = ИзмененныеПроведенныеДокументы.Добавить();
СтрокаДляДокумента.ДатаДокумента = ОбъектБД.Дата;
СтрокаДляДокумента.ТипДокумента = ОбъектМД.Имя;
СтрокаДляДокумента.Документ = ОбъектБД.Ссылка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ВыполнитьЗаменуЭлементов()
// Ищет все экземпляры значения ЧтоЗаменять в объекте и заменяет их на НаЧтоЗаменять
Функция ЗаменитьЗначениеВОбъектеБДЛкс(Объект, ЧтоЗаменять, НаЧтоЗаменять, РодителиПравильного = Неопределено)
ОбъектМД = Объект.Метаданные();
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПоляТаблицыБД = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ПолноеИмяМД);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
ОбъектИзменен = Ложь;
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Попытка
ТабличнаяЧасть = Объект[ПолеТаблицыБД.Имя];
Исключение
// Сюда например попадаем в случае системной папки СистемныеПоля
ТабличнаяЧасть = Неопределено;
КонецПопытки;
Если ТабличнаяЧасть <> Неопределено Тогда
МетаТЧ = ОбъектМД.ТабличныеЧасти[ПолеТаблицыБД.Имя];
ПоляТаблицыТЧ = ирОбщий.ПолучитьПоляТаблицыМДЛкс(МетаТЧ.ПолноеИмя());
Для Каждого КолонкаТЧ Из ТабличнаяЧасть.Выгрузить().Колонки Цикл
ИмяРеквизита = КолонкаТЧ.Имя;
Если КолонкаТЧ.ТипЗначения.СодержитТип(ТипЗнч(ЧтоЗаменять)) Тогда
СтрокиТабЧасти = ТабличнаяЧасть.НайтиСтроки(Новый Структура(ИмяРеквизита, ЧтоЗаменять));
Для Каждого СтрокаТабЧасти Из СтрокиТабЧасти Цикл
ОбъектИзменен = ЗаменитьЗначениеРеквизитаСПроверкойВозможности(СтрокаТабЧасти, ИмяРеквизита, НаЧтоЗаменять, ПоляТаблицыТЧ) Или ОбъектИзменен;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
ИмяРеквизита = "" + ПолеТаблицыБД.Имя;
Если ирОбщий.СтрокиРавныЛкс(ИмяРеквизита, "Ссылка") Тогда
Продолжить;
КонецЕсли;
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(ТипЗнч(ЧтоЗаменять)) И Объект[ИмяРеквизита] = ЧтоЗаменять Тогда
Если Истина
И РодителиПравильного <> Неопределено
И ирОбщий.СтрокиРавныЛкс(ПолеТаблицыБД.Имя, "Родитель")
И РодителиПравильного.Найти(Объект.Ссылка) <> Неопределено
Тогда
// Вместо зацикливания уровней иерархии поднимаем до ближайшего корректного родителя
лНаЧтоЗаменять = ЧтоЗаменять.Родитель;
Пока РодителиПравильного.Найти(лНаЧтоЗаменять) <> Неопределено Цикл
лНаЧтоЗаменять = лНаЧтоЗаменять.Родитель;
КонецЦикла;
Сообщить("Родитель объекта """ + Объект + """ был заменен на """ + лНаЧтоЗаменять + """ для избежания зацикливания уровней");
Иначе
лНаЧтоЗаменять = НаЧтоЗаменять;
КонецЕсли;
ОбъектИзменен = ЗаменитьЗначениеРеквизитаСПроверкойВозможности(Объект, ИмяРеквизита, лНаЧтоЗаменять, ПоляТаблицыБД) Или ОбъектИзменен;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ОбъектИзменен;
КонецФункции
// Результат - Булево - была ли выполнена замена
Функция ЗаменитьЗначениеРеквизитаСПроверкойВозможности(СтрокаТаблицы, ИмяРеквизита, НаЧтоЗаменять, ПоляТаблицыБД)
ОбъектНеИзменен = Истина;
ПолнаяЗаменаВозможна = ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицы, ИмяРеквизита, НаЧтоЗаменять, ПоляТаблицыБД, , Истина);
Если ПолнаяЗаменаВозможна Тогда
ОбъектНеИзменен = ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицы, ИмяРеквизита, НаЧтоЗаменять, ПоляТаблицыБД, , Ложь);
КонецЕсли;
Возврат Не ОбъектНеИзменен;
КонецФункции
// Результат - Булево
// Если ТолькоПроверитьВозможность = Истина, то содержит успешность полной замены
// Если ТолькоПроверитьВозможность = Ложь, то содержит факт отсутствия изменения объекта
Функция ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицыБД, ИмяРеквизита, Знач НаЧтоЗаменять, ПоляТаблицыБД, ПравилаЗаменыЗависимых = Неопределено,
ТолькоПроверитьВозможность = Истина, ИмяРеквизитаОтбора = "Ссылка", ИсключитьЗависимое = "", ИсключитьВлияющее = "")
Результат = Истина;
Если ТипЗнч(НаЧтоЗаменять) = Тип("Структура") Тогда
ПравилаЗаменыЗависимых = НаЧтоЗаменять.ПравилаЗависимых;
НаЧтоЗаменять = НаЧтоЗаменять.Значение;
КонецЕсли;
ЧтоЗаменять = СтрокаТаблицыБД[ИмяРеквизита];
Если ТипЗнч(ЧтоЗаменять) = Тип("ЭлементОтбора") Тогда
ЧтоЗаменять = ЧтоЗаменять.Значение;
КонецЕсли;
Если ЧтоЗаменять = НаЧтоЗаменять Тогда
Возврат Результат;
КонецЕсли;
Если ПравилаЗаменыЗависимых <> Неопределено Тогда
ПолеТаблицы = ПоляТаблицыБД.Найти(ИмяРеквизита, "Имя");
ДанныеДляПоискаСвязейПоВладельцу = Неопределено;
Если ОпределятьСвязьПоВладельцуПоДанным Тогда
ДанныеДляПоискаСвязейПоВладельцу = СтрокаТаблицыБД;
КонецЕсли;
Если ПолеТаблицы.Метаданные <> Неопределено Тогда
СвязиПараметровВыбора = Новый Массив(ПолеТаблицы.Метаданные.СвязиПараметровВыбора);
Если ОпределятьСвязьПоВладельцуПоДанным Тогда
Попытка
ЗначениеВладельца = ЧтоЗаменять.Владелец;
Исключение
ЗначениеВладельца = Неопределено;
КонецПопытки;
Если ЗначениеЗаполнено(ЗначениеВладельца) Тогда
Для Каждого ПолеТаблицыБДВладельца Из ПоляТаблицыБД Цикл
Попытка
ЗначениеПоляВладельца = ДанныеДляПоискаСвязейПоВладельцу[ПолеТаблицыБДВладельца.Имя];
Исключение
// Ссылка у строки ТЧ
Продолжить;
КонецПопытки;
Если ТипЗнч(ЗначениеПоляВладельца) = Тип("ЭлементОтбора") Тогда
ЗначениеПоляВладельца = ЗначениеПоляВладельца.Значение;
КонецЕсли;
Если ЗначениеПоляВладельца = ЗначениеВладельца Тогда
СвязиПараметровВыбора.Добавить(Новый Структура("Имя, ПутьКДанным", "Отбор.Владелец", ПолеТаблицыБДВладельца.Имя));
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
УжеОбработанныеРеквизиты = Новый Структура;
Для Каждого СвязьПараметровВыбора Из СвязиПараметровВыбора Цикл
ИмяРеквизитаСодежащегоВлияющее = СвязьПараметровВыбора.ПутьКДанным;
ИмяРеквизитаСодежащегоВлияющее = ирОбщий.ПолучитьПоследнийФрагментЛкс(ИмяРеквизитаСодежащегоВлияющее);
Если ИсключитьВлияющее = ИмяРеквизитаСодежащегоВлияющее Тогда
Продолжить;
КонецЕсли;
ИмяРеквизитаОтбора = СтрЗаменить(СвязьПараметровВыбора.Имя, "Отбор.", "");
Если УжеОбработанныеРеквизиты.Свойство(ИмяРеквизитаОтбора) Тогда
Продолжить;
КонецЕсли;
УжеОбработанныеРеквизиты.Вставить(ИмяРеквизитаОтбора);
ВлияющееЗначениеЧтоЗаменять = ЧтоЗаменять[ИмяРеквизитаОтбора];
ВлияющееЗначениеНаЧтоЗаменять = НаЧтоЗаменять[ИмяРеквизитаОтбора];
Если ВлияющееЗначениеЧтоЗаменять <> ВлияющееЗначениеНаЧтоЗаменять Тогда
Результат = ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицыБД, ИмяРеквизитаСодежащегоВлияющее, ВлияющееЗначениеНаЧтоЗаменять, ПоляТаблицыБД,
ПравилаЗаменыЗависимых, ТолькоПроверитьВозможность, ИмяРеквизитаОтбора, ИмяРеквизита) И Результат;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ЗависимыеРеквизиты = ПолучитьЗависимыеРеквизитыМД(ПоляТаблицыБД, ИмяРеквизита, ДанныеДляПоискаСвязейПоВладельцу);
Для Каждого КлючИЗначение Из ЗависимыеРеквизиты Цикл
Если ИсключитьЗависимое = КлючИЗначение.Ключ Тогда
Продолжить;
КонецЕсли;
ЗависимоеЗначение = СтрокаТаблицыБД[КлючИЗначение.Ключ];
Если ТипЗнч(ЗависимоеЗначение) = Тип("ЭлементОтбора") Тогда
ЗависимоеЗначение = ЗависимоеЗначение.Значение;
КонецЕсли;
Если Не ЗначениеЗаполнено(ЗависимоеЗначение) Тогда
Продолжить;
КонецЕсли;
КлючПоискаПравила = Новый Структура("ПутьКДаннымВлияющего, ТипЗначения, ЧтоЗаменять, ЗависимоеВлияющее, ВлияющееЧтоЗаменять",
ИмяРеквизитаОтбора, Новый (ТипЗнч(ЗависимоеЗначение)), ЗависимоеЗначение, КлючИЗначение.Значение, ЧтоЗаменять);
ПравилаЗаменыЗависимого = ПравилаЗаменыЗависимых.НайтиСтроки(КлючПоискаПравила);
Если ПравилаЗаменыЗависимого.Количество() > 0 Тогда
ПравилоЗаменыЗависимого = ПравилаЗаменыЗависимого[0];
Если ПравилоЗаменыЗависимого.Пометка Тогда
Результат = ЗаменитьЗначениеРеквизитаСВлияющимиИЗависимыми(СтрокаТаблицыБД, КлючИЗначение.Ключ, ПравилоЗаменыЗависимого.НаЧтоЗаменять, ПоляТаблицыБД,
ПравилаЗаменыЗависимых, ТолькоПроверитьВозможность, ПравилоЗаменыЗависимого.ЗависимоеВлияющее,, ИмяРеквизита) И Результат;
Иначе
Результат = Ложь;
КонецЕсли;
Иначе
ПравилоЗаменыЗависимого = ПравилаЗаменыЗависимых.Добавить();
ЗаполнитьЗначенияСвойств(ПравилоЗаменыЗависимого, КлючПоискаПравила);
Результат = Ложь;
КонецЕсли;
ПравилоЗаменыЗависимого.НайденоСтрок = ПравилоЗаменыЗависимого.НайденоСтрок + 1;
ПравилоЗаменыЗависимого.Требуется = Истина;
КонецЦикла;
КонецЕсли;
Если Не ТолькоПроверитьВозможность Тогда
Если ТипЗнч(СтрокаТаблицыБД[ИмяРеквизита]) = Тип("ЭлементОтбора") Тогда
Результат = Не ирОбщий.БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(СтрокаТаблицыБД[ИмяРеквизита].Значение, НаЧтоЗаменять) И Результат;
Иначе
Результат = Не ирОбщий.БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(СтрокаТаблицыБД[ИмяРеквизита], НаЧтоЗаменять) И Результат;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыполнитьЗаменуВНабореЗаписей(НаборЗаписейИлиМенеджерЗаписи, Заменяемые, НеправильныеСсылкиВОбъекте, Блокировать = Истина)
ОбъектМД = ирОбщий.ПолучитьМетаданныеЛкс(НаборЗаписейИлиМенеджерЗаписи);
ИмяТаблицыРегистра = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ОбъектМД);
Если ирОбщий.ЛиМенеджерЗаписиРегистраЛкс(НаборЗаписейИлиМенеджерЗаписи) Тогда
НаборЗаписей = ирОбщий.ПолучитьНаборЗаписейПоКлючуЛкс(ИмяТаблицыРегистра, НаборЗаписейИлиМенеджерЗаписи);
Иначе
НаборЗаписей = НаборЗаписейИлиМенеджерЗаписи;
КонецЕсли;
Если Блокировать Тогда
НачатьТранзакцию();
КонецЕсли;
Попытка
Если Блокировать Тогда
ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина);
КонецЕсли;
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ИмяТаблицыРегистра);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() = 0 Тогда
Если Блокировать Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Возврат Истина;
КонецЕсли;
ПоляТаблицыБД = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ОбъектМД);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
// Старый пустой набор нужен для очистки строк по старому отбору в случае изменения отбора набора
СтарыйНабор = ирОбщий.СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ИмяТаблицыРегистра);
ирОбщий.СкопироватьОтборЛкс(СтарыйНабор.Отбор, НаборЗаписей.Отбор);
ОтборИзменен = Ложь;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
ЗначениеПоля = ЭлементОтбора.Значение;
НаЧтоЗаменять = Заменяемые[ЗначениеПоля];
Если НаЧтоЗаменять = Неопределено Тогда
Продолжить;
КонецЕсли;
ОтборИзменен = ЗаменитьЗначениеРеквизитаСПроверкойВозможности(НаборЗаписей.Отбор, ЭлементОтбора.Имя, НаЧтоЗаменять, ПоляТаблицыБД) Или ОтборИзменен;
КонецЦикла;
ОбъектИзменен = ОтборИзменен; // Антибаг платформы 8.2. При изменении реквизитов строк набора записей для регистра бухгалтерии не взводится модифицированность
ЭтоРегистрБухгалтерии = ирОбщий.ПолучитьПервыйФрагментЛкс(ИмяТаблицыРегистра) = "РегистрБухгалтерии";
Если ЭтоРегистрБухгалтерии Тогда
ТаблицаНабора = НаборЗаписей.Выгрузить();
Иначе
ТаблицаНабора = НаборЗаписей;
КонецЕсли;
Для Каждого СтрокаНабора Из ТаблицаНабора Цикл
ОбъектИзменен = ВыполнитьЗаменуВСтрокеНабораЗаписей(СтрокаНабора, Заменяемые, ПоляТаблицыБД) Или ОбъектИзменен;
#Если Клиент Тогда
ОбработкаПрерыванияПользователя();
#КонецЕсли
КонецЦикла;
Если ЭтоРегистрБухгалтерии Тогда
НаборЗаписей.Загрузить(ТаблицаНабора);
ирОбщий.НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(НаборЗаписей);
ИначеЕсли ТипТаблицы = "РегистрСведений" И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
// Избавимся от неуникальных строк набора
Если НаборЗаписей.Количество() > 1 Тогда
СтруктураКлюча = ирОбщий.ПолучитьСтруктуруКлючаТаблицыБДЛкс(ИмяТаблицыРегистра,,, Ложь);
СтрокаПолейКлюча = "";
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
СтрокаПолейКлюча = СтрокаПолейКлюча + "," + КлючИЗначение.Ключ;
КонецЦикла;
СтрокаПолейКлюча = Сред(СтрокаПолейКлюча, 2);
НеуникальныеКлючи = ирОбщий.ПолучитьНеуникальныеКлючиКолонкиТаблицыЛкс(НаборЗаписей, СтрокаПолейКлюча);
Если НеуникальныеКлючи.Количество() > 0 Тогда
ТаблицаНабора = НаборЗаписей.Выгрузить();
Для Каждого НеуникальныйКлюч Из НеуникальныеКлючи Цикл
СтрокиНеуникальногоКлюча = ТаблицаНабора.НайтиСтроки(НеуникальныйКлюч);
Для ИндексУдаляемойСтроки = 0 По СтрокиНеуникальногоКлюча.Количество() - 2 Цикл
ТаблицаНабора.Удалить(СтрокиНеуникальногоКлюча[ИндексУдаляемойСтроки]);
КонецЦикла;
ПредставлениеСтруктуры = ирОбщий.ПолучитьПредставлениеСтруктурыЛкс(НеуникальныйКлюч);
Сообщить("Замещены неуникальные строки регистра сведений " + ОбъектМД.Имя + " по ключу " + ПредставлениеСтруктуры);
КонецЦикла;
НаборЗаписей.Загрузить(ТаблицаНабора);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ОбъектИзменен Тогда
Если ОтборИзменен Тогда
ирОбщий.ЗаписатьОбъектЛкс(СтарыйНабор, ЗаписьНаСервере,,, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
КонецЕсли;
ирОбщий.ЗаписатьОбъектЛкс(НаборЗаписей, ЗаписьНаСервере,,, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
КонецЕсли;
Если ТипТаблицы = "РегистрРасчета" Тогда
Для Каждого Перерасчет Из ОбъектМД.Перерасчеты Цикл
ИмяТаблицыПерерасчета = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(Перерасчет);
НаборЗаписейПерерасчета = ирОбщий.СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ИмяТаблицыПерерасчета);
НаборЗаписейПерерасчета.Отбор.ОбъектПерерасчета.Установить(НаборЗаписей.Отбор.Регистратор.Значение);
БылиИсключения = Не ВыполнитьЗаменуВНабореЗаписей(НаборЗаписейПерерасчета, Заменяемые, НеправильныеСсылкиВОбъекте, Ложь);
Если БылиИсключения Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Блокировать Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Исключение
Если Блокировать Тогда
ОтменитьТранзакцию();
КонецЕсли;
Если ОбщаяТранзакция Тогда
ВызватьИсключение;
КонецЕсли;
Сообщить("Ошибка обработки ссылающегося объекта " + ирОбщий.ПолучитьXMLКлючОбъектаБДЛкс(НаборЗаписей) + ": " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
Функция ВыполнитьЗаменуВСтрокеНабораЗаписей(СтрокаНабора, Заменяемые, ПоляТаблицыБД)
ОбъектИзменен = Ложь;
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Продолжить;
КонецЕсли;
//Если Не Поле.Поле Тогда // было для полей построителя запроса
// // Антибаг платформы. Зачем то добавляются лишние поля в доступные поля, не свойственные по признаку наличия корресподнеции
// // у бухгалтерских таблиц.
// Продолжить;
//КонецЕсли;
//ИмяПоля = Поле.Имя;
ИмяПоля = ПолеТаблицыБД.Имя;
ЗначениеПоля = СтрокаНабора[ИмяПоля];
НаЧтоЗаменять = Заменяемые[ЗначениеПоля];
Если НаЧтоЗаменять = Неопределено Тогда
Продолжить;
КонецЕсли;
ОбъектИзменен = ЗаменитьЗначениеРеквизитаСПроверкойВозможности(СтрокаНабора, ИмяПоля, НаЧтоЗаменять, ПоляТаблицыБД) Или ОбъектИзменен;
КонецЦикла;
Возврат ОбъектИзменен;
КонецФункции
Функция ПолучитьЗависимыеРеквизитыМД(ПоляТаблицы, ИмяРеквизита, ДанныеДляПоискаСвязейПоВладельцу = Неопределено) Экспорт
Результат = Новый Структура;
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
Если ПолеТаблицы.Метаданные = Неопределено Тогда
Продолжить;
КонецЕсли;
Для Каждого СвязьПараметровВыбора Из ПолеТаблицы.Метаданные.СвязиПараметровВыбора Цикл
ИмяРеквизитаСодежащегоВлияющее = СвязьПараметровВыбора.ПутьКДанным;
//Если Найти(ИмяРеквизитаСодежащегоВлияющее, ОбъектМД.Имя + ".") = 1 Тогда
// // Это строка ТЧ
ИмяРеквизитаСодежащегоВлияющее = ирОбщий.ПолучитьПоследнийФрагментЛкс(ИмяРеквизитаСодежащегоВлияющее);
//КонецЕсли;
Если ИмяРеквизитаСодежащегоВлияющее = ИмяРеквизита Тогда
ИмяРеквизитаОтбора = СтрЗаменить(СвязьПараметровВыбора.Имя, "Отбор.", "");
Результат.Вставить(ПолеТаблицы.Имя, ИмяРеквизитаОтбора);
КонецЕсли;
КонецЦикла;
Если ДанныеДляПоискаСвязейПоВладельцу <> Неопределено Тогда
Попытка
ЗначениеВладельца = ДанныеДляПоискаСвязейПоВладельцу[ПолеТаблицы.Имя].Владелец;
Исключение
ЗначениеВладельца = Неопределено;
КонецПопытки;
Если ЗначениеВладельца <> Неопределено Тогда
Если ЗначениеВладельца = ДанныеДляПоискаСвязейПоВладельцу[ИмяРеквизита] Тогда
Результат.Вставить(ПолеТаблицы.Имя, "Владелец");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ОбработатьНеправильныйОбъектПослеЗамены(УдаляемаяСсылка, НепосредственноеУдаление = Ложь, СсылкаДляЗаменыДанных = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
УдаляемаяСсылка = Справочники.УчастникиИис.ПустаяСсылка();
#КонецЕсли
Объект = УдаляемаяСсылка.ПолучитьОбъект();
ОбъектУдалили = Объект = Неопределено;
Если Не ОбъектУдалили Тогда
КорневойТип = ирОбщий.ПолучитьКорневойТипКонфигурацииЛкс(УдаляемаяСсылка);
НачатьТранзакцию();
Попытка
ПредставлениеОбъекта = "" + Объект;
Если СсылкаДляЗаменыДанных <> Неопределено Тогда
ПравильныйЭлементСНеправильнымиДанными = СсылкаДляЗаменыДанных.ПолучитьОбъект();
СтандартнаяОбработка = Истина;
Если ЗначениеЗаполнено(ОбработкаЗаменыДанных) Тогда
ТекстАлгоритма = "ПравильныйОбъект = _П0; НеправильныйОбъект = _П1; СтандартнаяОбработка = _П2; " + ОбработкаЗаменыДанных + "; _П2 = СтандартнаяОбработка;";
ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритма,,, ПравильныйЭлементСНеправильнымиДанными, Объект, СтандартнаяОбработка);
КонецЕсли;
Если СтандартнаяОбработка Тогда
НеправильныйОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(ПравильныйЭлементСНеправильнымиДанными);
НеправильныйОбъектXDTO.Ref = УдаляемаяСсылка;
ПравильныйОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(Объект);
ПравильныйОбъектXDTO.Ref = СсылкаДляЗаменыДанных;
ПравильныйОбъект = СериализаторXDTO.ПрочитатьXDTO(ПравильныйОбъектXDTO);
Если Истина
И Не ирОбщий.РежимСовместимостиМеньше8_3_4Лкс()
И ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип)
И (Ложь
Или Не НепосредственноеУдаление
Или (Истина
И НепосредственноеУдаление
И Не ЗначениеЗаполнено(ПравильныйОбъект.ИмяПредопределенныхДанных)))
Тогда
ПравильныйОбъект.ИмяПредопределенныхДанных = ПравильныйЭлементСНеправильнымиДанными.ИмяПредопределенныхДанных;
КонецЕсли;
Иначе
ПравильныйОбъект = ПравильныйЭлементСНеправильнымиДанными;
КонецЕсли;
ирОбщий.ЗаписатьОбъектЛкс(ПравильныйОбъект, ЗаписьНаСервере, , , Истина);
Если СтандартнаяОбработка Тогда
Объект = СериализаторXDTO.ПрочитатьXDTO(НеправильныйОбъектXDTO);
Объект.Прочитать();
ПредставлениеОбъекта = "" + Объект;
КонецЕсли;
КонецЕсли;
Если НепосредственноеУдаление Тогда
ирОбщий.УдалитьОбъектЛкс(Объект, ЗаписьНаСервере, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
ОбъектУдалили = Истина;
Сообщить("Удалили """ + ПредставлениеОбъекта + """");
Иначе
ирОбщий.УстановитьПометкуУдаленияОбъектаЛкс(Объект, ЗаписьНаСервере, Истина);
Сообщить("Установили пометку удаления """ + ПредставлениеОбъекта + """");
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
Сообщить("Обработка неправильного """ + ПредставлениеОбъекта + """: " + ОписаниеОшибки());
ОтменитьТранзакцию();
КонецПопытки;
КонецЕсли;
Возврат ОбъектУдалили;
КонецФункции
Процедура ОбработатьПравильныйОбъектПослеЗамены(ПравильнаяСсылка, СнятьПометкуУдаления = Ложь, Перезаписать = Ложь) Экспорт
Если Истина
И Не СнятьПометкуУдаления
И Не Перезаписать
Тогда
Возврат;
КонецЕсли;
Объект = ПравильнаяСсылка.ПолучитьОбъект();
Попытка
Если СнятьПометкуУдаления Тогда
Объект.ПометкаУдаления = Ложь;
Сообщить("Сняли пометку удаления """ + Объект + """");
КонецЕсли;
ирОбщий.ЗаписатьОбъектЛкс(Объект, ЗаписьНаСервере, , , ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Исключение
Сообщить("Обработка правильного """ + Объект + """: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
КонецПроцедуры
Функция ПолучитьСсылочныеИзмеренияРегистраЛкс(НаборЗаписей, МетаРегистр) Экспорт
ПоляТаблицы = НаборЗаписей.ВыгрузитьКолонки();
Результат = Новый Структура;
Для Каждого МетаИзмерение Из МетаРегистр.Измерения Цикл
ПолеТаблицы = ПоляТаблицы.Найти(МетаИзмерение.Имя);
Если ПолеТаблицы = Неопределено Тогда
// Например, небалансовое измерение регистра бухгалтерии
Продолжить;
КонецЕсли;
Для Каждого Тип Из МетаИзмерение.Тип.Типы() Цикл
Если Найти(XMLТип(Тип).ИмяТипа, "Ref.") > 0 Тогда
Результат.Вставить(МетаИзмерение.Имя, МетаИзмерение.Тип);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ЗаблокироватьРегистрПоОтборуИИзмерениямПередЗаменой(НаборЗаписей, НайденныеВОбъектеНеправильныеСсылки) Экспорт
Блокировка = Новый БлокировкаДанных;
ОбъектМД = НаборЗаписей.Метаданные();
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ИмяТаблицыРегистра = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ОбъектМД);
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ИмяТаблицыРегистра);
// По регистратору
Если Ложь
Или Не ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Или ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
Тогда
ПространствоБлокировок = ПолноеИмяМД + ".НаборЗаписей";
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
ЭлементБлокировки.УстановитьЗначение("Регистратор", НаборЗаписей.Отбор.Регистратор.Значение);
КонецЕсли;
// По измерениям блокируем все возможные диапазоны. В большинстве случаев при замене ссылок такие блокировки будут неоправданными
ПространствоБлокировок = ПолноеИмяМД;
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
СсылочныеИзмерения = ПолучитьСсылочныеИзмеренияРегистраЛкс(НаборЗаписей, ОбъектМД);
Для Каждого КлючЗначение Из СсылочныеИзмерения Цикл
ИмяИзмерения = КлючЗначение.Ключ;
ТипИзмерения = КлючЗначение.Значение;
Для Каждого НеправильнаяСсылка Из НайденныеВОбъектеНеправильныеСсылки Цикл
Если ТипИзмерения.СодержитТип(ТипЗнч(НеправильнаяСсылка)) Тогда
Блокировка.Добавить(ПространствоБлокировок).УстановитьЗначение(ИмяИзмерения, НеправильнаяСсылка);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Блокировка.Заблокировать();
КонецПроцедуры // ВыполнитьЗаменуВНабореЗаписей()
//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
//ирПортативный #Если Клиент Тогда
//ирПортативный Контейнер = Новый Структура();
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = ВосстановитьЗначение("ирПолноеИмяФайлаОсновногоМодуля");
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
//ирПортативный КонецЕсли;
//ирПортативный #Иначе
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный #КонецЕсли
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");
мПлатформа = ирКэш.Получить();
ТаблицаБукв = Новый ТаблицаЗначений;
ТаблицаБукв.Колонки.Добавить("Позиция");
ТаблицаБукв.Колонки.Добавить("КолвоПропущенных");
ТаблицаБукв.Колонки.Добавить("ДлинаСлова");
ТаблицаБукв.Колонки.Добавить("ПропущеноНа");
ЗаписьНаСервере = ирОбщий.ПолучитьРежимЗаписиНаСервереПоУмолчаниюЛкс();
ЭтотОбъект.ОтключатьКонтрольЗаписи = Истина;