Имя: Пароль:
1C
 
Выборочное удаление строк документа
0 Vladal
 
11.11.10
10:17
Есть документ Маршрутный лист, при удалении которого нужно очистить ссылки на этот маршрутный лист в документах его табличной части.

Строки ТЧ перебираю циклом "Для каждого", и в случае успешной записи документа, из ТЧ маршрутного листа удаляется строка с его ссылкой.
Но в результате строки удаляются через одну, притом в самом маршрутном листе остались строки с теми документами, у которых ссылки уже удалены.

Пробовал решить так, как я это сделал бы в семерке - идти циклом "Для" от последней строки к первой и удалять их.


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
   
   Если ПометкаУдаления Тогда
       
       КолвоСтрок = ДанныеОГрузе.Количество();
       
       Для Каждого СтрокаТЧ Из ДанныеОГрузе Цикл
           
           ОбъектДокументОтгрузки = СтрокаТЧ.ДокументОтгрузки.ПолучитьОбъект();
           
           Попытка
               
               ОбъектДокументОтгрузки.МаршрутныйЛист = Неопределено;
               ОбъектДокументОтгрузки.Записать(?(ОбъектДокументОтгрузки.Проведен, РежимЗаписиДокумента.Проведение, РежимЗаписиДокумента.Запись));
               ДанныеОГрузе.Удалить(СтрокаТЧ.НомерСтроки);
               
           Исключение
               
               // Если не получится очистить ссылку на этот документ в документе отгрузки,
               // возвращаем отказ
               Отказ = Истина;
               #Если Клиент Тогда
                   Сообщить("Не удалось удалить ссылку на маршрутный лист в документе "+ОбъектДокументОтгрузки+
                            Символы.ПС+"по причине: "+ОписаниеОшибки());
               #КонецЕсли
               
           КонецПопытки;
           
       КонецЦикла;
       
   КонецЕсли;

... и далее
1 Ненавижу 1С
 
гуру
11.11.10
10:19
"от последней строки к первой"
а тут этого нет ни разу
2 mikecool
 
11.11.10
10:20
НайтиСтроки(здесь отбор)
перебрать и ТЧ.Удалить(строка из массива)
3 Vladal
 
11.11.10
10:21
(1) Ну я не нашел метод ПолучитьСтрокупоНомеру.
4 Ненавижу 1С
 
гуру
11.11.10
10:21
не проще ли в данном случае написать:
Для Каждого СтрокаТЧ Из ДанныеОГрузе Цикл
           
           ОбъектДокументОтгрузки = СтрокаТЧ.ДокументОтгрузки.ПолучитьОбъект();
           ОбъектДокументОтгрузки.МаршрутныйЛист = Неопределено;
           ОбъектДокументОтгрузки.Записать(?(ОбъектДокументОтгрузки.Проведен, РежимЗаписиДокумента.Проведение, РежимЗаписиДокумента.Запись));
           
КонецЦикла;
ДанныеОГрузе.Очистить();
5 Ненавижу 1С
 
гуру
11.11.10
10:22
(3) а и не надо, обращение к строке по номеру есть:

ДанныеОГрузе[НомерСтроки]
6 Vladal
 
11.11.10
10:23
(2) Чем такой метод отличается от моего? Вроде тоже ссылка или из списка отбора?
В отборе у меня есть строки 1, 2 и 5, т.к. документы из 3 и 4 были заблокированы.
И я вот думаю, ка кон удалит? Удали т первую, все ссылки сместятся вниз, 3 в 2, 4 в 3 и т.д.

Или я что-то не понимаю.
7 Vladal
 
11.11.10
10:23
(5) Спасибо, сейчас попробую.
8 Vladal
 
11.11.10
10:24
(4) Проще.. Но если документ реализации кем-то занят, то я в него не запишу пустую ссылку на маршрутный лист.
А в нём проверки, типа нельзя его включить в другой маршрут, т.к. он уже есть в этом. А это как раз и удален..
9 Фокусник
 
11.11.10
10:25
(7) +к(5) только не номер, а индекс строки
10 Ненавижу 1С
 
гуру
11.11.10
10:25
(9) да, именно индекс, короче от 0 нумерация
11 anddro
 
11.11.10
10:26
(0)
Для Сч = 1 - ТЧ.Количество() По 0 Цикл
 СтрокаТЧ = ТЧ[-Сч];
 Если УсловиеУдаления(СтрокТЧ) Тогда
    ТЧ.Удалить(-Сч);
 КонецЕсли
КонецЦикла
12 mikecool
 
11.11.10
10:26
(6) я не перебираю строки, нахожу ссылки
при таком методе выборки строк нет и нечему сбиваться
13 anddro
 
11.11.10
10:28
(12) НайтиСтроки() - классная штука и ее использовать лучше, но это только в случае простых условий
14 Vladal
 
11.11.10
10:30
(13) Да, хороший метод. Я думаю, тут не подойдёт.

Как его применить к моей задаче?
Я вот думал - выгрузить все ссылки на документы в ТЗ или обойти запросом.
Потом найти строки в этой ТЗ, у которых не удалось очистить ссылку на маршрутный лист.
15 Vladal
 
11.11.10
10:31
(11) Хороший метод. Пробую.
16 anddro
 
11.11.10
10:36
(0) а вообще, внимательно почитав исходную постановку задачи: тут проблема в исходной архитектуре решения.
Т.е. имеем обратные ссылки: маршрутный лист ссылается на документ, документ ссылается на маршрутный лист.
От подобных решений лучше отказываться изначально, т.к. вреда от них больше чем пользы.
Ссылки из ТЧ в МЛ достаточно, чтобы в каждом из документов очень быстро найти его МЛ простейшим запросом.
17 mikecool
 
11.11.10
10:38
(13) не пойму, для топика отбор по значению реквизита - что тут сложного?
18 anddro
 
11.11.10
10:40
(17) там вообще нет отбора. Он удаляет все строки, предварительно изменив документ, на который была ссылка в строке
19 Aprobator
 
11.11.10
10:43
(0) а че строку ТЧ обязательно по номеру удалять?
Можно строки подлежащие удалению сначала в массив собрать, а потом уже удалять.
Примерно так:

МассивУдаляемыхСтрок = Новый Массив;
Для каждого СтрокаТЧ из ТЧ Цикл
   Если УсловиеУдаления(СтрокаТЧ) Тогда
        МассивУдаляемыхСтрок.Добавить(СтрокаТЧ)
   КонецЕсли;
КонецЦикла;

Для каждого УдаляемаяСтрока из МассивдаляемыхСтрок Цикл
   ТЧ.УдалитьСтроку(УдаляемаяСтрока)
КонецЦикла;
20 Aprobator
 
11.11.10
10:43
Вместо УдалитьСТроку(УдаляемаяСтрока) - просто Удалить(УдаляемаяСтрока)
21 mikecool
 
11.11.10
10:44
(18) мне вообще - пофик ))
просто обычно начинают изобретать велосипед на пустом месте
22 Aprobator
 
11.11.10
10:47
(18) хм - а как в отборе узнать запишется документ или нет?
23 Aprobator
 
11.11.10
10:47
опс (22) к (17)
24 Vladal
 
11.11.10
11:00
(11) Спасибо, получилось!

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
   
   // ВЛ - 2010-11-09 - Очищение ссылок на помеченный к удалению документ - начало
   //                   Имеет смысл это сделать до проверок
   //Для Каждого СтрокаТЧ Из ДанныеОГрузе Цикл
   Для Сч = 1 - ДанныеОГрузе.Количество() По 0 Цикл
       СтрокаТЧ = ДанныеОГрузе[-Сч];
       
       ОбъектДокументОтгрузки = СтрокаТЧ.ДокументОтгрузки.ПолучитьОбъект();
       
       Попытка
           
           ОбъектДокументОтгрузки.МаршрутныйЛист = Неопределено;
           ОбъектДокументОтгрузки.Записать(РежимЗаписиДокумента.Запись);
           //(?(ОбъектДокументОтгрузки.Проведен, РежимЗаписиДокумента.Проведение, РежимЗаписиДокумента.Запись));
           
           //ДанныеОГрузе.Удалить(СтрокаТЧ.НомерСтроки);
           СсылкаОчищена = Истина;
           
       Исключение
           
           // Если не получится очистить ссылку на этот документ в документе отгрузки,
           // возвращаем отказ
           Отказ = Истина;
           #Если Клиент Тогда
               Сообщить("Не удалось удалить ссылку на маршрутный лист в документе "+ОбъектДокументОтгрузки+
               Символы.ПС+"по причине: "+ОписаниеОшибки());
           #КонецЕсли
           
           СсылкаОчищена = Ложь;
           
       КонецПопытки;
       
       Если СсылкаОчищена Тогда
           ДанныеОГрузе.Удалить(-Сч);
       КонецЕсли
       
   КонецЦикла;
   // ВЛ - 2010-11-09 - Очищение ссылок на помеченный к удалению документ - конец

....
25 Vladal
 
11.11.10
11:09
(16) Понимаю, что не хорошо. Это данность.
А так все документы по этому маршруту в одной кучке, т.е. в одном МЛ.
Да и в журнале реализации можно быстро отобрать по колонке "Маршрутный лист"
26 anddro
 
11.11.10
11:13
(25) для отбора в журнале есть критерии отбора
27 Vladal
 
11.11.10
11:18
Вот в этот критерий отбора как раз и указана ссылка на маршрутный лист.
28 Vladal
 
11.11.10
11:52
Всем спасибо! Работает.
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.