Имя: Пароль:
1C
1C 7.7
v7: Использование НайтиСсылки. Ошибка.
0 unknown181538
 
14.07.11
19:52
Вот в эту процедуру передаются данные справочника порциями (т.к. при передаче в НайтиСсылки справочника целиком, платформа падала) по 2000.
Код выполняется некоторое количество раз (например 14) и программа закрывается с ошибкой.
Что можно предпринять?

Процедура ОбработатьСписок(Список,ТаблицаСоотв,Вид,ТаблицаОстатков = "")
   
   //НачатьТранзакцию();
   ТЗ = СоздатьОбъект("ТаблицаЗначений");
   Состояние("Поиск ссылок....");
   НайтиСсылки(Список,ТЗ);
   Состояние("Сортировка...");
   Если ТЗ.КоличествоСтрок()>0 Тогда
       ТЗ.Сортировать("1");    
       //ТЗ.ВыбратьСтроку();
   КонецЕсли;
   ТЗ.ВыбратьСтроки();
   ТекОбъект = "";
   ПредОбъект = "";
   НомСтр = 0;
   Оставить = 0;
   Спр = СоздатьОбъект("Справочник.СерииДисконтКарт");
   Спр.НайтиПоКоду("4");
   Серия1 = Спр.ТекущийЭлемент();
   Спр = СоздатьОбъект("Справочник.СерииДисконтКарт");
   Спр.НайтиПоКоду("5");
   Серия2 = Спр.ТекущийЭлемент();
   Состояние("Обход таблицы....");  
   //Для А=1 По 4 Цикл
       Пока ТЗ.ПолучитьСтроку()=1 Цикл
           НомСтр = НомСтр + 1;
           ТекОбъект = ТЗ.ПолучитьЗначение(НомСтр,1);
           ТаблицаСоотв.НоваяСтрока();
           ТаблицаСоотв.Объект = ТекОбъект;
           ТаблицаСоотв.ЕстьСсылки = 1;
           //Если ПредОбъект<>"" Тогда
           //    Если ТекОбъект<>ПредОбъект Тогда
           //        Если Оставить=0 Тогда  
           //            СпрОбъект = СоздатьОбъект("Справочник."+Вид);
           //            СпрОбъект.НайтиЭлемент(ПредОбъект);
           //            СпрОбъект.Удалить(0);
           //            Состояние("Помечен "+СпрОбъект);
           //            СпрОбъект.Наименование = СпрОбъект.Наименование + " - [[устарел]]";
           //            СпрОбъект.Записать();
           //            ИтогоПомеченоНом=ИтогоПомеченоНом+1;
           //        КонецЕсли;
           //        Оставить = 0;
           //    КонецЕсли;
           //КонецЕсли;
           ОбСсыл = ТЗ.ПолучитьЗначение(НомСтр,2);
           Если ТипЗначения(ОбСсыл)=12 Тогда
               Если (ОбСсыл.ДатаДок>=МинДата)И(ОбСсыл.ПометкаУдаления()=0) Тогда
                   Оставить = 1;  
                   ТаблицаСоотв.НоваяСтрока();
                   ТаблицаСоотв.Объект = ТекОбъект;
                   ТаблицаСоотв.Оставить = 1;
               КонецЕсли;
           КонецЕсли;
           Если Вид = "Контрагенты" Тогда
               Если ПустоеЗначение(ТекОбъект.ДисконтКарта)=0 Тогда
                   Владелец = ТекОбъект.ДисконтКарта.Получить(РабочаяДата()).Владелец;
                   Если (Владелец = Серия1) или (Владелец = Серия2) Тогда
                       Оставить = 1;
                       ТаблицаСоотв.НоваяСтрока();
                       ТаблицаСоотв.Объект = ТекОбъект;
                       ТаблицаСоотв.Оставить = 1;
                   КонецЕсли;
               КонецЕсли;
           ИначеЕсли Вид = "Номенклатура" Тогда
               Если ТаблицаОстатков.НайтиЗначение(ТекОбъект,"","Товар")=1 Тогда
                   Оставить = 1;      
                   ТаблицаСоотв.НоваяСтрока();
                   ТаблицаСоотв.Объект = ТекОбъект;
                   ТаблицаСоотв.Оставить = 1;
               КонецЕсли;
           КонецЕсли;
           ПредОбъект = ТекОбъект;
       КонецЦикла;      
   //КонецЦикла;
   //Если (Оставить=0) И (ПредОбъект<>"") Тогда
   //    СпрОбъект = СоздатьОбъект("Справочник."+Вид);
   //    СпрОбъект.НайтиЭлемент(ПредОбъект);
   //    СпрОбъект.Удалить(0);
   //    СпрОбъект.Наименование = СпрОбъект.Наименование + " - [[устарел]]";
   //    Сообщить("Помечен "+СпрОбъект);
   //    СпрОбъект.Записать();
   //КонецЕсли;
   //
   // Теперь удалим то, что совсем без ссылок
   Сч = 1;
   ТаблицаСоотв.Свернуть("Объект","ЕстьСсылки,Оставить");
   ТаблицаСоотв.ВыбратьСтроки();
   Пока ТаблицаСоотв.ПолучитьСтроку()=1 Цикл
       Оставить = 0;
       ТекОбъект = ТаблицаСоотв.Объект;
       //Если Вид = "Контрагенты" Тогда
       //    Если ПустоеЗначение(ТекОбъект.ДисконтКарта)=0 Тогда
       //        Владелец = ТекОбъект.ДисконтКарта.Получить(РабочаяДата()).Владелец;
       //        Если (Владелец = Серия1) или (Владелец = Серия2) Тогда
       //            Оставить = 1;
       //        КонецЕсли;
       //    КонецЕсли;
       //ИначеЕсли Вид = "Номенклатура" Тогда
       //    Если ТаблицаОстатков.НайтиЗначение(ТекОбъект,"","Товар")=1 Тогда
       //        Оставить = 1;
       //    КонецЕсли;
       //КонецЕсли;
       Если (ТаблицаСоотв.ЕстьСсылки =0)И(ТаблицаСоотв.Оставить = 0) Тогда
           СпрОбъект = СоздатьОбъект("Справочник."+Вид);
           СпрОбъект.НайтиЭлемент(ТаблицаСоотв.Объект);
           СпрОбъект.Удалить(0);
           СпрОбъект.Наименование = СпрОбъект.Наименование + " - [нет ссылок]";
           Состояние("Помечен "+СпрОбъект);
           //СпрОбъект.Записать();  
           ИтогоПомеченоНом=ИтогоПомеченоНом+1;  
       Сч = Сч + 1;
           Продолжить;
       КонецЕсли;  
       Если (ТаблицаСоотв.Оставить = 0) Тогда
           СпрОбъект = СоздатьОбъект("Справочник."+Вид);
           СпрОбъект.НайтиЭлемент(ТаблицаСоотв.Объект);
           СпрОбъект.Удалить(0);
           СпрОбъект.Наименование = СпрОбъект.Наименование + " - [устарел]";
           Состояние("Помечен "+СпрОбъект);
           //СпрОбъект.Записать();    
       Сч = Сч + 1;
           ИтогоПомеченоНом=ИтогоПомеченоНом+1;
       КонецЕсли;  
       Если Сч = 100 Тогда
           //ЗафиксироватьТранзакцию();
           Сч = 1;
           //НачатьТранзакцию();
           
       КонецЕсли;
   КонецЦикла;
   ТаблицаСоотв.УдалитьСтроки();
   //ЗафиксироватьТранзакцию();
   
