Имя: Пароль:
1C
1C 7.7
v7: Как правильно удалить строки таблицы значений
,
0 gregs
 
24.06.13
12:56
Нужно удалить определенные строки тз. Типа такого варианта


ТЗ_уд.ВыбратьСтроки();
       Пока ТЗ_уд.ПолучитьСтроку() = 1 Цикл
           
           
           Если Тз_уд.Предоплата = 1 Тогда
               Сообщить("ДокАкт "+ТЗ_уд.Док+"  Номер строки "+ТЗ_уд.НомерСтроки+" Удаляем!");
               Тз_уд.УдалитьСтроку();
           КонецЕсли;
           
       КонецЦикла;
1 KishMish
 
24.06.13
12:58
ТЗ_уд.ВыбратьСтроки();
       Пока ТЗ_уд.ПолучитьСтроку() = 1 Цикл          
           
          Пока (Тз_уд.Предоплата = 1) и (ТЗ_уд.НомерСтроки>0) Цикл
               Сообщить("ДокАкт "+ТЗ_уд.Док+"  Номер строки "+ТЗ_уд.НомерСтроки+" Удаляем!");
               Тз_уд.УдалитьСтроку();
КонеЦикла;
           
       КонецЦикла;
2 vcv
 
24.06.13
13:02
Строчка = 1;
Пока Строчка <= ТЗ_уд.КоличествоСтрок() Цикл
 Если Тз_уд.ПолучитьЗначение(Строчка,"Предоплата")=1 Тогда
   Тз_уд.УдалитьСтроку();
 Иначе
   Строчка = Строчка + 1;
 КонецЕсли;
КонецЦикла;
3 Плот
 
24.06.13
13:02
(0) Кажется здесь нужно вводить счетчик.
4 Плот
 
24.06.13
13:02
(+3) смотри (2)
5 vcv
 
24.06.13
13:04
Сейчас кто-нибудь предложит вариант в пару строчек с использованием индексированной таблицы :)
6 vinogradъ
 
24.06.13
13:05
7 KishMish
 
24.06.13
13:06
(5) ненене, самый популярный здесь обратным циклом, дабы выборка не сбивалась
8 Анцеранана
 
24.06.13
13:09
(7) +1
9 de Bug
 
24.06.13
13:09
Для Сч = -ТЗ_уд.КоличествоСтрок() По -1 Цикл
  ТЗ_уд.ПолучитьСтрокуПоНомеру(-Сч);            
  Если Тз_уд.Предоплата = 1 Тогда
     Сообщить("ДокАкт "+ТЗ_уд.Док+"  Номер строки "+ТЗ_уд.НомерСтроки+" Удаляем!");
     Тз_уд.УдалитьСтроку();
  КонецЕсли;
КонецЦикла;
10 IVT_2009
 
24.06.13
13:10
тз.выбратьСтроки();
пока тз.получитьСтроку()=1 цикл
если (условие = 1 ) тогда
 тз.удалитьСтроку();
 тз.выбратьСтроки();
конецЕсли;
конецЦикла;
11 vcv
 
24.06.13
13:11
(10) А не будет ли оно тормозить на маленькой таблице из пары миллионов строк?
12 IVT_2009
 
24.06.13
13:12
будет конечно , но несколько тысяч удалить можно.
13 gregs
 
24.06.13
13:23
(10) работает, но конечно....

всетаки наверное счетчик нужен
14 gregs
 
24.06.13
13:30
(2)

вот так вроде работает норм

Строчка = 1;
       Пока Строчка <= ТЗ_уд.КоличествоСтрок() Цикл
           Если Тз_уд.ПолучитьЗначение(Строчка,"Предоплата")=1 Тогда
               Тз_уд.УдалитьСтроку(Строчка);
           Иначе
               Строчка = Строчка + 1;
           КонецЕсли;
       КонецЦикла;
15 Has
 
24.06.13
13:42
(0)см.на проклабе
Конкурс: самый быстрый вариант удаления ненужных строк из Таблицы Значений

или см.(9)

в общем виде:
Для Индекс = -ТЗ.КоличествоСтрок() По -1 Цикл
   ТЗ.ПолучитьСтрокуПоНомеру(-Индекс);
   Если <ПроверкаУсловий> Тогда
       ТЗ.УдалитьСтроку();
   КонецЕсли;
