пятница, 31 октября 2014 г.

Удаление строк из табличной части или таблицы значений в цикле

правильное удаление строк из табличной части


К данному виду циклов необходимо при разработке сразу предусмотреть процес прерывания иначе зацикливание просто неизбежно. Ниже я приведу пример обратного обхода строк таблицы значений или табличной части с последующим удалением строк:
        
//удаляем из табличной части товары Используя Индекс строки
ИндексСтроки = ТабличнаяЧастьДокумента.Количество()-1;
        Пока Истина Цикл

            Если
ИндексСтроки < 0 Тогда
                Прервать;
            КонецЕсли;

           
СтрокаТабличнойЧасти = ТабличнаяЧастьДокумента.Получить(ИндексСтроки);
           
//условие при котором должна удалятся строка
            //в данном случае проверяется внешняя таблица значений на вхождение этого товара и если такого товара нет, строка удаляется.
           
Если ТаблицаЗначений.Найти(СтрокаТабличнойЧасти.Номенклатура, "Номенклатура") = Неопределено Тогда
               
ТабличнаяЧастьДокумента.Удалить(ИндексСтроки);
            КонецЕсли;

           
ИндексСтроки = ИндексСтроки - 1;

        КонецЦикла;


Индекс = МассивЭлементов.ВГраница();
Пока Индекс >= 0 Цикл 
   Если ТипЗнч(МассивЭлементов[Индекс]) = Тип("Число") Тогда 
      МассивЭлементов.Удалить(Индекс); 
   КонецЕсли; 
   Индекс = Индекс - 1; 
КонецЦикла; 

// Удаляет дубли строк из таблицы значений.
//
// Параметры:
//  ТаблицаИсточник           - ТаблицаЗначений - Таблица из которой необходимо удалить дубли строк
//  МассивИменКолонок         - Массив          - Имена колонок по которым производится поиск соответствий
//  ИмяКолонкиУказательСтроки - Строка          - Наименование колонки с указателем строки. 
//   Где значения указателя Тип Число, Строка
//   Например: указан параметр "НомерСтрокиФайла". Для каждой строки таблицы он равняется числам 1,2,3,4 и т.д.
//          При удалении дублирующих строк в исходящую таблицу будет добавлена колонка "УказательСтроки", где и будут размещены эти "идентификаторы/указатели". 
//          Колонка "НомерСтрокиФайла" будет содержать какое-то из значений.  
//           "УказательСтроки"  = "4;1;2;3;" 
//           "НомерСтрокиФайла" = 4
//          Удаление происходит обратным перебором поэтому числа резмещены в таком порядке.
//
// Возвращаемое значение:
//   ТаблицаЗначений   - Содержит коллекцию имен входящих колонок.
//      Когда был указан параметр "ИмяКолонкиУказательСтроки" то добавляется колонка "УказательСтроки"
//
Функция УдалитьДублиСтрокИзТаблицыЗначений(ТаблицаИсточник, МассивИменКолонок, ИмяКолонкиУказательСтроки = "") Экспорт
 
 ИмяКлючевыхКолонок = СтрСоединить(МассивИменКолонок, ",");
 
 Если Не ПустаяСтрока(ИмяКолонкиУказательСтроки) Тогда
  ИмяКлючевыхКолонок = ИмяКлючевыхКолонок + "," + ИмяКолонкиУказательСтроки;
 КонецЕсли; 
 
 Таблица = ТаблицаИсточник.Скопировать(,ИмяКлючевыхКолонок);
 Если Не ПустаяСтрока(ИмяКолонкиУказательСтроки) Тогда
  Таблица.Колонки.Добавить("УказательСтроки");
 КонецЕсли; 
 
 СтруктураОтбора = Новый Структура;
 Для каждого Имя Из МассивИменКолонок Цикл
  СтруктураОтбора.Вставить(Имя);
 КонецЦикла; 
 
 ИндексСтроки = Таблица.Количество()-1;
 Пока Истина Цикл
  
  Если ИндексСтроки < 0 Тогда
   Прервать;
  КонецЕсли;
  
  СтрокаЗначений = Таблица.Получить(ИндексСтроки);
  ЗаполнитьЗначенияСвойств(СтруктураОтбора, СтрокаЗначений);
  
  НайденныеСтроки = Таблица.НайтиСтроки(СтруктураОтбора);
  Если НайденныеСтроки.Количество() > 1 Тогда
   
   Для каждого УдаляемаяСтрока Из НайденныеСтроки Цикл
    
    Если Таблица.Индекс(УдаляемаяСтрока) = ИндексСтроки Тогда
     Продолжить; //оставляем текущую строку 
    КонецЕсли; 
    
    //укажем какие указатели строк были удалены
    Если Не ПустаяСтрока(ИмяКолонкиУказательСтроки) Тогда
     
     ТекПозицияСтр = Формат(СтрокаЗначений[ИмяКолонкиУказательСтроки], "ЧГ=0");
     Если СтрНайти(СтрокаЗначений.УказательСтроки, ТекПозицияСтр) = 0 Тогда
      
      СтрокаЗначений.УказательСтроки = ТекПозицияСтр + ";";
      
     КонецЕсли; 
     
     СтрокаЗначений.УказательСтроки = СтрокаЗначений.УказательСтроки + Формат(УдаляемаяСтрока[ИмяКолонкиУказательСтроки],"ЧГ=0") + ";";
     
    КонецЕсли; 
    
    Таблица.Удалить(УдаляемаяСтрока);
    ИндексСтроки = ИндексСтроки - 1;//строк становится меньше (уменшаем индекс)
    
   КонецЦикла; 
   
  КонецЕсли;
  
  ИндексСтроки = ИндексСтроки - 1;
  
 КонецЦикла;
 
 Возврат Таблица;
КонецФункции 

Комментариев нет:

Отправить комментарий