Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Правильное удаление группы в справочнике Номенклатура  (Прочитано 14647 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
regAlex2
Гость
« : 21-12-2009 09:56 » 

Помогите, пожалуйста, создать внешнюю обработку правильного удаления выбранной группы справочника Номенклатуры, если есть ссылки на удаляемые объекты - то их тоже удалить, и у них тоже......

Комплексная конфигурация "Бухгалтерия+Торговля+Склад+Зарплата+Кадры", редакция 4.5
Данные в .dbf


У меня пока что не удается рекурсия и помечает только часть:


Код:

//ВыбНоменклатура - удаляеммая группа
Процедура СсылкиНаСсылки(Удал1, н1) Далее

//*******************************************
Процедура Сформировать() //начало

СсылкиНаСсылки(ВыбНоменклатура, 1);

Сообщить("Готово");
КонецПроцедуры
 

//н1 - счетчик
//Удал1 = Удаляемый объект
Процедура СсылкиНаСсылки(Удал1, н1)


//Помечает на удаление объекты выбранного справочника Номенклатуры и передает в СпНом
СпНом = СоздатьОбъект("СписокЗначений");
СпрНом = СоздатьОбъект("Справочник.Номенклатура");

СпрНом.ВыбратьЭлементы();
Пока СпрНом.ПолучитьЭлемент() = 1 Цикл
Если СпрНом.ТекущийЭлемент() = Удал1 Тогда
СпрНом.Удалить(0);
    СпНом.ДобавитьЗначение(СпрНом.ТекущийЭлемент());
КонецЕсли;
КонецЦикла;

//Удаление выб. Номенклатуры, если есть ссылки на них - не удаляются, а ссылки в ТЗ
ТЗ = СоздатьОбъект("ТаблицаЗначений");
УдалитьОбъекты (СпНом, 1, ТЗ);



//ссылки на справочники и документы помечаем на удаление
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл

Объект = ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки,"Ссылка");
    ТипОбъекта = ТипЗначенияСтр(Объект);
    ВидОбъекта = Объект.Вид();
    ВремОбъект = СоздатьОбъект(ТипОбъекта+"."+ВидОбъекта);
    Если ТипОбъекта = "Справочник" Тогда
        Элем=ВремОбъект.НайтиЭлемент(Объект);
        ВремОбъект.Удалить(0); //помечаем на удаление
н1=н1+1;
СсылкиНаСсылки(ВремОбъект, 1);
    ИначеЕсли ТипОбъекта = "Документ" Тогда
        Докум=ВремОбъект.НайтиДокумент(Объект);
        ВремОбъект.Удалить(0);
н1=н1+1;
СсылкиНаСсылки(ВремОбъект, 1);
КонецЕсли;
Сообщить(н1);
КонецЦикла;

Сообщить("КонецОбхода");
КонецПроцедуры


Записан
Kivals
Модератор

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 21-12-2009 17:45 » 

Структурировность кода на низком уровне - читать тяжело. Отсюда следствие - желания разбираться нет. Облагородь код для начала.
И еще  - почитай про функцию НайтиСсылки() в синтакс-помощнике
Записан
regAlex2
Гость
« Ответ #2 : 22-12-2009 07:18 » 

Вот более понятный, без пробования рекурсии, код:

Код:

Процедура Сформировать()

//Помечает на удаление объекты выбранного справочника Номенклатуры и передает в СпНом
СпНом = СоздатьОбъект("СписокЗначений");
СпрНом = СоздатьОбъект("Справочник.Номенклатура");
СпрНом.ИспользоватьРодителя(ВыбНоменклатура);  //ВыбНоменклатура - группа из которой надо все удалить
СпрНом.ВыбратьЭлементы();
Пока СпрНом.ПолучитьЭлемент() = 1 Цикл
СпрНом.Удалить(0);
        СпНом.ДобавитьЗначение(СпрНом.ТекущийЭлемент());
КонецЦикла;