КонецЦикла;
16 drongo-god
 
24.06.13
13:55
(0) Получать и удалять строки нужно по индексу. Только нужно учитывать что при удалении строки общее количество индексов уменьшается. Соответственно и индекс следующей строки после удаленной будет таким же как у только что удаленной строки.
17 aka AMIGO
 
24.06.13
13:57
(15) еще и самый правильный и безопасный :)
18 drongo-god
 
24.06.13
14:04
(0)
КвоСтрок = ТЗ.КоличествоСтрок();
Для НомСтрТИ = <Начальный_Номер_Строки> По КвоСтрок Цикл
Если ТЗ.ПолучитьЗначение(НомСтрТИ,"ИМЯ_ПОЛЯ") = <Требуемое_услове> Тогда
ТЗ.УдалитьСтроку(НомСтрТИ);
КвоСтрок = КвоСтрок - 1;
НомСтрТИ = НомСтрТИ - 1;
КонецЕсли;
КонецЦикла;
19 ХомаБрут
 
24.06.13
14:17
Правильный вариант (9) с обратным перебором цикла. Ибо самый простой и быстрый.
20 drongo-god
 
24.06.13
14:23
(15) Хотя вариант с обходом ТЗ с конца к началу более симпатичный.

Мой метод будет быстрее тогда когда мы можем сначала правильно отсортировать ТЗ и найти первый нужный индекс удаляемой строки. И выходить из цикла когда условие не истина. Тогда всю ТЗ не надо пробегать.

Не универсально, но лучше всего (по скорости) подходит когда нужно удалить строки с определенным признаком.
21 Эльниньо
 
24.06.13
15:28
Давненько этого вопроса не было. Я уже тревожится стал.
22 Zhuravlik
 
24.06.13
15:57
//======================================================================
       Процедура гд_УдалитьСтрокиТЗ(тз, флСообщить = 0) Экспорт
           //Универсальная процедура быстрой очистки таблицы значений.
           //тз - таблица значений. Перед передачи в эту процедуру тз необходимо обработать след.
           //образом:
           //        - Создать колонку "Удалить"
           //        - пройтись по условию, и пометить удалемые строки флагом 1.
           //флСообщить - флаг, если 1 - сообщается количество удаленных и оставшихся строк.
           //Колонка удалить авт. удаляется из тз.
           
           Попытка
               КолСтрокУд = тз.Итог("Удалить");
           Исключение
               Возврат;
           КонецПопытки;
           
           Если КолСтрокУд <= 0 Тогда
               Если флСообщить = 1 Тогда
                   Сообщить("Не было удалено ни одной строки.");
               КонецЕсли;
               тз.УдалитьКолонку("Удалить");
               Возврат;
           КонецЕсли;
           
           КолСтрок = тз.КоличествоСтрок();
           Если КолСтрок = КолСтрокУд Тогда
               тз.УдалитьСтроки();
               Если флСообщить = 1 Тогда
                   Сообщить("Таблица полностью очищена.", "I");
               КонецЕсли;
           Иначе
               ТЗРаб = СоздатьОбъект("ТаблицаЗначений");
               тз.Выгрузить(ТЗРаб);
               ТЗРаб.Сортировать("+Удалить");
               ТЗРаб.Выгрузить(тз,1,КолСтрок - КолСтрокУд);
               ТЗРаб = 0;
               Если флСообщить = 1 Тогда
                   Сообщить("Из " + КолСтрок + " строк таблицы, было удалено " +
                   КолСтрокУд + ". Осталось - " + тз.КоличествоСтрок() + " строк.", "I");
               КонецЕсли;                
           КонецЕсли;
           тз.УдалитьКолонку("Удалить");
           
       КонецПроцедуры // УдалитьСтрокиТЗ
23 Эльниньо
 
24.06.13
16:28
(19) Самый простой в (1)
24 vcv
 
24.06.13
18:28
(23) Самый простой в (1) сильно страдает от плохой читабельности. А посему некошерен при сколько-нибудь серьёзном проекте с N разработчиками и текучкой кадров.
25 vladko
 
24.06.13
18:33
самый быстрый и беспроблемный способ в (15). Сам таким пользуюсь
26 Ковычки
 
