|
Удаление строк из ТаблицыЗначений за один проход | ☑ | ||
---|---|---|---|---|
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
|
можно и перебором от начала,но нужно понимать,что когда мы удалили текущую строку,то текущей стала следующая,и можно не увеличивая счетчик цикла пройти еще одну иттерацию.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |