mirror of
https://github.com/tormozit/RDT1C.git
synced 2025-12-17 05:04:11 +00:00
+В списке добавлена группа колонок свойств настроек управляемого приложения
+Добавлена кнопка "Установить..." для установки настроек управляемого приложения выделенным пользователям
+В форме запуска под пользователем добавлен флажок "Режим интерфейса "Такси""
+Запуск под пользователем с флагом "Разрешить отладку" теперь сразу подключает текущий отладчик к запускаемому сеансу
Общее
+Команда "Запустить обычное приложение" теперь в обоих типах управляемого приложения открывает одинаковую форму, в которой добавлен включенный по умолчанию флажок "Текущий пользователь"
+Команда "Запустить связанный тонкий клиент" теперь передает имя текущего пользователя в строке соединения
+При включенной параметром запуска /EnableCheckModal проверке модальности теперь при первом в сеансе открытии любой формы подсистемы предлагается запуск нового сеанса без проверки модальности
Интерфейсная панель.
+В контекстном меню добавлена команда "Связанный динамический список", открывающая единое окно динамического списка, обновляющее список при активизации строки
Динамический список
+Добавлена кнопка "Связанный редактор объекта БД", открывающая прикрепленное окно редактора объекта БД, загружающее объект при активизации строки
+Реализовано автоматическое обновление отображаемых строк при записи объекта в редакторе объекта БД
*Реализован обход ошибки платформы установки табличному полю типа списка независимого непериодического регистра сведений без измерений
Редактор объекта БД
*Увеличена длина дробной части значений отбора набора записей
Контекстная подсказка
*Исправлена ошибка инициализации формы списка слов при отсутствии activex компоненты Forms20
Консоль запросов
*Кнопка "Найти в дереве запроса" теперь доступна только в режиме просмотра узла дерева запроса
*При сохранении узла дерева запроса, текущий узел теперь ищется не по именам, а по индексам узлов
*Исправлено зависание программы при копировании папки дерева запросов
*Исправлено некорректное определение имени узла дерева запроса в некоторых случаях при наличии функции ЗНАЧЕНИЕ(...)
*При выборе основного элемента результата пакетного запроса теперь игнорируются результаты уничтожения таблиц
Редактор табличного документа
+Добавлена кнопка "Сохранить"
3.70
Консоль компоновки данных
+В настройках компоновки в таблице условного оформления добавлен пример оформления текста в колонке "Пример"
Консоль кода
+Добавлено дерево алгоритмов
+Изменен формат файлов на t1c, старый формат f1c доступен только для открытия файлов
*После сохранения в файл теперь сбрасывается модифицированность формы
+Добавлена кнопка объединения с файлом
+Добавлено подменю последних открытых файлов
+Для булевых параметров реализовано отображение флажка
Консоль запросов
+При генерации текста модуля пакетного запроса теперь добавляется установка переменных вида "Индекс_<ИмяЗапроса>=<Индекс>" для всех именованных запросов
+Команде "Найти в дереве" назначено сочетание клавиш CTRL+T
+Для булевых параметров реализовано отображение флажка
*Исправлено некорректное отображение количества строк в дереве результата при наличии выборок итогов
Общее
*Исправлены ошибки работы подсистемы при наличии общего модуля с именем ОбменДанными
*Кнопка "Установить одинаковую ширину для всех колонок" заменена на "Расширить все колонки на 5 символов"
Синтакс-помощник
*Исправлено построение дерева, сломавшееся несколько версий назад
Управление службами серверов 1С
*Исправлена ошибка чтения служб при наличии службы сервера 1С без ключа "range" в строке запуска
Редактор объекта БД
+Для наборов записей добавлена фиксированная колонка картинки вида движения регистра накопления
+По умолчанию для списка движений теперь включен отбор "Только не пустые"
+Кнопка открытия редактора для таблицы движений теперь передает текущую строку
Подбор и обработка объектов
+Реализована поддержка журналов документов в однотабличном режиме
Динамический список
+В режиме выбора в заголовке теперь добавляется "(выбор)"
Интерфейсная панель
+Теперь уважает настройку использования "Динамический список / Основная форма списка"
3.69
Общее
+Вместо форм выбора теперь по умолчанию всегда открывается динамический список
-Кнопка "Редактировать список" для значения отбор компоновки везде удалена, теперь редактирование списка всегда выполняется в расширенном режиме
Динамический список
+Добавлен флажок "Вместо основной" сохраняемый в настройках пользователя в разрезе объектов метаданных, управляющий подменой форм выбора
Консоль компоновки
*Исправлена ошибка команды "переставить с родителем" для группировок колонок и строк таблиц
Контекстная подсказка
*Кнопка "Удалить переносы" теперь еще заменяет двойные кавычки обычными
Конструктор запросов
+Для списка доступных таблиц добавлена закладка-отбор "Параметр"
+При добавлении таблицы-параметра в выбранные таблицы сразу устанавливать тип запроса и имя временной таблицы
Консоль запросов
*Исправлена вычисление группировок итогов с закомментированным словом ОБЩИЕ
+Кнопки выполнения запроса разделены на "Выполнить отображаемый запрос (F7)" и "Выполнить полный запрос (F8)"
Редактор объекта БД
*Исправлена ошибка поиска значения в бизнес процессе
3.68
Редактор констант
+Добавлена частичная поддержка констант с типом значения "Хранилище значения"
Динамический список
+Добавлена кнопка открытия основной формы списка с передачей отбора, текущей строки и владельца формы
*Исправлена свежая ошибки открытия журнала документов
Менеджер табличного поля
*Исправлено ограничение типа значений элементов отбора
Редактор объекта БД
+В элементах управления колонок набора записей и движений реализован учет многострочного режима и других свойств из метаданных
*Исправлена свежая поломка привязок на вкладке "Связанные колонки"
Управление службами 1с
*Исправлено перезаполнение списка при изменении компьютера
Консоль запросов
+Реализовано сохранение и восстановление позиции в тексте запроса при переходе между запросами и переключении режима дерева запроса
+Для поля текста запроса добавлена команда "найти в дереве запроса" (текущую позицию в тексте запроса)
Поиск дублей и замена ссылок
*Исправлена свежая ошибка выполнения замены в иерархическом справочнике без флажка "Изменять поля по связям параметров выбора"
Расширенный ввод значений
+Добавлено распознавание навигационных ссылок
Общее
+Кнопка запуска связанного тонкого клиента теперь при повторном нажатии позволяет открыть в редакторе объекта БД один из открытых в связанном сеансе объектов
Контекстная подсказка
+Включена поддержка 8.3.8 в низкоуровневом получении описаний объектов
3.67
Управление службами серверов 1С
*Устранена ошибка открытия при наличии в строке соединения порта
*Исправлено открытие при ошибках подключения WMI
Консоль компоновки
*Исправлена ошибка расшифровки при наличии пользовательских настроек компоновки
+В панели настроек добавлена закладка "Пользовательские настройки" только для просмотра
+В подменю "Исследовать" добавлена команда "Пользовательские настройки"
+При сохранении варианта настроек добавлен пункт "<Новый>"
+Реализовано перетаскивание полей на строки-коллекции в структуре
Консоль запросов
*Исправлена некорректная работа команды "найти результат" дерева запроса
*Исправлена некорректная работа команды "Встроить из подзапроса" дерева запроса
Конструктор запросов
*Исправлено обновление представления условия связи при перетаскивании элементов отбора между связями
Подбор и обработка объектов
*Исправлены свежие ошибки при обработке подчиненных регистров сведений
Редактор объекта БД
*Исправлена недоступность для изменения основной формы измененного объекта
+Добавлена кнопка "Отрыть основную форму объекта по ссылке"
+При двойном клике по имени регистра в списке движений открывается его форма списка с отбором по регистратору
*Исправлен сломанный несколько версий назад расширенный ввод значений в поле Ссылка
Общее
+В панели инструментов добавлена кнопка "Запустить связанный тонкий клиент"
Интерфейсная панель
+Реализовано явное отображение пустых ссылок в дереве
Динамический список
+Добавлена команда "Редактор объекта БД ячейки"
Поиск дублей и замена ссылок
+При выполнении замены реализовано предотвращение зацикливания уровней путем поднятия до ближайшего корректного родителя
Настройка техножурнала
*Реализован обход проблемы платформы со смещением времени изменения файла на 1ч
3.66
+Добавлен инструмент "Управление службами серверов 1С"
Поиск дублей и замена ссылок
*Исправлена ошибка вывода сообщения об ошибке при отказе в записи независимых регистров сведений
*Исправлено неверное замещение неуникальных записей в подчиненных регистрах сведений
Подбор и обработка объектов
*Исправлены ошибки при работе с подчиненными регистрами сведений
Общее
*Исправлено восстановление пароля в форме подключения СУБД
*Исправлено свежее незапланированное изменение в поведении кнопки "Редактор объекта БД"
Консоль компоновки данных
*Кнопка "Исполняемый запрос" теперь открывает консоль запросов немодально
Различные значения колонки
+Добавлена кнопка "В список"
*Исправлено некорректное вычисление типов значений
Редактор объекта БД
+Реализована поддержка флагов "Многострочный режим" и "Расширенное редактирование" колонок табличных частей и наборов записей
1218 lines
87 KiB
Plaintext
1218 lines
87 KiB
Plaintext
//ирПортативный Перем ирПортативный Экспорт;
|
||
//ирПортативный Перем ирОбщий Экспорт;
|
||
//ирПортативный Перем ирСервер Экспорт;
|
||
//ирПортативный Перем ирКэш Экспорт;
|
||
//ирПортативный Перем ирПривилегированный Экспорт;
|
||
|
||
Перем мПлатформа Экспорт;
|
||
Перем мСервисныйПроцессор Экспорт; // Для программного вызова из Интеграции
|
||
Перем ТаблицаБукв;
|
||
Перем мИскомыйОбъектПоискаДублей Экспорт;
|
||
Перем мСтруктураПоиска Экспорт;
|
||
|
||
Функция ЭтоБуква (Символ)
|
||
|
||
Код = КодСимвола(Символ);
|
||
|
||
Если (Код<=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";
|
||
//ирПортативный #Если Клиент Тогда
|
||
//ирПортативный Контейнер = Новый Структура();
|
||
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
|
||
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
|
||
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = ВосстановитьЗначение("ирПолноеИмяФайлаОсновногоМодуля");
|
||
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
|
||
//ирПортативный КонецЕсли;
|
||
//ирПортативный #Иначе
|
||
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
|
||
//ирПортативный #КонецЕсли
|
||
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
|
||
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
|
||
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
|
||
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");
|
||
|
||
мПлатформа = ирКэш.Получить();
|
||
ТаблицаБукв = Новый ТаблицаЗначений;
|
||
ТаблицаБукв.Колонки.Добавить("Позиция");
|
||
ТаблицаБукв.Колонки.Добавить("КолвоПропущенных");
|
||
ТаблицаБукв.Колонки.Добавить("ДлинаСлова");
|
||
ТаблицаБукв.Колонки.Добавить("ПропущеноНа");
|
||
ЗаписьНаСервере = ирОбщий.ПолучитьРежимЗаписиНаСервереПоУмолчаниюЛкс();
|
||
ЭтотОбъект.ОтключатьКонтрольЗаписи = Истина; |