//Удаление выб. Номенклатуры, если есть ссылки на них - не удаляются, а ссылки в ТЗ
ТЗ = СоздатьОбъект("ТаблицаЗначений");
УдалитьОбъекты (СпНом, 1, ТЗ);


//ссылки на справочники и документы помечаем на удаление
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл

    Объект = ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки,"Ссылка");

//Определяем какой объект получен и создаем нужный
    ТипОбъекта = ТипЗначенияСтр(Объект);
    ВидОбъекта = Объект.Вид();
    ВремОбъект = СоздатьОбъект(ТипОбъекта+"."+ВидОбъекта);

//Помечаем на удаление
    Если ТипОбъекта = "Справочник" Тогда
        Элем=ВремОбъект.НайтиЭлемент(Объект);
        ВремОбъект.Удалить(0); //помечаем на удаление
    ИначеЕсли ТипОбъекта = "Документ" Тогда
        Докум=ВремОбъект.НайтиДокумент(Объект);
        ВремОбъект.Удалить(0);
    КонецЕсли;

КонецЦикла;


Сообщить("Готово");

КонецПроцедуры

Записан
regAlex2
Гость
« Ответ #3 : 22-12-2009 09:17 » 

Счас заметил что как минимум часть помеченных не удаляется из-за того что хоть и помечены, но ссылаются друг на друга.
Как модернезировать, чтобы такие сразу удалялись?
Записан
Dest
Опытный

ru
Offline Offline

« Ответ #4 : 22-12-2009 12:19 » 

Непосредственное удаление

Код:
СпрНом.Удалить(1);
Записан
Kivals
Модератор

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 22-12-2009 12:26 » 

ИМХО без рекурсии здесь никак. (Ну т.е. можно - по теории любая рекурсия раскладывается в цикл, но менее наглядно)
Опасно удалять сразу. Например: А ссылается на Б, Б ссылается на А, но кроме того С также ссылается на А
Помоему лучше вызывать УдалитьОбъекты() до тех пор, пока не вернет пустую ТЗ.
Вызвали УдалитьОбъекты(), если ТЗ не пустая и объект не помечен на цдаление - пометили на удаление, добавили объект в список и опять вызвали УдалитьОбъекты(). Еще нужно условие выхода по "не увеличению" списка - спастись от зацикливания.

Хм. Хотя вроде получилось и через цикл вполне приемлимо Улыбаюсь
Записан
regAlex2
Гость
« Ответ #6 : 23-12-2009 07:40 » 

ИМХО без рекурсии здесь никак. (Ну т.е. можно - по теории любая рекурсия раскладывается в цикл, но менее наглядно)
Опасно удалять сразу. Например: А ссылается на Б, Б ссылается на А, но кроме того С также ссылается на А
Помоему лучше вызывать УдалитьОбъекты() до тех пор, пока не вернет пустую ТЗ.
Вызвали УдалитьОбъекты(), если ТЗ не пустая и объект не помечен на цдаление - пометили на удаление, добавили объект в список и опять вызвали УдалитьОбъекты(). Еще нужно условие выхода по "не увеличению" списка - спастись от зацикливания.


Помоги, пожалуйста, реализовать. Я лично застрял.
Продвинулся только замены кода вверху строк:

Код:
СсылкиНаСсылки(ВремОбъект, 1);

На

Код:
СсылкиНаСсылки(Объект, н1);

Результат: Стал работать дольше , счетчик н1 показал в 4 раза больше обходов.
Но все равно не хочет удалять все вложенные (а также вложенных (и т.д.) ) зависимости. А также не решил проблемы ссылки друг на друга.

Хм. Хотя вроде получилось и через цикл вполне приемлимо Улыбаюсь

Хоть что-то удалось...
Записан
Kivals
Модератор

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 23-12-2009 09:57 » 

Вызвали УдалитьОбъекты(), если ТЗ не пустая и объект не помечен на цдаление - пометили на удаление, добавили объект в список и опять вызвали УдалитьОбъекты(). Еще нужно условие выхода по "не увеличению" списка - спастись от зацикливания.
А где код, который это делает?
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines