Видалення кількох рядків у табличній частині, it-prospect

На перший погляд, завдання досить тривіальна - взяв, пройшовся в циклі по всіх рядках, та й видалив непотрібні:

Для i = 0 За ТабЧасть.Колічество () - 1 Цикл
Якщо ТабЧасть [i] .Пометка Тоді
ТабЧасть.Удаліть (i);
КонецЕсли;
КонецЦікла;

Але насправді тут є цілих дві проблеми:

1) Після кожного видалення рядка всі індекси рядків зсуваються на 1 назад.

Після видалення i-го рядка i + 1-а приймає номер i, а цикл то йде далі, і на наступній ітерації ми будемо обробляти вже i + 1 рядок (колишню i + 2-ий).
Таким чином, по-перше, змінна циклу перестає відповідати номеру рядка, а по-друге, не обробляється рядок, що слідувала за видаляється!
Рішення проблеми - в порушенні рекомендацій класичного програмування, в зміні змінної циклу в тілі циклу:

Для i = 0 За ТабЧасть.Колічество () - 1 Цикл
Якщо ТабЧасть [i] .Пометка Тоді
ТабЧасть.Удаліть (i);
i = i-1;
КонецЕсли;
КонецЦікла;

2) Після кожного видалення рядка загальна кількість рядків зменшується на 1.

Начебто так і повинно бути, в чому ж тоді проблема? А проблема в тому, що на початку циклу 1С раз і назавжди запам'ятовує значення межі ітерацій змінної (ТабЧасть.Колічество () - 1) і не перераховує його кожен раз при поверненні в початок циклу. Коли ми видалимо всі потрібні нам рядки і дійдемо до кінця таблиці, ітерації циклу продовжаться, і вилетить помилка перевищення індексу масиву.
Рішення проблеми - в додатковій перевірці:

Для i = 0 За ТабЧасть.Колічество () - 1 Цикл
Якщо ТабЧасть [i] .Пометка Тоді
ТабЧасть.Удаліть (i);
i = i-1;
КонецЕсли;
Якщо i = ТабЧасть.Колічество () - 1 Тоді
перервати;
КонецЕсли;
КонецЦікла;

Ну а якщо вас все ж таки бентежить повернення на 1 в лічильнику змінної циклу, є ось такий варіант з використанням циклу "Поки":

i = 0;
поки i<=ТабЧасть.Количество()-1 Цикл
Якщо ТабЧасть [i] .Пометка Тоді
ТабЧасть.Удаліть (i);
інакше
i = i + 1;
КонецЕсли;
КонецЦікла;