24.06.13
18:34
(23)

(c) Эльниньо
27 Ковычки
 
24.06.13
18:39
(24) в твоем случае просче так

Стр=0;
Пока ТЗ_уд.НайтиЗначение(1,Стр,"Предоплата")=1 Цикл
   ТЗ_уд.УдалитьСтроку();
   Стр=0;
КонецЦикла;
28 Ковычки
 
24.06.13
18:41
ТЗ_уд.УдалитьСтроку(Стр);
29 vcv
 
24.06.13
18:44
(27) Если точно известно, что удаляемых строк мало, возможно и так. При большой таблице и большом количестве удаляемых строк будет не только проще, но еще и медленней, и печальней.
30 Сияющий Асинхраль
 
24.06.13
18:47
(24) Ничем не более плохочитаем по сравнение со всем остальным, я бы сказал даже запоминается лучше ибо неожиданно и красиво. Скажем метод NS как самый быстрый тоже не очень то читаем, но используется часто, ибо скорость нужна...
31 Simod
 
24.06.13
18:52
(0) Шо? Опять?
32 vcv
 
24.06.13
18:52
(27)(30) Два вложенных цикла делают один обход таблицы значений построчно. Используется некошерная особенность 1С, что получение атрибута таблицы при невыбранной строке возвращает пустое значение вместо фатальной ошибки. Используется недокументированное поведение 1С в случае удаления последней строки таблицы (позиционирование строки после удаления текущей).
Да, я нуден, но неужели вы это называете хорошим стилей программирования?
33 Сияющий Асинхраль
 
24.06.13
18:56
(32) Да, вариант (1) я называю хорошим стилем программирования, ибо Красиво. Если ты не видишь этой красоты, то извини, о вкусах не спорят...
34 Сияющий Асинхраль
 
24.06.13
18:58
+(32) Если уж на то пошло, то вариант NS тоже использует именно особенности 1С, тем не менее ты вряд ли будешь утверждать, что он некошерен...
35 Simod
 
24.06.13
19:04
(34) Какие особенности?

Все варианты с УдалитьСтроку() годятся только для ТЗ < 100 строк, ибо медленно.
36 vcv
 
24.06.13
19:05
(33) Я ж не про красоту. А про читабельность. Попробуй проведи эксперимент - отлови Nцать произвольных 1Сников и спроси их, что делает этот код. На мой взгляд, если у заметного количества опрошенных время на правильный ответ займёт больше нескольких секунд - код плохой. И это еще идеальный выхолощенный вариант, когда примитивое однострочное условие на удаление и нет каких-то других выполняемых действий в цикле.
37 Ковычки
 
24.06.13
19:51
(29) отсортируй и будет простой цикл, не быстро но просто
38 exwill
 
24.06.13
20:01
(36) Что за читабельность такая? Компьютер читает - значит читабельно.
39 Ковычки
 
24.06.13
20:07
(38) не умничай
40 Сияющий Асинхраль
 
24.06.13
21:26
(36) вот въехать в запрос на восьмерке на тысячу строчек с кучей подзапросов трудно, а если кто-то понять не может пару вложенных циклов, то зря в 1с пошел...
41 KRV
 
24.06.13
21:30
(0) Зачем? Не ешьте что не надо.. мешает - выгрузите в другую таблицу.. заодно и от лишней поиибени избавитесь.. ох уж эти восьмершники.. - даже не представляют, что адинасс умеет и на 128 метрах памяти с целкой 500-й работать..
42 Эльниньо
 
24.06.13
23:11
(36) Многие крутые одинэсники сходу смеялись над ним, потом извинялись.
И что теперь - писать код в расчёте на будущих прогеров тугодумов?
43 ХомаБрут
 
26.06.13
13:06
(42) подумайте на досуге, может быть лучше котёнка с дерева снять, чем услаждать своё самомнение сложностью написанного кода?
44 Эльниньо
 
26.06.13
13:11
(43) Проще этого только код в (27)
45 NikVars
 
27.06.13
09:55
Проще - не проще...
Совсем забыли, что речь в (0):"v7: Как правильно удалить строки таблицы значений".
Там утверждается, что правильно так, как в (0).
Разошлись...
А вопрос никто и не задавал.