КонецПроцедуры
1 zak555
 
14.07.11
19:53
раскрой конечную цель задачи
2 unknown181538
 
14.07.11
19:59
(1) Цель задачи, грубо говоря, пометить на удаление элементы на которые нет ссылок в документах позднее начала 2008 года. + еще есть некоторые нюансы (есть остатки, дисконтные карты и т.п.)
3 unknown181538
 
15.07.11
13:11
Ап
4 Анна_84
 
15.07.11
15:17
(3) база у Вас скл или дбф?
5 unknown181538
 
15.07.11
16:20
(4) ДБФ
6 Анна_84
 
15.07.11
16:42
(6) У меня просто был похожая задачка, на НайтиСсылки целиком по справочнику также падала, я в итоге писала поиск ссылок на прямых запросах для скульной базы. Если хотите (сможете подправить, чтоб на дбф работала) - могу поделиться обработкой
7 unknown181538
 
15.07.11
17:47
(6) Эх.. времени на переписывание немного, с прямыми плохо, оплачивать клиент не будет.
Но буду благодарен - мыло в личке.
8 Анна_84
 
15.07.11
17:53
(7) вечером кину, часов в 9-10
9 Мимохожий Однако
 
15.07.11
17:58
Пометить на удаление все. Удалить, которые могут удалиться. Снять пометку удаления с тех, которые не удалились.
10 unknown181538
 
15.07.11
18:27
(9) Нет. Те, которые упоминаются только в документах до 2008 года тоже надо пометить.
11 unknown181538
 
15.07.11
18:28
К тому же при удалении будет поиск ссылок, и он тоже может упасть.
12 Мимохожий Однако
 
15.07.11
18:29
Универсальной обработкой подбора можно задать любой нужный период. И ничего не упадет.
13 unknown181538
 
15.07.11
18:32
(12) Как мне пометить-то только нужные?
14 Мимохожий Однако
 
15.07.11
18:45
см(9) пометить надо ВСЕ.
15 Мимохожий Однако
 
15.07.11
18:46
Нужные останутся сами, т.к. не смогут удалиться :)
16 Анна_84
 
15.07.11
22:54
(7) кинула Вам обработку, посмотрите - может, пригодится )
17 Cthulhu
 
16.07.11
14:49
(10): недоговариваешь.
для сохранения ссылочной целостности "документы до 2008 года" тоже надо удалять.
Пометить на удаление ВСЕ элемены.
Пометить на удаление документы до 2008 года.
Удалить все что можно удалить.
ИЛИ
Код не такой простынный, будь проще.
0. Составить СЗ со всеми удаляемыми данными.
1. НайтиСсылки сразу СЗ п.0.
2. Из ТЗ, полученной в п.1. тупо удалить строки, в которых Объект = документ до 2008 года.
3. Опционально зачистить ТЗ по иным признакам.
4. Удалить все объекты, которые есть в СЗ п.0 и которых нет в ТЗ п.2/3.
5. Получить нарушение ссылочной целостности базы данных.
Нах велосипеды с прямыми запросами - хз.