Имя: Пароль:
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
можно и перебором от начала,но нужно понимать,что когда мы удалили текущую строку,то текущей стала следующая,и можно не увеличивая счетчик цикла пройти еще одну иттерацию.
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn