mirror of
https://github.com/tormozit/RDT1C.git
synced 2025-12-17 13:14:11 +00:00
*Исправлена ошибка при выполнении команды вставки ссылки при выделенном имени не ссылочного параметра
Общее
*Исправлена ошибка вывода строк таблицы в табличный документ без оформления в портативном варианте
*Исправлено игнорирование общих параметров записи в файловой базе
Редактор объекта БД
*Исправлено не сохранение изменений значений реквизитов после загрузки табилцы реквизитов из табличного документа
Удаление объектов с контролем ссылок
*Исправлена ошибка выполнения контроля в таблице Субконто в английском варианте встроенного языка
Статистика запросов MSSQL
*Исправлена ошибка выполнения с заданными границами интервала времени в случае нестандартного формата даты datetime в БД
Управление профайлами 1С
*Исправлена некорректное извлечение ключа базы из командной строки в некоторых случаях
1266 lines
96 KiB
Plaintext
1266 lines
96 KiB
Plaintext
//ирПортативный Перем ирПортативный Экспорт;
|
||
//ирПортативный Перем ирОбщий Экспорт;
|
||
//ирПортативный Перем ирСервер Экспорт;
|
||
//ирПортативный Перем ирКэш Экспорт;
|
||
//ирПортативный Перем ирПривилегированный Экспорт;
|
||
|
||
Перем мСервисныйПроцессор Экспорт; // Для программного вызова из Интеграции
|
||
|
||
Процедура лСостояние(Текст)
|
||
//#Если Клиент Тогда
|
||
//Состояние(Текст);
|
||
//#КонецЕсли
|
||
КонецПроцедуры
|
||
|
||
// Выводит сообщение об ошибке
|
||
// Параметры:
|
||
// ТекстСообщения - строка, текст сообщения.
|
||
//
|
||
Процедура вСообщить(ТекстСообщения, Статус )
|
||
Сообщить(ТекстСообщения, Статус);
|
||
КонецПроцедуры // вСообщитьОбОшибке()
|
||
|
||
Процедура лСостояниеПоиск(Текст)
|
||
//#Если Клиент Тогда
|
||
//Состояние("Поиск в "+Текст);
|
||
//#КонецЕсли
|
||
КонецПроцедуры
|
||
|
||
Процедура УстановитьЧтоСсылкуНельзяУдалить(Знач Ссылка, Связи, Типы)
|
||
|
||
// убираем эту ссылку из таблицы связей, где она является Ссылкой, т.к. проверять ссылание на неё уже не надо
|
||
Строки = Связи.НайтиСтроки(Новый Структура("Ссылка",Ссылка));
|
||
|
||
Если Строки.Количество() = 0 Тогда // ссылка уже исключена из кандидатов на удаление
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Для каждого С из Строки Цикл
|
||
Связи.Удалить(С);
|
||
КонецЦикла;
|
||
|
||
// убираем эту ссылку из дальнейших проверок в полях базы
|
||
МассивСсылок = Типы[ТипЗнч(Ссылка)];
|
||
МассивСсылок.Удалить(МассивСсылок.Найти(Ссылка));
|
||
Если МассивСсылок.Количество() = 0 Тогда
|
||
Типы.Удалить(ТипЗнч(Ссылка));
|
||
КонецЕсли;
|
||
|
||
// надо также убрать из кандидатов все ссылки, для которых данная была связью
|
||
Строки = Связи.НайтиСтроки(Новый Структура("Данные",Ссылка));
|
||
Для каждого С из Строки Цикл
|
||
УстановитьЧтоСсылкуНельзяУдалить(С.Ссылка,Связи,Типы);
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ПросмотретьСсылкиИзЗапроса(Запрос, КолвоСсылок, ДляУдаления, Связи, Типы, ЭтоТаблицаОбъектов,
|
||
ОбъектСвязи,
|
||
ИмяРегистра = Неопределено, КлючиЗаписей = Неопределено, ОтборКлюча = Неопределено, // для работы с независимыми регистрами сведений
|
||
Мета = Неопределено // для записи в данные, если данные=Неопределено
|
||
)
|
||
|
||
Отбор = Новый Структура("Ссылка,Данные");
|
||
Выборка = Запрос.Выполнить().Выбрать();
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Выборка.Количество(), ОбъектСвязи);
|
||
Пока Выборка.Следующий() Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
К = КолвоСсылок;
|
||
Пока К > 0 Цикл
|
||
К = К - 1;
|
||
Ссылка = Выборка[К];
|
||
Если Истина
|
||
И ЗначениеЗаполнено(Ссылка)
|
||
И Не (Истина
|
||
И ДляУдаления
|
||
И ЭтоТаблицаОбъектов
|
||
И Ссылка = Выборка.Ссылка)
|
||
Тогда // проверяем только заполненные ссылки и не учитываем связи с собой же
|
||
СтрокаСвязи = Связи.Найти(Ссылка, "Ссылка");
|
||
Если СтрокаСвязи <> Неопределено Тогда // ссылка - кандидат на удаление
|
||
Если ДляУдаления Тогда
|
||
// если ключ записи в качестве ссылки - всегда считаем, что нельзя удалять и надо убрать из кандидатов
|
||
Если Истина
|
||
И ЭтоТаблицаОбъектов
|
||
И Связи.Найти(Выборка.Ссылка, "Ссылка") <> Неопределено
|
||
Тогда // связанная ссылка находится в таблице кандидатов на удаление, поэтому нельзя пока сказать точно можно удалить текущую или нет
|
||
Если СтрокаСвязи.Данные = Неопределено Тогда // если ранее еще не было связей с кандидатами на удаление
|
||
СтрокаСвязи.Данные = Выборка.Ссылка; // поменяли, что есть связь с кандидатом на удаление
|
||
СтрокаСвязи.ОбъектСвязи = ОбъектСвязи;
|
||
ИначеЕсли СтрокаСвязи.Данные <> Выборка.Ссылка Тогда // если текущая найденная связь не с этим кандидатом, поищем нет ли с этим
|
||
Отбор.Ссылка = Ссылка;
|
||
Отбор.Данные = Выборка.Ссылка;
|
||
Если Связи.НайтиСтроки(Отбор).Количество() = 0 Тогда // нет связей с таким кандидатом - надо добавить
|
||
СтрокаСвязи = Связи.Добавить();
|
||
ЗаполнитьЗначенияСвойств(СтрокаСвязи, Отбор);
|
||
СтрокаСвязи.ОбъектСвязи = ОбъектСвязи;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Иначе // связанная ссылка не находится в таблице кандидатов на удаление, поэтому текущую ссылку точно удалять нельзя
|
||
УстановитьЧтоСсылкуНельзяУдалить(Ссылка,Связи,Типы);
|
||
КонецЕсли;
|
||
Иначе // если просто ищем все ссылки на помеченные
|
||
// если есть ссылка - в качестве ключа берём её, иначе надо где-то хранить ключи и в качестве Данные давать строку из этой таблицы
|
||
Если КлючиЗаписей = Неопределено Тогда
|
||
Отбор.Данные = Выборка.Ссылка;
|
||
Если Отбор.Данные = Неопределено Тогда
|
||
Если ТипЗнч(Мета) = Тип("Строка") Тогда
|
||
Мета = Метаданные.НайтиПоПолномуИмени(Мета);
|
||
КонецЕсли;
|
||
Отбор.Данные = Мета;
|
||
КонецЕсли;
|
||
Иначе
|
||
Для каждого Элемент из ОтборКлюча Цикл
|
||
ОтборКлюча[Элемент.Ключ] = Выборка[Элемент.Ключ];
|
||
КонецЦикла;
|
||
Строки = КлючиЗаписей.НайтиСтроки(ОтборКлюча);
|
||
Если Строки.Количество() = 0 Тогда
|
||
СК = КлючиЗаписей.Добавить();
|
||
Для каждого Элемент из ОтборКлюча Цикл
|
||
СК[Элемент.Ключ] = Элемент.Значение;
|
||
КонецЦикла;
|
||
НомерСтроки = КлючиЗаписей.Количество()-1;
|
||
Иначе
|
||
СК = Строки[0];
|
||
НомерСтроки = КлючиЗаписей.Индекс(СК);
|
||
КонецЕсли;
|
||
Отбор.Данные = ИмяРегистра + "." + Формат(НомерСтроки, "ЧГ=0");
|
||
//КлючЗаписи = РегистрыСведений[ИмяРегистра].СоздатьКлючЗаписи(ОтборКлюча);
|
||
//Отбор.Данные = ЗначениеВСтрокуВнутр(КлючЗаписи);
|
||
КонецЕсли;
|
||
Если СтрокаСвязи.Данные = Неопределено Тогда
|
||
СтрокаСвязи.Данные = Отбор.Данные;
|
||
СтрокаСвязи.ОбъектСвязи = ОбъектСвязи;
|
||
//Если СтрокаСвязи.Данные = Неопределено Тогда
|
||
// Если ТипЗнч(Мета) = Тип("Строка") Тогда
|
||
// Мета = Метаданные.НайтиПоПолномуИмени(Мета);
|
||
// КонецЕсли;
|
||
// СтрокаСвязи.Данные = Мета;
|
||
//КонецЕсли;
|
||
//Сообщить(Строка(Ссылка)+ " <- " + Отбор.Данные);
|
||
ИначеЕсли СтрокаСвязи.Данные <> Отбор.Данные Тогда
|
||
Отбор.Ссылка = Ссылка;
|
||
Если Связи.НайтиСтроки(Отбор).Количество() = 0 Тогда
|
||
СтрокаСвязи = Связи.Добавить();
|
||
ЗаполнитьЗначенияСвойств(СтрокаСвязи, Отбор);
|
||
//Сообщить(Строка(Ссылка)+ " <- " + Отбор.Данные);
|
||
СтрокаСвязи.ОбъектСвязи = ОбъектСвязи;
|
||
//Если СтрокаСвязи.Данные = Неопределено Тогда
|
||
// Если ТипЗнч(Мета) = Тип("Строка") Тогда
|
||
// Мета = Метаданные.НайтиПоПолномуИмени(Мета);
|
||
// КонецЕсли;
|
||
// СтрокаСвязи.Данные = Мета;
|
||
//КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли; // ЗначениеЗаполнено(Ссылка)
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Реквизиты,ИмяСсылка,КлючиЗаписей=Неопределено,
|
||
Знач Мета=Неопределено // метаданные, чтобы записать в данные если неопределено
|
||
)
|
||
|
||
Если Реквизиты.Количество() = 0 Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
// надо искать в реквизитах и табличных частях документов
|
||
Запрос = Новый Запрос;
|
||
ТекстУсловия = "";
|
||
ТекстВыбора = "";
|
||
|
||
Для каждого Реквизит из Реквизиты Цикл
|
||
// строим массив ссылок для этого реквизита
|
||
СсылкиРеквизита = Неопределено;
|
||
|
||
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
|
||
#Если Сервер И Не Сервер Тогда
|
||
Для каждого ТекущийТип из Типы Цикл
|
||
Если Реквизит.Тип.СодержитТип(ТекущийТип.Ключ) Тогда // надо проверить по этому реквизиту ссылки этого типа
|
||
Если СсылкиРеквизита = Неопределено Тогда
|
||
СсылкиРеквизита = Новый Массив;
|
||
КонецЕсли;
|
||
Для каждого Ссылка из ТекущийТип.Значение Цикл
|
||
СсылкиРеквизита.Добавить(Ссылка);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
#КонецЕсли
|
||
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
|
||
Для каждого ТекущийТип из Типы Цикл Если Реквизит.Тип.СодержитТип(ТекущийТип.Ключ) Тогда Если СсылкиРеквизита = Неопределено Тогда СсылкиРеквизита = Новый Массив; КонецЕсли; Для каждого Ссылка из ТекущийТип.Значение Цикл СсылкиРеквизита.Добавить(Ссылка); КонецЦикла; КонецЕсли; КонецЦикла;
|
||
|
||
Если СсылкиРеквизита <> Неопределено Тогда
|
||
ИмяПараметра = Реквизит.Имя;
|
||
ТекстВыбора = ТекстВыбора + ИмяПараметра + ",";
|
||
ТекстУсловия = ТекстУсловия + " ИЛИ " + ИмяПараметра + " В (&" + ИмяПараметра + ")";
|
||
Запрос.УстановитьПараметр(ИмяПараметра, СсылкиРеквизита);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если ТекстВыбора <> "" Тогда // есть хотя бы один искомый реквизит в документе
|
||
Отбор = Новый Структура("Ссылка,Данные");
|
||
ОтборКлюча = Неопределено; // здесь будет структура для отбора по ключу независимого регистра сведений, если нужно
|
||
Если КлючиЗаписей = Неопределено Тогда
|
||
ПолеСсылки = ИмяСсылка + " КАК Ссылка";
|
||
ИначеЕсли КлючиЗаписей = ИСТИНА Тогда
|
||
ПолеСсылки = "";
|
||
Иначе // ключ получаем, а не ссылку
|
||
ПолеСсылки = "";
|
||
Для каждого Поле из КлючиЗаписей.Колонки Цикл
|
||
ПолеСсылки = ПолеСсылки + "," + Поле.Имя;
|
||
КонецЦикла;
|
||
ПолеСсылки = Сред(ПолеСсылки, 2);
|
||
ОтборКлюча = Новый Структура;
|
||
Для каждого Колонка из КлючиЗаписей.Колонки Цикл
|
||
ОтборКлюча.Вставить(Колонка.Имя, Неопределено);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Если ПолеСсылки = "" Тогда
|
||
ПолеСсылки = "Неопределено КАК Ссылка";
|
||
КонецЕсли;
|
||
Запрос.Текст = "ВЫБРАТЬ " + ТекстВыбора + ПолеСсылки + " ИЗ " + ИмяТаблицы + " ГДЕ " + Сред(ТекстУсловия, 6);
|
||
ЭтоТаблицаОбъектов = (ВРЕГ(ИмяСсылка) = "ССЫЛКА");
|
||
ПросмотретьСсылкиИзЗапроса(Запрос, Запрос.Параметры.Количество(), ДляУдаления, Связи, Типы, ЭтоТаблицаОбъектов, ИмяТаблицы, ИмяСсылка, КлючиЗаписей, ОтборКлюча, Мета);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура НайтиСсылкиВТаблицеСубконто(ДляУдаления,Мета,Связи,Типы)
|
||
// ищет ссылки в таблице субконто регистров бухгалтерии
|
||
// будем пытаться использовать индекс по Вид(Субконто) + Значение
|
||
|
||
// в процессе работы могут наши типы удаляться из соответствия Типы, надо учитывать эту ситуацию - сбросим их во временный массив
|
||
МассивТипов = Новый Массив;
|
||
Для каждого ТекущийТип из Типы Цикл
|
||
МассивТипов.Добавить(ТекущийТип.Ключ);
|
||
КонецЦикла;
|
||
|
||
ИмяТаблицы = Мета.ПолноеИмя() + "." + ирОбщий.ПеревестиСтроку("Субконто");
|
||
Запрос = Новый Запрос("ВЫБРАТЬ Значение,Регистратор КАК Ссылка ИЗ " + ИмяТаблицы + " ГДЕ Вид=&ВидСубконто И Значение В (&Значение)");
|
||
|
||
МетаВидыСубконто = Мета.ПланСчетов.ВидыСубконто;
|
||
Если МетаВидыСубконто <> Неопределено Тогда
|
||
ЗапросВидаСубконто = Новый Запрос("ВЫБРАТЬ Ссылка,ТипЗначения ИЗ "+МетаВидыСубконто.ПолноеИмя());
|
||
ВыборкаВидаСубконто = ЗапросВидаСубконто.Выполнить().Выбрать();
|
||
Пока ВыборкаВидаСубконто.Следующий() Цикл
|
||
Запрос.УстановитьПараметр("ВидСубконто", ВыборкаВидаСубконто.Ссылка); // готовимся выбирать значения субконто этого вида
|
||
// надо посмотреть какие наши типы подходят в этот ВидСубконто
|
||
Л = МассивТипов.Количество();
|
||
Пока Л > 0 Цикл
|
||
Л = Л - 1;
|
||
Если Истина
|
||
И ВыборкаВидаСубконто.ТипЗначения <> Null
|
||
И ВыборкаВидаСубконто.ТипЗначения.СодержитТип(МассивТипов[Л])
|
||
Тогда
|
||
// можно проверять наших кандидатов указанного типа с этим видом субконто
|
||
МассивСсылок = Типы[МассивТипов[Л]];
|
||
Если МассивСсылок <> Неопределено Тогда // могут удалиться некоторые типы в процессе работы
|
||
Запрос.УстановитьПараметр("Значение", МассивСсылок);
|
||
ПросмотретьСсылкиИзЗапроса(Запрос, 1, ДляУдаления, Связи, Типы, Ложь, ИмяТаблицы);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры // НайтиСсылкиВТаблицеСубконто
|
||
|
||
Процедура ОбновитьСтрокуУдаляемогоОбъекта(ЭтаФорма, СтрокаУдаляемогоОбъекта = Неопределено, СоответствиеТипаКМетаданному = Неопределено, Знач ПометкаУдаления = Неопределено,
|
||
Знач Представление = Неопределено) Экспорт
|
||
|
||
Если СтрокаУдаляемогоОбъекта = Неопределено Тогда
|
||
СтрокаУдаляемогоОбъекта = ЭтаФорма.ЭлементыФормы.УдаляемыеОбъекты.ТекущаяСтрока;
|
||
КонецЕсли;
|
||
#Если Сервер И Не Сервер Тогда
|
||
СтрокаУдаляемогоОбъекта = УдаляемыеОбъекты.Добавить();
|
||
#КонецЕсли
|
||
Если Представление = Неопределено Тогда
|
||
Представление = "" + СтрокаУдаляемогоОбъекта.Ссылка;
|
||
КонецЕсли;
|
||
СтрокаУдаляемогоОбъекта.Представление = Представление;
|
||
ТипУдаляемогоОбъекта = ТипЗнч(СтрокаУдаляемогоОбъекта.Ссылка);
|
||
Если СоответствиеТипаКМетаданному <> Неопределено Тогда
|
||
ИмяМетаданного = СоответствиеТипаКМетаданному[ТипУдаляемогоОбъекта];
|
||
КонецЕсли;
|
||
Если ИмяМетаданного = Неопределено Тогда
|
||
ИмяМетаданного = СтрокаУдаляемогоОбъекта.Ссылка.Метаданные().ПолноеИмя();
|
||
Если СоответствиеТипаКМетаданному <> Неопределено Тогда
|
||
СоответствиеТипаКМетаданному.Вставить(ТипУдаляемогоОбъекта, ИмяМетаданного);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
СтрокаУдаляемогоОбъекта.Метаданные = ИмяМетаданного;
|
||
СтрокаУдаляемогоОбъекта.Разрешен = Истина;
|
||
//СтрокаУдаляемогоОбъекта.Удаляется = Истина;
|
||
Если ПометкаУдаления = Неопределено Тогда
|
||
ПометкаУдаления = СтрокаУдаляемогоОбъекта.Ссылка.ПометкаУдаления;
|
||
КонецЕсли;
|
||
Если ПометкаУдаления Тогда
|
||
СтрокаУдаляемогоОбъекта.ИндексКартинки = 1;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ДобавитьМассивОбъектовВУдаляемыеОбъекты(МассивОбъектов, ЭтаФорма = Неопределено, УстанавливатьТекущуюСтроку = Ложь, ПредлагатьПомечатьНаУдаление = Ложь) Экспорт
|
||
|
||
ВМассивеБылиНовыеПодходящиеОбъекты = Ложь;
|
||
ТаблицаОбъектов = УдаляемыеОбъекты.ВыгрузитьКолонки();
|
||
Для Каждого Объект Из МассивОбъектов Цикл
|
||
Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(Объект) Тогда
|
||
СтрокаОбъекта = ТаблицаОбъектов.Добавить();
|
||
СтрокаОбъекта.Ссылка = Объект;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если ТаблицаОбъектов.Количество() = 0 Тогда
|
||
Возврат ВМассивеБылиНовыеПодходящиеОбъекты;
|
||
КонецЕсли;
|
||
ОбновитьДанныеКандидатов(ТаблицаОбъектов);
|
||
СписокБылПустым = УдаляемыеОбъекты.Количество() = 0;
|
||
СоответствиеТипаКМетаданному = Новый Соответствие;
|
||
Если ПредлагатьПомечатьНаУдаление Тогда
|
||
ПомечатьНаУдаление = Неопределено;
|
||
Иначе
|
||
ПомечатьНаУдаление = Ложь;
|
||
КонецЕсли;
|
||
#Если Клиент Тогда
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаОбъектов.Количество(), "Добавление кандидатов");
|
||
#КонецЕсли
|
||
Для Каждого СтрокаОбъекта Из ТаблицаОбъектов Цикл
|
||
#Если Клиент Тогда
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
#КонецЕсли
|
||
Если СтрокаОбъекта.Предопределенный Тогда
|
||
Сообщить("Предопределенный объект """ + СтрокаОбъекта.Представление + """ нельзя добавлять в кандидаты");
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Если Не СписокБылПустым Тогда
|
||
СтрокаКандидата = УдаляемыеОбъекты.Найти(СтрокаОбъекта.Ссылка, "Ссылка");
|
||
Иначе
|
||
СтрокаКандидата = Неопределено;
|
||
КонецЕсли;
|
||
Если СтрокаКандидата = Неопределено Тогда
|
||
#Если Клиент Тогда
|
||
Если ПомечатьНаУдаление = Неопределено И Не СтрокаОбъекта.ПометкаУдаления Тогда
|
||
Ответ = Вопрос("Хотите пометить на удаление добавляемые кандидаты?", РежимДиалогаВопрос.ДаНет);
|
||
ПомечатьНаУдаление = Ответ = КодВозвратаДиалога.Да;
|
||
КонецЕсли;
|
||
#КонецЕсли
|
||
Если ПомечатьНаУдаление = Истина И Не СтрокаОбъекта.ПометкаУдаления Тогда
|
||
//ОбъектКандидата = СтрокаОбъекта.Ссылка.ПолучитьОбъект();
|
||
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(СтрокаОбъекта.Ссылка.Метаданные().ПолноеИмя(), СтрокаОбъекта.Ссылка);
|
||
ирОбщий.УстановитьПометкуУдаленияОбъектаЛкс(СтруктураОбъекта.Методы,, Истина);
|
||
СтрокаОбъекта.ПометкаУдаления = Истина;
|
||
КонецЕсли;
|
||
СтрокаКандидата = УдаляемыеОбъекты.Добавить();
|
||
СтрокаКандидата.Ссылка = СтрокаОбъекта.Ссылка;
|
||
ОбновитьСтрокуУдаляемогоОбъекта(ЭтаФорма, СтрокаКандидата, СоответствиеТипаКМетаданному, СтрокаОбъекта.ПометкаУдаления, СтрокаОбъекта.Представление);
|
||
ВМассивеБылиНовыеПодходящиеОбъекты = Истина;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
#Если Клиент Тогда
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
#КонецЕсли
|
||
Если Истина
|
||
И ЭтаФорма <> Неопределено
|
||
И УстанавливатьТекущуюСтроку
|
||
И СтрокаКандидата <> Неопределено
|
||
Тогда
|
||
ЭтаФорма.ЭлементыФормы.УдаляемыеОбъекты.ТекущаяСтрока = СтрокаКандидата;
|
||
КонецЕсли;
|
||
Если ВМассивеБылиНовыеПодходящиеОбъекты Тогда
|
||
Если ЭтаФорма <> Неопределено Тогда
|
||
ЭтаФорма.НеобходимоВыполнитьКонтроль = Истина;
|
||
Если ЭтаФорма.Открыта() Тогда
|
||
ЭтаФорма.ПодключитьОбработчикОжидания("ПослеИзмененияСоставаКандидатов", 0.1, Истина);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Возврат ВМассивеБылиНовыеПодходящиеОбъекты;
|
||
|
||
КонецФункции
|
||
|
||
// Неинтерактивный аналог метода формы вОбновитьПомеченныеНаУдаление
|
||
Процедура ЗаполнитьКандидатыНаУдалениеПомеченнымиНаУдаление() Экспорт
|
||
|
||
СсылкиНаКандидата.Очистить();
|
||
УдаляемыеОбъекты.Очистить();
|
||
МассивКУдалению = НайтиПомеченныеНаУдаление();
|
||
ДобавитьМассивОбъектовВУдаляемыеОбъекты(МассивКУдалению);
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура УстановитьНеблокирующиеТипы(МассивПолныхИменМД) Экспорт
|
||
|
||
КопияТаблицы = НеблокирующиеТипы.Выгрузить();
|
||
НеблокирующиеТипы.Очистить();
|
||
Для Каждого ПолноеИмяМД Из МассивПолныхИменМД Цикл
|
||
СтрокаНеблокирующегоТипа = НеблокирующиеТипы.Добавить();
|
||
СтрокаНеблокирующегоТипа.Метаданные = ПолноеИмяМД;
|
||
СтараяСтрока = КопияТаблицы.Найти(ПолноеИмяМД, "Метаданные");
|
||
Если СтараяСтрока <> Неопределено Тогда
|
||
СтрокаНеблокирующегоТипа.Игнорировать = СтараяСтрока.Игнорировать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
НеблокирующиеТипы.Сортировать("Метаданные");
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция НайтиСсылки(Ссылки, ДляУдаления) Экспорт
|
||
// Ссылки - массив ссылок объектов для проверки
|
||
// ДляУдаления - равен Ложь если надо получить результат в виде таблицы, аналогично встроенной функции ПоискПоСсылкам()
|
||
// - равен Истина для более быстрого поиска объектов, которые можно удалить. Результат возвращается в виде массива объектов для удаления.
|
||
|
||
//лСостояние("Поиск помеченных на удаление...");
|
||
// найдём помеченные на удаление
|
||
//Ссылки = НайтиПомеченныеНаУдаление();
|
||
|
||
ДатаНачала = ТекущаяДата();
|
||
// готовим таблицу найденных ссылок
|
||
Связи = Новый ТаблицаЗначений;
|
||
Связи.Колонки.Добавить("Ссылка");
|
||
Связи.Колонки.Добавить("Данные");
|
||
Связи.Колонки.Добавить("ОбъектСвязи", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100)));
|
||
|
||
// раскладываем ссылки по типам
|
||
Типы = Новый Соответствие;
|
||
Для каждого Ссылка из Ссылки Цикл
|
||
ТекущийТип = ТипЗнч(Ссылка);
|
||
СсылкиТипа = Типы[ТекущийТип];
|
||
Если СсылкиТипа = Неопределено Тогда
|
||
СсылкиТипа = Новый Массив;
|
||
Типы.Вставить(ТекущийТип,СсылкиТипа);
|
||
КонецЕсли;
|
||
СсылкиТипа.Добавить(Ссылка);
|
||
С = Связи.Добавить(); // начальное заполнение кандидатов
|
||
С.Ссылка = Ссылка;
|
||
С.Данные = Неопределено;
|
||
КонецЦикла;
|
||
|
||
Связи.Индексы.Добавить("Ссылка");
|
||
Связи.Индексы.Добавить("Ссылка,Данные");
|
||
//Если ДляУдаления Тогда
|
||
Связи.Индексы.Добавить("Данные");
|
||
//КонецЕсли;
|
||
|
||
//Регистраторы = Новый Соответствие; // будет таблица типов регистраторов для регистров. Ключ - имя регистра
|
||
ТаблицаВсехТаблиц = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс();
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаВсехТаблиц.Количество(), "Поиск ссылок по таблицам");
|
||
Для Каждого ОписаниеТаблицы Из ТаблицаВсехТаблиц Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
Если Ложь
|
||
Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ОписаниеТаблицы.Тип)
|
||
Или ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ОписаниеТаблицы.Тип)
|
||
Тогда
|
||
КлючевоеПоле = "Ссылка";
|
||
ИначеЕсли Ложь
|
||
Или ОписаниеТаблицы.Тип = "РегистрНакопления"
|
||
Или ОписаниеТаблицы.Тип = "РегистрРасчета"
|
||
Или ОписаниеТаблицы.Тип = "Последовательность"
|
||
//Или ОписаниеТаблицы.Тип = "Границы"
|
||
Тогда
|
||
КлючевоеПоле = "Регистратор";
|
||
ИначеЕсли Ложь
|
||
Или ОписаниеТаблицы.Тип = "Константа"
|
||
Тогда
|
||
КлючевоеПоле = "НЕОПРЕДЕЛЕНО";
|
||
ИначеЕсли Ложь
|
||
Или ОписаниеТаблицы.Тип = "Перерасчет"
|
||
Тогда
|
||
КлючевоеПоле = "ОбъектПерерасчета";
|
||
Иначе
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Реквизиты = Новый ТаблицаЗначений;
|
||
Реквизиты.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
|
||
Реквизиты.Колонки.Добавить("Тип");
|
||
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ОписаниеТаблицы.ПолноеИмя);
|
||
#Если Сервер И Не Сервер Тогда
|
||
ПоляТаблицыБД = НайтиПоСсылкам().Колонки;
|
||
#КонецЕсли
|
||
|
||
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
|
||
#Если Сервер И Не Сервер Тогда
|
||
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
|
||
Если Ложь
|
||
Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
|
||
Или ирОбщий.СтрокиРавныЛкс(ПолеТаблицыБД.Имя, КлючевоеПоле)
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Реквизит = Реквизиты.Добавить();
|
||
Реквизит.Имя = ПолеТаблицыБД.Имя;
|
||
Реквизит.Тип = ПолеТаблицыБД.ТипЗначения;
|
||
КонецЦикла;
|
||
#КонецЕсли
|
||
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
|
||
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл Если Ложь Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Или ирОбщий.СтрокиРавныЛкс(ПолеТаблицыБД.Имя, КлючевоеПоле) Тогда Продолжить; КонецЕсли; Реквизит = Реквизиты.Добавить(); Реквизит.Имя = ПолеТаблицыБД.Имя; Реквизит.Тип = ПолеТаблицыБД.ТипЗначения; КонецЦикла;
|
||
|
||
НайтиСсылкиВТаблице(ДляУдаления, Связи, Типы, ОписаниеТаблицы.ПолноеИмя, Реквизиты, КлючевоеПоле,, ОписаниеТаблицы.ПолноеИмя);
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
/////////////// документы
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.Документы.Количество(), "Документы");
|
||
//Для каждого Мета из Метаданные.Документы Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы); // что проверяем
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Мета.Реквизиты,"Ссылка");
|
||
// Для каждого ТЧ из Мета.ТабличныеЧасти Цикл
|
||
// ИмяТаблицы = Мета.ПолноеИмя()+"."+ТЧ.Имя;
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,ТЧ.Реквизиты,"Ссылка");
|
||
// КонецЦикла;
|
||
// // построим таблицу по регистрам какие регистраторы будут при сканировании документов
|
||
// //Для каждого Движение из Мета.Движения Цикл
|
||
// // ИмяРегистра = Движение.ПолноеИмя();
|
||
// // МассивТипов = Регистраторы[ИмяРегистра];
|
||
// // Если МассивТипов = Неопределено Тогда
|
||
// // МассивТипов = Новый Массив;
|
||
// // Регистраторы.Вставить(ИмяРегистра,МассивТипов);
|
||
// // КонецЕсли;
|
||
// // МассивТипов.Добавить(Тип(ТипСсылкаСтрокой(Мета)));
|
||
// //КонецЦикла;
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
//
|
||
///////////////// Планы видов расчета
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.ПланыВидовРасчета.Количество(), "Планы видов расчета");
|
||
//Для каждого Мета из Метаданные.ПланыВидовРасчета Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы); // что проверяем
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Мета.Реквизиты,"Ссылка");
|
||
// Для каждого ТЧ из Мета.ТабличныеЧасти Цикл
|
||
// ИмяТаблицы = Мета.ПолноеИмя()+"."+ТЧ.Имя;
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,ТЧ.Реквизиты,"Ссылка");
|
||
// КонецЦикла;
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
//
|
||
/////////////// планы видов характеристик
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.ПланыВидовХарактеристик.Количество(), "Планы видов характеристик");
|
||
//Для каждого Мета из Метаданные.ПланыВидовХарактеристик Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы); // что проверяем
|
||
// Если Мета.Иерархический Тогда
|
||
// Реквизиты = Новый Массив;
|
||
// Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Реквизиты.Добавить(Новый Структура("Имя,Тип","Родитель",Новый ОписаниеТипов(ТипСсылкаСтрокой(Мета))));
|
||
// Иначе
|
||
// Реквизиты = Мета.Реквизиты;
|
||
// КонецЕсли;
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Реквизиты,"Ссылка");
|
||
// Для каждого ТЧ из Мета.ТабличныеЧасти Цикл
|
||
// ИмяТаблицы = Мета.ПолноеИмя()+"."+ТЧ.Имя;
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,ТЧ.Реквизиты,"Ссылка");
|
||
// КонецЦикла;
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
//
|
||
/////////////// планы счетов
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.ПланыСчетов.Количество(), "Планы счетов");
|
||
//Для каждого Мета из Метаданные.ПланыСчетов Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы); // что проверяем
|
||
// Реквизиты = Новый Массив;
|
||
// Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Реквизиты.Добавить(Новый Структура("Имя,Тип","Родитель",Новый ОписаниеТипов(ТипСсылкаСтрокой(Мета))));
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Реквизиты,"Ссылка");
|
||
// Для каждого ТЧ из Мета.ТабличныеЧасти Цикл
|
||
// ИмяТаблицы = Мета.ПолноеИмя()+"."+ТЧ.Имя;
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,ТЧ.Реквизиты,"Ссылка");
|
||
// КонецЦикла;
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
//
|
||
///////////////// Бизнес-процессы
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.БизнесПроцессы.Количество(), "Бизнес-процессы");
|
||
//Для каждого Мета из Метаданные.БизнесПроцессы Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы); // что проверяем
|
||
// Реквизиты = Новый Массив;
|
||
// Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Реквизиты.Добавить(Новый Структура("Имя,Тип","ВедущаяЗадача",Задачи.ТипВсеСсылки()));
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Мета.Реквизиты,"Ссылка");
|
||
// Для каждого ТЧ из Мета.ТабличныеЧасти Цикл
|
||
// ИмяТаблицы = Мета.ПолноеИмя()+"."+ТЧ.Имя;
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,ТЧ.Реквизиты,"Ссылка");
|
||
// КонецЦикла;
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
//
|
||
///////////////// Задачи
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.Задачи.Количество(), "Задачи");
|
||
//Для каждого Мета из Метаданные.Задачи Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы); // что проверяем
|
||
// Реквизиты = Новый Массив;
|
||
// Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Для каждого Реквизит из Мета.РеквизитыАдресации Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Реквизиты.Добавить(Новый Структура("Имя,Тип","БизнесПроцесс",БизнесПроцессы.ТипВсеСсылки()));
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Мета.Реквизиты,"Ссылка");
|
||
// Для каждого ТЧ из Мета.ТабличныеЧасти Цикл
|
||
// ИмяТаблицы = Мета.ПолноеИмя()+"."+ТЧ.Имя;
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,ТЧ.Реквизиты,"Ссылка");
|
||
// КонецЦикла;
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
//
|
||
/////////////// справочники
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.Справочники.Количество(), "Справочники");
|
||
//Для каждого Мета из Метаданные.Справочники Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы); // что проверяем
|
||
// Если Мета.Иерархический ИЛИ Мета.Владельцы.Количество()>0 Тогда
|
||
// Реквизиты = Новый Массив;
|
||
// Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Если Мета.Иерархический Тогда // надо бы ещё проверить поле Родитель
|
||
// Реквизиты.Добавить(Новый Структура("Имя,Тип","Родитель",Новый ОписаниеТипов(ТипСсылкаСтрокой(Мета))));
|
||
// КонецЕсли;
|
||
// // надо бы еще поле Владелец проверить
|
||
// Если Мета.Владельцы.Количество()>0 Тогда
|
||
// ТипыВладельцев = Новый Массив;
|
||
// Для каждого Владелец Из Мета.Владельцы Цикл
|
||
// ТипыВладельцев.Добавить(Тип(ТипСсылкаСтрокой(Владелец)));
|
||
// КонецЦикла;
|
||
// Реквизиты.Добавить(Новый Структура("Имя,Тип","Владелец",Новый ОписаниеТипов(ТипыВладельцев)));
|
||
// КонецЕсли;
|
||
// Иначе
|
||
// Реквизиты = Мета.Реквизиты;
|
||
// КонецЕсли;
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Реквизиты,"Ссылка");
|
||
// Для каждого ТЧ из Мета.ТабличныеЧасти Цикл
|
||
// ИмяТаблицы = Мета.ПолноеИмя()+"."+ТЧ.Имя;
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,ТЧ.Реквизиты,"Ссылка");
|
||
// КонецЦикла;
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
//////////////////////////// Последовательности
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.Последовательности.Количество(), "Последовательности");
|
||
//ТаблицыКлючей = Новый Структура;
|
||
//Для каждого Мета из Метаданные.Последовательности Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Мета.Измерения,"Регистратор",,Мета);
|
||
// // надо поискать и в границах
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы+".Границы",Мета.Измерения,"Регистратор",,Мета);
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
////////////////////////// Регистры бухгалтерии
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.РегистрыБухгалтерии.Количество(), "Регистры бухгалтерии");
|
||
Для каждого Мета из Метаданные.РегистрыБухгалтерии Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
ИмяТаблицы = Мета.ПолноеИмя();
|
||
//лСостояниеПоиск(ИмяТаблицы);
|
||
// надо проверить по регистраторам для зависимых регистров
|
||
// для независимых будем ключ записи искать
|
||
Реквизиты = Новый Массив;
|
||
Для каждого Реквизит из Мета.Измерения Цикл
|
||
Если Мета.Корреспонденция И Не Реквизит.Балансовый Тогда
|
||
Реквизиты.Добавить(Новый Структура("Имя,Тип", Реквизит.Имя+"Кт", Реквизит.Тип));
|
||
Реквизиты.Добавить(Новый Структура("Имя,Тип", Реквизит.Имя+"Дт", Реквизит.Тип));
|
||
Иначе
|
||
Реквизиты.Добавить(Реквизит);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Для каждого Реквизит из Мета.Ресурсы Цикл
|
||
Если Мета.Корреспонденция И Не Реквизит.Балансовый Тогда
|
||
Реквизиты.Добавить(Новый Структура("Имя,Тип", Реквизит.Имя+"Кт", Реквизит.Тип));
|
||
Реквизиты.Добавить(Новый Структура("Имя,Тип", Реквизит.Имя+"Дт", Реквизит.Тип));
|
||
Иначе
|
||
Реквизиты.Добавить(Реквизит);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
Реквизиты.Добавить(Реквизит);
|
||
КонецЦикла;
|
||
ОписаниеТиповСсылки = Новый ОписаниеТипов(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Мета.ПланСчетов));
|
||
Если Мета.Корреспонденция Тогда
|
||
Реквизиты.Добавить(Новый Структура("Имя,Тип","СчетКт", ОписаниеТиповСсылки));
|
||
Реквизиты.Добавить(Новый Структура("Имя,Тип","СчетДт", ОписаниеТиповСсылки));
|
||
Иначе
|
||
Реквизиты.Добавить(Новый Структура("Имя,Тип","Счет", ОписаниеТиповСсылки));
|
||
КонецЕсли;
|
||
//Реквизиты.Добавить(Новый Структура("Имя,Тип","Регистратор",Новый ОписаниеТипов(Регистраторы[ИмяТаблицы])));
|
||
НайтиСсылкиВТаблице(ДляУдаления, Связи, Типы, ИмяТаблицы, Реквизиты, "Регистратор");
|
||
// надо поискать ещё в таблице субконто
|
||
НайтиСсылкиВТаблицеСубконто(ДляУдаления, Мета, Связи, Типы);
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
/////////// Регистры сведений
|
||
ТаблицыКлючей = Новый Структура;
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.РегистрыСведений.Количество(), "Регистры сведений");
|
||
Для каждого Мета из Метаданные.РегистрыСведений Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
ИмяТаблицы = Мета.ПолноеИмя();
|
||
//лСостояниеПоиск(ИмяТаблицы);
|
||
// надо проверить по регистраторам для зависимых регистров
|
||
// для независимых будем ключ записи искать
|
||
Реквизиты = Новый Массив;
|
||
Для каждого Реквизит из Мета.Измерения Цикл
|
||
// не будем проверять измерения со признаком "Ведущее", т.к. они должны автоматически удаляться при удалении объекта
|
||
Если Не (ДляУдаления И Реквизит.Ведущее) Тогда
|
||
Реквизиты.Добавить(Реквизит);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Для каждого Реквизит из Мета.Ресурсы Цикл
|
||
Реквизиты.Добавить(Реквизит);
|
||
КонецЦикла;
|
||
Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
Реквизиты.Добавить(Реквизит);
|
||
КонецЦикла;
|
||
Если Мета.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
|
||
ИмяСсылка = "Регистратор";
|
||
//Реквизиты.Добавить(Новый Структура("Имя,Тип","Регистратор",Новый ОписаниеТипов(Регистраторы[ИмяТаблицы])));
|
||
КлючиЗаписей = Неопределено;
|
||
Иначе
|
||
Если ДляУдаления Тогда
|
||
ИмяСсылка = "";
|
||
КлючиЗаписей = Истина;
|
||
Иначе
|
||
ИмяСсылка = Мета.Имя;
|
||
КлючиЗаписей = Новый ТаблицаЗначений;
|
||
ТаблицыКлючей.Вставить(Мета.Имя,КлючиЗаписей);
|
||
СтрокаИндекса = "";
|
||
// надо набор измерений основного отбора и период (если основной отбор по периоду) в качестве ключей
|
||
// как искать в связях? - надо будет ещё одну дополнительную таблицу для хранения ключей независимого регистра сведений
|
||
Если Мета.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
|
||
//Если Мета.ОсновнойОтборПоПериоду Тогда
|
||
ИмяПоля = "Период";
|
||
КлючиЗаписей.Колонки.Добавить(ИмяПоля,Новый ОписаниеТипов("Дата",,,Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
|
||
СтрокаИндекса = СтрокаИндекса + "," + ИмяПоля;
|
||
КонецЕсли;
|
||
Для каждого Измерение из Мета.Измерения Цикл
|
||
//Если Измерение.ОсновнойОтбор Тогда
|
||
ИмяПоля = Измерение.Имя;
|
||
КлючиЗаписей.Колонки.Добавить(ИмяПоля, Измерение.Тип);
|
||
СтрокаИндекса = СтрокаИндекса + "," + ИмяПоля;
|
||
//КонецЕсли;
|
||
КонецЦикла;
|
||
КлючиЗаписей.Индексы.Добавить(Сред(СтрокаИндекса, 2));
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Реквизиты,ИмяСсылка,КлючиЗаписей,Мета);
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
//////////////////////////// Регистры накопления
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.РегистрыНакопления.Количество(), "Регистры накопления");
|
||
//Для каждого Мета из Метаданные.РегистрыНакопления Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// // надо проверить по регистраторам для зависимых регистров
|
||
// // для независимых будем ключ записи искать
|
||
// Реквизиты = Новый Массив;
|
||
// Для каждого Реквизит из Мета.Измерения Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Для каждого Реквизит из Мета.Ресурсы Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// //Реквизиты.Добавить(Новый Структура("Имя,Тип","Регистратор",Новый ОписаниеТипов(Регистраторы[ИмяТаблицы])));
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Реквизиты,"Регистратор");
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
//////////////////////////// Регистры расчёта
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.РегистрыРасчета.Количество(), "Регистры расчета");
|
||
//Для каждого Мета из Метаданные.РегистрыРасчета Цикл
|
||
// ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
// ИмяТаблицы = Мета.ПолноеИмя();
|
||
// //лСостояниеПоиск(ИмяТаблицы);
|
||
// // надо проверить по регистраторам для зависимых регистров
|
||
// // для независимых будем ключ записи искать
|
||
// Реквизиты = Новый Массив;
|
||
// Для каждого Реквизит из Мета.Измерения Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Для каждого Реквизит из Мета.Ресурсы Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Для каждого Реквизит из Мета.Реквизиты Цикл
|
||
// Реквизиты.Добавить(Реквизит);
|
||
// КонецЦикла;
|
||
// Реквизиты.Добавить(Новый Структура("Имя,Тип","ВидРасчета",Новый ОписаниеТипов(ТипСсылкаСтрокой(Мета.ПланВидовРасчета))));
|
||
// //ОписаниеТиповРегистраторы = Новый ОписаниеТипов(Регистраторы[ИмяТаблицы]);
|
||
// //Реквизиты.Добавить(Новый Структура("Имя,Тип","Регистратор",ОписаниеТиповРегистраторы));
|
||
// НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяТаблицы,Реквизиты,"Регистратор");
|
||
// // перерасчеты тоже проверим
|
||
// //Для каждого Перерасчет из Мета.Перерасчеты Цикл
|
||
// // ИмяПерерасчета = ИмяТаблицы+"."+Перерасчет.Имя;
|
||
// // лСостояниеПоиск(ИмяПерерасчета);
|
||
// //
|
||
// // Реквизиты.Очистить();
|
||
// // Для каждого Реквизит из Перерасчет.Измерения Цикл
|
||
// // Реквизиты.Добавить(Мета.Измерения[Реквизит.Имя]);
|
||
// // КонецЦикла;
|
||
// // Реквизиты.Добавить(Новый Структура("Имя,Тип","ВидРасчета",Новый ОписаниеТипов(ТипСсылкаСтрокой(Мета.ПланВидовРасчета))));
|
||
// // Реквизиты.Добавить(Новый Структура("Имя,Тип","ОбъектПерерасчета",ОписаниеТиповРегистраторы));
|
||
// // НайтиСсылкиВТаблице(ДляУдаления,Связи,Типы,ИмяПерерасчета,Реквизиты,"Регистратор");
|
||
// //
|
||
// //КонецЦикла;
|
||
//КонецЦикла;
|
||
//ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
Если ДляУдаления Тогда
|
||
Связи.Свернуть("Ссылка");
|
||
лСостояние("Поиск закончен.");
|
||
Возврат Связи.ВыгрузитьКолонку("Ссылка");
|
||
Иначе
|
||
Строки = Связи.НайтиСтроки(Новый Структура("Данные",Неопределено));
|
||
Для каждого С из Строки Цикл
|
||
Связи.Удалить(С);
|
||
КонецЦикла;
|
||
// надо заменить ссылки на ключи независимых регистров сведений на сами ключи
|
||
ТипСтрока = Тип("Строка");
|
||
Связи.Колонки.Добавить("Метаданные");
|
||
Для каждого С из Связи Цикл
|
||
Если ТипЗнч(С.Данные) = ТипСтрока Тогда
|
||
// выделяем имя таблицы и номер строки из таблицы
|
||
Позиция = Найти(С.Данные,".");
|
||
ИмяРегистра = Лев(С.Данные,Позиция-1);
|
||
Если Позиция = СтрДлина(С.Данные) Тогда
|
||
НомерСтроки = 0;
|
||
Иначе
|
||
НомерСтроки = Число(Сред(С.Данные,Позиция+1));
|
||
КонецЕсли;
|
||
ТЗ = ТаблицыКлючей[ИмяРегистра];
|
||
СК = ТЗ[НомерСтроки];
|
||
Отбор = Новый Структура;
|
||
Для каждого Колонка из ТЗ.Колонки Цикл
|
||
Отбор.Вставить(Колонка.Имя,СК[Колонка.Имя]);
|
||
КонецЦикла;
|
||
С.Данные = РегистрыСведений[ИмяРегистра].СоздатьКлючЗаписи(Отбор);
|
||
С.Метаданные = Метаданные.РегистрыСведений[ИмяРегистра];
|
||
ИначеЕсли ТипЗнч(С.Данные)=Тип("ОбъектМетаданных") Тогда
|
||
С.Метаданные = С.Данные;
|
||
С.Данные = Неопределено;
|
||
Иначе
|
||
// бывает, что данные = Неопределено - тогда как найти метаданные?
|
||
С.Метаданные = С.Данные.Метаданные();
|
||
Если С.Данные = Неопределено Тогда
|
||
ВызватьИсключение "Невозможно установить поле Метаданные по значению Неопределено.";
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Длительность = ТекущаяДата() - ДатаНачала;
|
||
Если Длительность > 60 Тогда
|
||
Сообщить("Поиск ссылок выполнен за " + XMLСтрока(Длительность) + "с. Найдено " + XMLСтрока(Связи.Количество()) + " ссылок.");
|
||
КонецЕсли;
|
||
Возврат Связи;
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОбновитьДанныеКандидатов(ТаблицаОбъектов = Неопределено, МинимизироватьТипы = Истина, ДополнительноеПоле = "") Экспорт
|
||
|
||
Если ТаблицаОбъектов = Неопределено Тогда
|
||
ТаблицаОбъектов = УдаляемыеОбъекты.Выгрузить();
|
||
КонецЕсли;
|
||
Если МинимизироватьТипы Тогда
|
||
ТаблицаОбъектов = ирОбщий.ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(ТаблицаОбъектов); // Так будет меньше неявных соединений в запросе
|
||
КонецЕсли;
|
||
Запрос = Новый Запрос;
|
||
ТекстЗапроса = "
|
||
|ВЫБРАТЬ РАЗЛИЧНЫЕ * ПОМЕСТИТЬ ТЗ ИЗ &ТЗ КАК ТЗ;
|
||
|ВЫБРАТЬ ТЗ.Разрешен, ТЗ.Удаляется, ТЗ.НеудаляемыхСсылок, ТЗ.Ссылок, ТЗ.Метаданные, ТЗ.Ссылка, ЕСТЬNULL(ТЗ.Ссылка.ПометкаУдаления, ИСТИНА) КАК ПометкаУдаления,
|
||
|Представление(ТЗ.Ссылка) КАК Представление, ЕСТЬNULL(ТЗ.Ссылка.Предопределенный, Ложь) КАК Предопределенный,
|
||
|ВЫБОР КОГДА ЕСТЬNULL(ТЗ.Ссылка.ПометкаУдаления, ИСТИНА) ТОГДА 1 ИНАЧЕ 0 КОНЕЦ КАК ИндексКартинки ";
|
||
Если ЗначениеЗаполнено(ДополнительноеПоле) Тогда
|
||
ТекстЗапроса = ТекстЗапроса + "
|
||
|, ТЗ.Ссылка." + ДополнительноеПоле + " КАК " + ДополнительноеПоле;
|
||
КонецЕсли;
|
||
ТекстЗапроса = ТекстЗапроса + "
|
||
|ИЗ ТЗ КАК ТЗ";
|
||
Запрос.Текст = ТекстЗапроса;
|
||
Запрос.УстановитьПараметр("ТЗ", ТаблицаОбъектов);
|
||
|
||
// Проверяем наличие хотя бы одного типа с полем Предопределенный
|
||
ПроверочныйЗапрос = Новый ПостроительЗапроса;
|
||
ПроверочныйЗапрос.Текст = ирОбщий.ПолучитьЗапросИмитаторКоллекцииПолейЛкс(ТаблицаОбъектов.Колонки);
|
||
ПроверочныйЗапрос.ЗаполнитьНастройки();
|
||
Если ПроверочныйЗапрос.ДоступныеПоля.Ссылка.Поля.Найти("Предопределенный") = Неопределено Тогда
|
||
Запрос.Текст = СтрЗаменить(Запрос.Текст, "ТЗ.Ссылка.Предопределенный", "Ложь");
|
||
КонецЕсли;
|
||
// Может происходить ошибка платформы 8.3.10 "Несовместимые типы" https://partners.v8.1c.ru/forum/t/1617826/m/1617826
|
||
// Если она произошла, то попробуйте обрабатывать кандидатов мелкими порциями
|
||
ТаблицаОбъектов = Запрос.Выполнить().Выгрузить();
|
||
Возврат ТаблицаОбъектов;
|
||
|
||
КонецФункции
|
||
|
||
// Выполняет поиск ссылок на помеченные на удаление объекты,
|
||
// заполняет ими таблицу значений "ТаблицаСсылок",
|
||
// производит контроль на возможность удаления
|
||
//
|
||
// Результат - Булево - нужно ли выполнять повторный контроль
|
||
Функция КонтролироватьСсылкиНаКандидаты(ЭтаФорма = Неопределено, Пустышка = Ложь, выхДобавленыКандидаты = Ложь) Экспорт
|
||
|
||
выхДобавленыКандидаты = Ложь;
|
||
МассивКУдалению = Новый Массив;
|
||
Для Каждого СтрокаУдаляемогоОбъекта из УдаляемыеОбъекты Цикл
|
||
Если СтрокаУдаляемогоОбъекта.Разрешен Тогда
|
||
МассивКУдалению.Добавить(СтрокаУдаляемогоОбъекта.Ссылка);
|
||
СтрокаУдаляемогоОбъекта.Удаляется = Истина;
|
||
Иначе
|
||
СтрокаУдаляемогоОбъекта.Удаляется = Ложь;
|
||
КонецЕсли;
|
||
СтрокаУдаляемогоОбъекта.НеУдаляемыхСсылок = 0;
|
||
СтрокаУдаляемогоОбъекта.Ссылок = 0;
|
||
КонецЦикла;
|
||
СсылкиНаКандидата.Очистить();
|
||
Если СтандартныйПоискСсылок Тогда
|
||
ТаблицаСсылок = НайтиПоСсылкам(МассивКУдалению);
|
||
ирОбщий.ПеревестиКолонкиНайтиПоСсылкамЛкс(ТаблицаСсылок);
|
||
Иначе
|
||
ТаблицаСсылок = НайтиСсылки(МассивКУдалению, Ложь);
|
||
КонецЕсли;
|
||
ТаблицаСсылок.Колонки.Добавить("КлючЗаписиРегистраСведений");
|
||
ДатаНачала = ТекущаяДата();
|
||
ТаблицаСсылок.Колонки.Добавить("СсылкаДанного");
|
||
ТаблицаСсылок.Колонки.Добавить("Удаляется");
|
||
Для Каждого МетаРеквизит Из Метаданные().ТабличныеЧасти.СсылкиНаКандидата.Реквизиты Цикл
|
||
Если ТаблицаСсылок.Колонки.Найти(МетаРеквизит.Имя) = Неопределено Тогда
|
||
ТаблицаСсылок.Колонки.Добавить(МетаРеквизит.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
МассивДобавляемыхКандидатов = Новый Массив;
|
||
СоответствиеСсылокЧтенияПометкиУдаления = Новый Соответствие;
|
||
СоответствиеТиповЧтенияПометкиУдаления = Новый Соответствие;
|
||
// Для поиска строк ТЧ по ссыке будем использовать соотвествие
|
||
СоответствиеКандидатов = Новый Соответствие;
|
||
Для Каждого СтрокаКандидата Из УдаляемыеОбъекты Цикл
|
||
СоответствиеКандидатов[СтрокаКандидата.Ссылка] = СтрокаКандидата;
|
||
КонецЦикла;
|
||
ПредставлениеПроцесса = "Анализ ссылающихся объектов";
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
Индикатор = мСервисныйПроцессор.ПолучитьИндикаторПроцесса(ТаблицаСсылок.Количество(), ПредставлениеПроцесса);
|
||
Иначе
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаСсылок.Количество(), ПредставлениеПроцесса);
|
||
КонецЕсли;
|
||
Для каждого ЭлементТаблицыСсылок из ТаблицаСсылок Цикл
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
мСервисныйПроцессор.ОбновитьИндикатор(Индикатор);
|
||
Иначе
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
КонецЕсли;
|
||
Ссылка = ЭлементТаблицыСсылок.ссылка;
|
||
Данные = ЭлементТаблицыСсылок.Данные;
|
||
//СтрокаСсылки = ТаблицаКандидатов.Найти(Ссылка, "Ссылка");
|
||
СтрокаКандидатаСсылки = СоответствиеКандидатов[Ссылка];
|
||
МетаданныеДанных = ЭлементТаблицыСсылок.Метаданные;
|
||
ИмяМетаданных = МетаданныеДанных.ПолноеИмя();
|
||
ЭтоРегистрСведений = ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ирОбщий.ПолучитьПервыйФрагментЛкс(ИмяМетаданных));
|
||
Если ЭтоРегистрСведений Тогда
|
||
ЭлементТаблицыСсылок.КлючЗаписиРегистраСведений = ЭлементТаблицыСсылок.Данные;
|
||
ИзмеренияРегистраСведений = МетаданныеДанных.Измерения;
|
||
УдаляетсяРегистрСведений = Ложь;
|
||
Для Каждого Измерение Из ИзмеренияРегистраСведений Цикл
|
||
Если Измерение.Ведущее Тогда
|
||
Если Ссылка = Данные[Измерение.Имя] Тогда
|
||
УдаляетсяРегистрСведений = Истина;
|
||
ЭлементТаблицыСсылок.Данные = Ссылка;
|
||
Данные = ссылка;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если Не УдаляетсяРегистрСведений Тогда
|
||
ЭлементТаблицыСсылок.Данные = Неопределено;
|
||
Данные = Неопределено;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
СтрокаНеблокирующегоТипа = НеблокирующиеТипы.Найти(ИмяМетаданных, "Метаданные");
|
||
Если Данные = Неопределено Тогда
|
||
ЭлементТаблицыСсылок.ИндексКартинки = 3;
|
||
СтрокаКандидатаОбъектаСодержащегоСсылку = Неопределено;
|
||
Иначе
|
||
Если ТипЗнч(Данные) = Тип("Строка") Тогда
|
||
СтрокаКандидатаОбъектаСодержащегоСсылку = Неопределено;
|
||
ИначеЕсли Данные = Ссылка Тогда
|
||
СтрокаКандидатаОбъектаСодержащегоСсылку = СтрокаКандидатаСсылки;
|
||
Иначе
|
||
//СтрокаДанного = ТаблицаКандидатов.Найти(Данные, "Ссылка");
|
||
СтрокаКандидатаОбъектаСодержащегоСсылку = СоответствиеКандидатов[Данные];
|
||
КонецЕсли;
|
||
Если СтрокаНеблокирующегоТипа <> Неопределено И Не СтрокаНеблокирующегоТипа.Игнорировать Тогда
|
||
МассивДобавляемыхКандидатов.Добавить(Данные);
|
||
КонецЕсли;
|
||
СоответствиеСсылокЧтенияПометкиУдаления[Данные] = 1;
|
||
СоответствиеТиповЧтенияПометкиУдаления[ТипЗнч(Данные)] = 1;
|
||
КонецЕсли;
|
||
СтрокаКандидатаСсылки.Ссылок = СтрокаКандидатаСсылки.Ссылок + 1;
|
||
УдаляетсяСсылка = СтрокаКандидатаСсылки.Удаляется;
|
||
Если СтрокаКандидатаОбъектаСодержащегоСсылку = Неопределено Тогда
|
||
Если Ложь
|
||
//Или ЭтоРегистрСведений
|
||
Или СтрокаНеблокирующегоТипа <> Неопределено
|
||
Тогда
|
||
УдаляетсяОбъектСодержащийСсылку = Истина;
|
||
Иначе
|
||
УдаляетсяОбъектСодержащийСсылку = Ложь;
|
||
Если УдаляетсяСсылка Тогда
|
||
СтрокаКандидатаСсылки.Удаляется = Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Иначе
|
||
Если СтрокаКандидатаОбъектаСодержащегоСсылку.Ссылка = Ссылка Тогда
|
||
УдаляетсяОбъектСодержащийСсылку = СтрокаКандидатаОбъектаСодержащегоСсылку.Разрешен;
|
||
Иначе
|
||
УдаляетсяОбъектСодержащийСсылку = СтрокаКандидатаОбъектаСодержащегоСсылку.Удаляется;
|
||
КонецЕсли;
|
||
Если Не УдаляетсяОбъектСодержащийСсылку Тогда
|
||
Если УдаляетсяСсылка Тогда
|
||
СтрокаКандидатаСсылки.Удаляется = ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если УдаляетсяОбъектСодержащийСсылку = ложь Тогда
|
||
СтрокаКандидатаСсылки.НеУдаляемыхСсылок = СтрокаКандидатаСсылки.НеУдаляемыхСсылок + 1;
|
||
КонецЕсли;
|
||
ЭлементТаблицыСсылок.Удаляется = УдаляетсяОбъектСодержащийСсылку;
|
||
Если Данные <> ЭлементТаблицыСсылок.Данные Тогда // Для ускорения
|
||
ЭлементТаблицыСсылок.СсылкаДанного = Данные;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
мСервисныйПроцессор.ОсвободитьИндикаторПроцесса(Индикатор);
|
||
Иначе
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс(Индикатор);
|
||
КонецЕсли;
|
||
Если МассивДобавляемыхКандидатов.Количество() > 0 Тогда
|
||
Если ДобавитьМассивОбъектовВУдаляемыеОбъекты(МассивДобавляемыхКандидатов) Тогда
|
||
Сообщить("Состав кандидатов на удаление был дополнен. Рекомендуется выполнить контроль заново");
|
||
выхДобавленыКандидаты = Истина;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если СоответствиеТиповЧтенияПометкиУдаления.Количество() > 0 Тогда
|
||
МассивТиповКолонки = Новый Массив;
|
||
Для Каждого КлючИЗначение Из СоответствиеТиповЧтенияПометкиУдаления Цикл
|
||
МассивТиповКолонки.Добавить(КлючИЗначение.Ключ);
|
||
КонецЦикла;
|
||
ТаблицаЧтенияПометкиУдаления = УдаляемыеОбъекты.ВыгрузитьКолонки();
|
||
ТаблицаЧтенияПометкиУдаления.Колонки.Удалить("Ссылка");
|
||
ТаблицаЧтенияПометкиУдаления.Колонки.Добавить("Ссылка", Новый ОписаниеТипов(МассивТиповКолонки));
|
||
Для Каждого КлючИЗначение Из СоответствиеСсылокЧтенияПометкиУдаления Цикл
|
||
СтрокаОбъекта = ТаблицаЧтенияПометкиУдаления.Добавить();
|
||
СтрокаОбъекта.Ссылка = КлючИЗначение.Ключ;
|
||
КонецЦикла;
|
||
СчитанныеПометки = ОбновитьДанныеКандидатов(ТаблицаЧтенияПометкиУдаления, Ложь);
|
||
|
||
ПредставлениеПроцесса = "Заполнение пометок на удаление";
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
Индикатор = мСервисныйПроцессор.ПолучитьИндикаторПроцесса(СчитанныеПометки.Количество(), ПредставлениеПроцесса);
|
||
Иначе
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СчитанныеПометки.Количество(), ПредставлениеПроцесса);
|
||
КонецЕсли;
|
||
Для Каждого СтрокаСчитаннойПометки Из СчитанныеПометки Цикл
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
мСервисныйПроцессор.ОбновитьИндикатор(Индикатор);
|
||
Иначе
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
КонецЕсли;
|
||
СтрокиСсылающегося = ТаблицаСсылок.НайтиСтроки(Новый Структура("Данные", СтрокаСчитаннойПометки.Ссылка));
|
||
Для Каждого СтрокаСсылающегося Из СтрокиСсылающегося Цикл
|
||
СтрокаСсылающегося.ИндексКартинки = ?(СтрокаСчитаннойПометки.ПометкаУдаления, 4, 3); // В конце будем более подробно вычислять состояние
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
мСервисныйПроцессор.ОсвободитьИндикаторПроцесса(Индикатор);
|
||
Иначе
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс(Индикатор);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
НашлиДляИсключения = Истина;
|
||
Пока НашлиДляИсключения Цикл
|
||
НашлиДляИсключения = Ложь;
|
||
Для каждого ЭлементТаблицыСсылок из ТаблицаСсылок Цикл
|
||
СсылкаОбъектаСодержащегоСсылку = ЭлементТаблицыСсылок.СсылкаДанного;
|
||
Если СсылкаОбъектаСодержащегоСсылку = Неопределено Тогда
|
||
СсылкаОбъектаСодержащегоСсылку = ЭлементТаблицыСсылок.Данные;
|
||
КонецЕсли;
|
||
СтрокаКандидатаОбъектаСодержащегоСсылку = СоответствиеКандидатов[СсылкаОбъектаСодержащегоСсылку];
|
||
Если СтрокаКандидатаОбъектаСодержащегоСсылку <> Неопределено Тогда
|
||
УдаляетсяОбъектСодержащийСсылку = СтрокаКандидатаОбъектаСодержащегоСсылку.Удаляется;
|
||
УдаляетсяСсылающаясяСтрокаТаблицыБД = ЭлементТаблицыСсылок.Удаляется;
|
||
СтрокаКандидатаСсылки = СоответствиеКандидатов[ЭлементТаблицыСсылок.Ссылка];
|
||
УдаляетсяСсылка = СтрокаКандидатаСсылки.Удаляется;
|
||
Если УдаляетсяСсылающаясяСтрокаТаблицыБД И Не УдаляетсяОбъектСодержащийСсылку И СсылкаОбъектаСодержащегоСсылку <> Ссылка Тогда
|
||
ЭлементТаблицыСсылок.Удаляется = Ложь;
|
||
СтрокаКандидатаСсылки.НеУдаляемыхСсылок = СтрокаКандидатаСсылки.НеУдаляемыхСсылок + 1;
|
||
КонецЕсли;
|
||
Если УдаляетсяСсылка И Не УдаляетсяОбъектСодержащийСсылку Тогда
|
||
СтрокаКандидатаСсылки.Удаляется = Ложь;
|
||
НашлиДляИсключения = Истина;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
Длительность = ТекущаяДата() - ДатаНачала;
|
||
Если Длительность > 60 Тогда
|
||
Сообщить("Анализ найденных ссылок выполнен за " + XMLСтрока(Длительность) + "с.");
|
||
КонецЕсли;
|
||
Возврат ТаблицаСсылок;
|
||
|
||
КонецФункции
|
||
|
||
// Выполняет удаление помеченные объектов, которые возможно удалить
|
||
// В платформе есть похожий метод УдалитьОбъекты
|
||
//
|
||
Процедура УдалитьОбъектыЛкс(ТаблицаСсылок = Неопределено) Экспорт
|
||
вСообщить("---------------------- Удаление объектов -----------------------",);
|
||
Удалено = 0;
|
||
НеУдалено = 0;
|
||
Проход = 1;
|
||
Индикатор = Неопределено;
|
||
Обработанные = Новый Соответствие;
|
||
// Нужно минимизировать длительность транзакций. Поэтому на первых проходах удаляем только элементы без потомков
|
||
Пока Истина Цикл
|
||
СтруктураОтбора = Новый Структура;
|
||
СтруктураОтбора.Вставить("Удаляется", Истина);
|
||
ТаблицаУдаляемых = УдаляемыеОбъекты.Выгрузить(СтруктураОтбора);
|
||
Если Индикатор = Неопределено Тогда
|
||
ПредставлениеПроцесса = "Удаление";
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
Индикатор = мСервисныйПроцессор.ПолучитьИндикаторПроцесса(ТаблицаУдаляемых.Количество(), ПредставлениеПроцесса);
|
||
Иначе
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаУдаляемых.Количество(), ПредставлениеПроцесса);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ТаблицаСсылокСРодителями = ТаблицаУдаляемых.СкопироватьКолонки();
|
||
НачальноеКоличество = ТаблицаУдаляемых.Количество();
|
||
Для СчетчикТаблицаУдаляемых = 1 По НачальноеКоличество Цикл
|
||
СтрокаУдаляемого = ТаблицаУдаляемых[НачальноеКоличество - СчетчикТаблицаУдаляемых];
|
||
Если Истина
|
||
И Обработанные[СтрокаУдаляемого.Ссылка] = Неопределено
|
||
И ирОбщий.ЛиМетаданныеИерархическогоОбъектаЛкс(Метаданные.НайтиПоПолномуИмени(СтрокаУдаляемого.Метаданные))
|
||
Тогда
|
||
ЗаполнитьЗначенияСвойств(ТаблицаСсылокСРодителями.Добавить(), СтрокаУдаляемого);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если ТаблицаСсылокСРодителями.Количество() = 0 Тогда
|
||
МассивУдаляемых = Новый Массив;
|
||
Иначе
|
||
ТаблицаСсылокСРодителями = ОбновитьДанныеКандидатов(ТаблицаСсылокСРодителями,, "Родитель");
|
||
ТаблицаСсылокСРодителями.Колонки.Добавить("ЭтоЭлементБезПотомков");
|
||
ТаблицаСсылокСРодителями.Индексы.Добавить("Родитель");
|
||
Для Каждого СтрокаУдаляемого Из ТаблицаСсылокСРодителями Цикл
|
||
СтрокаУдаляемого.ЭтоЭлементБезПотомков = ТаблицаСсылокСРодителями.Найти(СтрокаУдаляемого.Ссылка, "Родитель") = Неопределено;
|
||
КонецЦикла;
|
||
МассивУдаляемых = ТаблицаСсылокСРодителями.Скопировать(Новый Структура("ЭтоЭлементБезПотомков", Истина));
|
||
КонецЕсли;
|
||
Если МассивУдаляемых.Количество() = 0 Тогда
|
||
МассивУдаляемых = ТаблицаУдаляемых;
|
||
КонецЕсли;
|
||
СтруктураОтбора.Очистить();
|
||
Для Каждого СтрокаУдаляемогоОбъекта из МассивУдаляемых Цикл
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
мСервисныйПроцессор.ОбновитьИндикатор(Индикатор);
|
||
Иначе
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
КонецЕсли;
|
||
Ссылка = СтрокаУдаляемогоОбъекта.Ссылка;
|
||
ОбъектМД = Ссылка.Метаданные();
|
||
//Представление = "" + СтрокаУдаляемогоОбъекта.Ссылка;
|
||
//Объект = Ссылка.ПолучитьОбъект();
|
||
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ОбъектМД.ПолноеИмя(), Ссылка);
|
||
Попытка
|
||
Если Истина
|
||
И СтруктураОбъекта.Методы <> Неопределено
|
||
И Не СтруктураОбъекта.Методы.ЭтоНовый()
|
||
Тогда
|
||
ирОбщий.УдалитьОбъектЛкс(СтруктураОбъекта.Методы);
|
||
ИначеЕсли ирОбщий.ЛиКорневойТипДокументаЛкс(ирОбщий.ПолучитьПервыйФрагментЛкс(СтрокаУдаляемогоОбъекта.Метаданные)) Тогда
|
||
ирОбщий.ОчиститьДвиженияДокументаЛкс(Ссылка, Истина, Истина);
|
||
КонецЕсли;
|
||
Если ВыводитьСообщения Тогда
|
||
Сообщить("Удален объект: " + СокрЛП(СтрокаУдаляемогоОбъекта.Метаданные) + ": " + СтрокаУдаляемогоОбъекта.Представление, СтатусСообщения.Информация);
|
||
КонецЕсли;
|
||
УдаляемыеОбъекты.Удалить(УдаляемыеОбъекты.Найти(Ссылка, "Ссылка"));
|
||
Если ТаблицаСсылок <> Неопределено Тогда
|
||
СтруктураОтбора.Вставить("Ссылка", Ссылка);
|
||
МассивСсылок = ТаблицаСсылок.НайтиСтроки(СтруктураОтбора);
|
||
Для Каждого СтрокаСсылки из МассивСсылок Цикл
|
||
ТаблицаСсылок.Удалить(СтрокаСсылки);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Удалено = Удалено + 1;
|
||
Исключение
|
||
Обработанные[Ссылка] = 1;
|
||
вСообщить("Не удален объект: " + СокрЛП(СтрокаУдаляемогоОбъекта.Метаданные) + ": " + СтрокаУдаляемогоОбъекта.Представление, СтатусСообщения.Важное);
|
||
вСообщить(" " + ОписаниеОшибки(), СтатусСообщения.Важное);
|
||
НеУдалено = НеУдалено + 1;
|
||
КонецПопытки;
|
||
КонецЦикла;
|
||
Если МассивУдаляемых = ТаблицаУдаляемых Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
Проход = Проход + 1;
|
||
КонецЦикла;
|
||
Если мСервисныйПроцессор <> Неопределено Тогда
|
||
мСервисныйПроцессор.ОсвободитьИндикаторПроцесса(Индикатор, Истина);
|
||
Иначе
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс(Индикатор, Истина);
|
||
КонецЕсли;
|
||
вСообщить("Удаление объектов закончено. Удалено объектов: " + Удалено
|
||
+ ?(НеУдалено <> 0, " Не удалено объектов : " + НеУдалено, ""),);
|
||
|
||
КонецПроцедуры
|
||
|
||
//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
|
||
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
|
||
//ирПортативный #Если Клиент Тогда
|
||
//ирПортативный Контейнер = Новый Структура();
|
||
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
|
||
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
|
||
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
|
||
//ирПортативный ирПортативный.Открыть();
|
||
//ирПортативный КонецЕсли;
|
||
//ирПортативный #Иначе
|
||
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
|
||
//ирПортативный #КонецЕсли
|
||
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
|
||
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
|
||
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
|
||
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");
|
||
|
||
ЭтотОбъект.ВыполнятьНаСервере = ирОбщий.ПолучитьРежимОбъектыНаСервереПоУмолчаниюЛкс(Ложь);
|