Имя: Пароль:
1C
1С v8
Удаление строк из ТаблицыЗначений за один проход
0 ssalikoff
 
04.08.18
22:49
Простая задача: удалить из таблицы значений или табличной части некоторые строки. Нужно в цикле пробежаться по всем строкам и удалить по некоему условию. Проблема в том, что при удалении строки сбивается счётчик цикла. Приходится пробегаться по таблице два раза, например, так:

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

Есть ли способ сделать это за один проход?
Я не могу догадаться, подскажите, кто знает.
1 Garykom
 
гуру
04.08.18
22:52
Удаляй с конца ))
2 Garykom
 
гуру
04.08.18
22:56
Но правильное удаление это создание новой ТЗ и перенос в нее только нужных строк.

При 50% удаляемых строк - это максимальное по скорости, если конечно у тебя не сотни колонок.
3 ssalikoff
 
04.08.18
23:01
(2) Мне нужно обрабатывать табличные части документов, так что вариант с создание новой ТЗ не годится.
А вот идея с удалением с конца пойдёт, я затупил, мог бы и сам додуматься. Единственное неудобство, что придётся отказаться от удобной конструкции Для Каждого Из и заменить её циклом со счётчиком.
4 Garykom
 
гуру
04.08.18
23:04
(3) Хо-хо кто тебе мешает из ТЧ копировать строк в ТЗ а потом загрузить в ТЧ из новой ТЗ ?
5 Garykom
 
гуру
04.08.18
23:06
Советую сравнить реальную скорость работы разными методами и сделать вывод для себя.
6 ssalikoff
 
04.08.18
23:06
(4) Не думаю, что копирование объекта туда-обратно эффективнее двойного обхода таблицы в цикле.
7 ssalikoff
 
04.08.18
23:07
(5) Хотя, соглашусь, всё нужно мерить и не полагаться на собственное чутьё
8 Garykom
 
гуру
04.08.18
23:27
(6) Проблема не в двойном обходе а в перестройке индексов и подсчета итогов после каждого удаления.
9 Cyberhawk
 
04.08.18
23:38
(8) Это ты для какого случая описываешь?
10 tesseract
 
05.08.18
08:27
(2) Соглашусь.
Если условие на равно можно просто ТЗ1 = ТЗ.Скопировать(ТЗ.НайтиСтроки(Новый Структура("Условие",условие)))
11 tesseract
 
05.08.18
08:29
(6) Зря. В С++ например операции со строками как раз через создание нового объекта выполняется. Так сокращается количество обращений к памяти.
12 dem0sphen
 
05.08.18
08:31
(0)
КоличествоУдаленныхСтрок = 0;
Для Cчетчик = 0 по ТабЧасть.Количество()-1 Цикл
    Если Условие Тогда
        ТабЧасть.Удалить(Счетчик-КоличествоУдаленныхСтрок);
        КоличествоУдаленныхСтрок = КоличествоУдаленныхСтрок + 1;
    КонецЕсли;
КонецЦикла;
13 tesseract
 
05.08.18
10:52
(12) Сам-то проверял к чему этот код приведет?
14 dem0sphen
 
05.08.18
11:11
(13) И ты проверь,  далее сюда отпишись.
15 Лефмихалыч
 
05.08.18
11:26
на вскидку - есть способов шесть
16 tesseract
 
05.08.18
17:29
(14) Удаляет не то.
17 tesseract
 
05.08.18
17:31
(13) Хотя если в условие добавлять строку по ТекИндекс = (индекс-количествоудаленных строк) то да.  Тогда извини.
18 Сияющий в темноте
 
06.08.18
14:25
Можно в процессе перебора удаляемые строки добавлять в отдельный массив,а потом по окончании перебора перебрать массив и все удалить скопом.
19 Сияющий в темноте
 
06.08.18
14:27
можно и перебором от начала,но нужно понимать,что когда мы удалили текущую строку,то текущей стала следующая,и можно не увеличивая счетчик цикла пройти еще одну иттерацию.
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой