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

1. Metabos 29 31.01.18 21:50 Сейчас в теме
Добрый вечер. Подскажите, что нужно сделать, чтобы удаление в таблице значений было корректным? Я методом Найти ищу сроку. Ее удаляю, но после первого удаления строки, строки меняются как то и удаляются или не все или не те.
По теме из базы знаний
Найденные решения
6. protexprotex 113 31.01.18 22:25 Сейчас в теме
(1) Добрый день. Удалять надо так:

Сч = 0;
Пока (Сч < ТаблицаДанных.Количество ()) Цикл
Строка = ТаблицаДанных.ПолучитьСтроку (Сч);
Если (УдаляемСтроку (Строка)) Тогда
ТаблицаДанных.Удалить(Сч);
Иначе
Сч = Сч + 1;
КонецЕсли;
КонецЦикла;

где Функция УдаляемСтроку () - анализ строки на удаление. Работает правильно и быстро.
VyacheslavShilov; user915901; asupigor; kabantus; hasp_x; Алсушка80; user665211_antonfo; user981405; dimisa; RolexStrider; Merkalov; jaroslav.h; MaxTolya; rmIvanT; +14 Ответить
Остальные ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
3. Xershi 1474 31.01.18 22:09 Сейчас в теме
(1) обходить таблицу надо с конца. А вы похоже с начала, вот индекс теряется!
kild; YanTsys; +2 Ответить
5. kild 89 31.01.18 22:23 Сейчас в теме
(3) Можно и не обходить. Автор-то не приводит свой код и не ясно что ему нужно. Лишь что-то ищет функцией Найти и удаляет. В этом случае обход может и не понадобится.

Вот куча способов удаление.

// 1. Удаление строк согласно условию
      

    НулевыеСтроки = ТаблицаПослеПодмен.НайтиСтроки(Новый Структура("Сумма",0));
      

    Для каждого СтрокаТаблицы Из НулевыеСтроки Цикл
      

    	ТаблицаПослеПодмен.Удалить(СтрокаТаблицы)
      

    КонецЦикла;
      

    
      

    // Нужно оставить строки только соответствующие условию,а остальные удалить то:
      

    ПараметрыОтбора = Новый Структура("Цена",15000);
      

    ТЗНов = ТЗ.Скопировать(ПараметрыОтбора); 
      

    // в результате в ТЗнов будут только строки из ТЗ, в которых значение поля Цена = 15000
      

    
      

    // 2. Удаление определенной строки, например УдаляемаяСтрока = 5;
      

    ТаблицаЗначений.Удалить(УдаляемаяСтрока); 
      

    
      

    // 3. Удаление первой строки
      

    ТаблицаЗначений.Удалить(0); 
      

    
      

    // 4. Удаление определенной колонки, например УдаляемаяКолонка = 3;
      

    ТаблицаЗначений.Колонки.Удалить(УдаляемаяКолонка); 
      

    
      

    // 5. Удалить первую колонку
      

    ТаблицаЗначений.Колонки.Удалить(0); 
      

    
      

    // 6. Удаление строк перебором, проверяя условие
      

    СтаршийИндексКолонок = ТаблицаЗначений.Колонки.Количество() - 1; 
      

    Индекс = ТаблицаЗначений.Количество() - 1; 
      

    Пока Индекс > = 0 Цикл 
      

    	Для Сч = 0 По СтаршийИндексКолонок Цикл 
      

    		Если ТипЗнч(ТаблицаЗначений[Индекс][Сч]) = Тип("Число") Тогда 
      

    			ТаблицаЗначений.Удалить(Индекс); 
      

    			Прервать; 
      

    		КонецЕсли; 
      

    	КонецЦикла; 
      

    	Индекс = Индекс - 1; 
      

    КонецЦикла;
      
Показать
starovton; user1621493; AlexGoldT; marinelle; HIVvich; Tworozhok; craftytigra; Simonov_NPM; +8 Ответить
8. YanTsys 12 31.01.18 22:28 Сейчас в теме
(5) Вообще-то проблема сформулирована крайне чётко, перечитайте вопрос... :)
7. пользователь 31.01.18 22:27
Сообщение было скрыто модератором.
...
6. protexprotex 113 31.01.18 22:25 Сейчас в теме
(1) Добрый день. Удалять надо так:

Сч = 0;
Пока (Сч < ТаблицаДанных.Количество ()) Цикл
Строка = ТаблицаДанных.ПолучитьСтроку (Сч);
Если (УдаляемСтроку (Строка)) Тогда
ТаблицаДанных.Удалить(Сч);
Иначе
Сч = Сч + 1;
КонецЕсли;
КонецЦикла;

где Функция УдаляемСтроку () - анализ строки на удаление. Работает правильно и быстро.
VyacheslavShilov; user915901; asupigor; kabantus; hasp_x; Алсушка80; user665211_antonfo; user981405; dimisa; RolexStrider; Merkalov; jaroslav.h; MaxTolya; rmIvanT; +14 Ответить
10. YanTsys 12 31.01.18 22:32 Сейчас в теме
(6) Я всё таки предпочитаю удалять строки после полной обработки таблицы, и индексы не портятся и не нужно помнить нюансы каждого языка программирования :)
12. protexprotex 113 31.01.18 22:39 Сейчас в теме
(10) Ну, тогда можете так:
ТаблицаДанных.Колонки.Добавить ("Удалить");
Для Каждого ТекСтрока Из ТаблицаДанных Цикл
    ТекСтрока.Удалить = УдаляемСтроку (Строка);
КонецЦикла;
ОтборСтрок = Новый Структура ("Удалить", Истина);
Строки = ТаблицаДанных.НайтиСтроки (ОтборСтрок );
ТаблицаДанных.Колонки.Удалить("Удалить");

И теперь удаляйте строки в ТаблицаДанных из списка строк Строки

Хотя, это уже изврат если просто нужно удалить строки по какому - то простому условия. Этот алгоритм имеет смысл только если удаление строки зависит от данных в других строках. Тогда да.
user819246; klaus38; user665211_antonfo; +3 Ответить
19. YanTsys 12 01.02.18 08:23 Сейчас в теме
(12) А чем не понравился мой вариант (4) с хранением строк которые потом нужно удалить в отдельном массиве? Тем более что если речь идет о таблицах которые динамически отражаются на экране то добавление лишней колонки отнимет лишнее время :)
21. Metabos 29 01.02.18 10:21 Сейчас в теме
(19)
А чем не понравился мой вариант (4) с хранением строк которые потом нужно удалить в отдельном массиве? Тем более что если речь идет о таблицах которые динамически отражаются на экране то добавление лишней колонки отнимет лишнее время :)

:-)) Я понимаю, что причина в номерах строки, что сбивается. И в решении было видно, что работа идет с этим. А в вашем решении как будто 2 раза одно и тоже по циклу проходит. Код не только должен работать, но и быть понятным, мне просто другой вариант был чисто визуально понятнее. Может он по другим параметрам уступает, но тут это не так важно, этот объект пользователи используют самое частое раз в день. А по факту за прошлый год раз 10. Строк там мало, 5-6. Поэтому не так важно, сколько он будет отрабатывать.
26. protexprotex 113 01.02.18 12:17 Сейчас в теме
(19) Ну, это уже кому как нравиться. Приносить в жертву понятность и легкость восприятия программного кода в угоду лишней миллисекунде выполнения кода - я думаю, что не стоит. Если бы тут был объем данных, скажем, строк миллиард, то да. Я бы тогда написал уже код или с индексами, или методы статистического анализа применил. Или метод золотого сечения и пр. А тут задача локальная. Мне кажется, что не стоит.
user665211_antonfo; +1 Ответить
13. Metabos 29 31.01.18 22:48 Сейчас в теме
(6) Строка = ТаблицаДанных.ПолучитьСтроку (Сч); - только не получитьстроку, а получить.
Да, работает спасибо!
15. protexprotex 113 31.01.18 23:10 Сейчас в теме
(13) Ну да, конечно получить.
16. kild 89 31.01.18 23:11 Сейчас в теме
(6) У вас похоже самый медленный алгоритм удаление из всех представленных. В каждой итерации вычисляется количество строк всей таблицы ТаблицаДанных.Количество () и доп.условия. Чтобы этого не было нужно перебирать с конца, как говорили остальные комментаторы.
Самый быстрый и легкий путь:

	 Индекс = ТаблицаЗначений.Количество() - 1; 
	 Пока Индекс >= 0 Цикл   		
	     Если УсловиеДляУдаленияСтроки(ТаблицаЗначений[Индекс]) Тогда      
	    	 ТаблицаЗначений.Удалить(Индекс);                              
	     КонецЕсли;         			
	     Индекс = Индекс - 1;                                                                         
	 КонецЦикла;
Показать


Ну если прямо хочется перебирать с начала по каким-то неведомым причинам, то хотя бы нужно переписать ваш код:

	Количество = ТаблицаДанных.Количество();
	Сч = 0; 
	Пока (Сч < Количество) Цикл 
				
		Если (УдаляемСтроку(ТаблицаДанных[Сч])) Тогда 
			ТаблицаДанных.Удалить(Сч); 
			Количество = ТаблицаДанных.Количество();
			Продолжить; 			
		КонецЕсли; 
		
		Сч = Сч + 1;
		
	КонецЦикла;
Показать
Sottoz; maxim_saharov; +2 Ответить
18. protexprotex 113 31.01.18 23:17 Сейчас в теме
(16) Вообще - то количество строк вычисляется компилятором не при каждом обращении к функции КоличестроСтрок(), а просто возвращается из предвычисленного параметра. Т.к. КоличествоСтрок() - это просто функция которая возвращает свойство таблицы КоличествоСтрок. При удалении строки из этого свойства вычитается 1-ца, а при добавлении строки добавляется единица. Так что Вы тут не правы. Это аналог TList -
TList *List = new TList;
for (int i = 0; i < 10; i++)
{
List-Add((void *)(new float[10]));
}
и здесь при обращении int Num = List->Count - также не вычисляется кол-во элементов в списке List, - он просто храниться в свойстве потомка класса.
user665211_antonfo; +1 Ответить
24. spacecraft 01.02.18 11:31 Сейчас в теме
(18) для небольших данных разница будет не существенна. На больших уже заметна.
Вот тест:
&НаКлиенте
Процедура Тест1(Команда)
	ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сч = 0;
	Пока (Сч < ТЗРезультат.Количество()) Цикл
		Сч = Сч + 1;
	КонецЦикла;
	ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить("Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры

&НаКлиенте
Процедура Тест2(Команда)
	ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сч = 0;
	Пока (Сч < КоличествоСтрокТЗ) Цикл
		Сч = Сч + 1;
	КонецЦикла;
	ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить("Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры
Показать

Для КоличествоСтрокТЗ = 1 000 000
Тест1: "Время выполнения: 7 128"
Тест2: "Время выполнения: 6 781"
27. protexprotex 113 01.02.18 12:20 Сейчас в теме
(24) Ну, во первых тут у Вас время в миллисекундах, и 200 миллисекунд разница. Для чистоты эксперимента надо прогнать алгоритм раз 100 и усреднить. Т.к. при запуске алгоритмов включается такие процессы, как использование кеша процессора/запуск других служб винды и пр. Тут судить нельзя по одному тесту. А во вторых:
Ну, это уже кому как нравиться. Приносить в жертву понятность и легкость восприятия программного кода в угоду лишней миллисекунде выполнения кода - я думаю, что не стоит. Если бы тут был объем данных, скажем, строк миллиард, то да. Я бы тогда написал уже код или с индексами, или методы статистического анализа применил. Или метод золотого сечения и пр. А тут задача локальная. Мне кажется, что не стоит.
user665211_antonfo; +1 Ответить
25. spacecraft 01.02.18 11:44 Сейчас в теме
(18) А вот когда в ТЗ меняются строки, то становится совсем интересно:
&НаКлиенте
Процедура Тест1(Команда)
	ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сч = 0;
	Пока (Сч < ТЗРезультат.Количество()) Цикл
		Если Сч%2 = 0 Тогда
			ТЗРезультат.Удалить(Сч);
		КонецЕсли;
		Сч = Сч + 1;
	КонецЦикла;
	ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить("Тест1: Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры

&НаКлиенте
Процедура Тест2(Команда)
	ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сч = 0;
	Пока (Сч < КоличествоСтрокТЗ/2) Цикл
		Если Сч%2 = 0 Тогда
			ТЗРезультат.Удалить(Сч);
		КонецЕсли;
		Сч = Сч + 1;
	КонецЦикла;
	ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить("Тест2: Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры
Показать

Для КоличествоСтрокТЗ = 100 000
Тест1: Время выполнения: 26 286
Тест2: Время выполнения: 20 127

Более 6 секунд на 100 000 строках. Половина из которых удаляется.
Вот это уже затратно.
28. protexprotex 113 01.02.18 12:25 Сейчас в теме
(25) Хм. Я даже не знаю как это комментировать. Неужели не понятно, что при удалении строки будет пересчет количества строк. И вот в этом алгоритме -
Пока (Сч < ТЗРезультат.Количество()) Цикл
        Если Сч%2 = 0 Тогда
            ТЗРезультат.Удалить(Сч);
        КонецЕсли;
        Сч = Сч + 1;
    КонецЦикла;

будет увеличение времени на пересчет.
А при удалении строк в алгоритме
Пока (Сч < КоличествоСтрокТЗ/2) Цикл
        Если Сч%2 = 0 Тогда
            ТЗРезультат.Удалить(Сч);
        КонецЕсли;
        Сч = Сч + 1;
    КонецЦикла;

пересчет количества строк не будет - у Вас в переменной хранится (и процессор деление на два заменить на битовый сдвиг) - вы же не знаете сколько строк будет удалено. А тут у Вас известно - ровно половина. Этот алгоритм попахивает нечистотой эксперимента.
29. spacecraft 01.02.18 12:34 Сейчас в теме
(28)
Я даже не знаю как это комментировать. Неужели не понятно, что при удалении строки будет пересчет количества строк.

ок. смотрим (18):
Вообще - то количество строк вычисляется компилятором не при каждом обращении к функции КоличестроСтрок(), а просто возвращается из предвычисленного параметра. Т.к. КоличествоСтрок() - это просто функция которая возвращает свойство таблицы КоличествоСтрок. При удалении строки из этого свойства вычитается 1-ца, а при добавлении строки добавляется единица

Комментировать и правда нечего. Все и так понятно.
30. protexprotex 113 01.02.18 12:51 Сейчас в теме
(29) Если Вы удаляете из таблицы строку, то из переменной ответственной за хранение кол-ва строк в таблице вычитается 1-ца. Это не относится к тому, что каждый раз при обращении к функции Количество() таблицы значений программа будет каждый раз пробегаться по строкам таблицы и подсчитывать их количество - так никто не делает при разработке компилятора транслятора - делают через хранение кол-ва строк в отдельной переменной - свойстве класса. Это же элементарно :-)
32. spacecraft 01.02.18 12:55 Сейчас в теме
(30) действительно не понимаете о чем речь, или специально в другую сторону уводите?
Удаление строк одинаково в обоих случаях. Тест1 и Тест2.
Если не удалять строки, то разница во времени выполнения не принципиальная. Логично, вычисление ТЗ.Количество() просто кешируется.
Если происходит удаление, то Количество() каждый раз выполняется. И разница во времени становится уже очень заметна.
Так что не надо говорить, что с условием ТЗ.Количество() не будет разницы. Вот о чем речь.
Capitullo; +1 Ответить
31. protexprotex 113 01.02.18 12:53 Сейчас в теме
(29) А у Вас метод такой - Вы задаете программе сколько надо удалить строк, и начинаете это количество строк удалять. Вопрос - откуда Вы знаете сколько строк надо удалить?
как у Вас:
Пока (Сч < КоличествоСтрокТЗ/2) Цикл
Если Сч%2 = 0 Тогда
ТЗРезультат.Удалить(Сч);
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;

тут Вы откуда то еще до анализа таблицы уже знаете, что надо удалить половину строк таблицы.
33. spacecraft 01.02.18 12:56 Сейчас в теме
(31) смотрите алгоритм. В обоих Тест1 и Тест2 удаляются четные элементы. Это ровно половина выборки.
34. protexprotex 113 01.02.18 13:10 Сейчас в теме
(33) Ну а причем тут четные элементы выборки? - прочитайте постановку задачи у автора - ему надо удалить не четные элемент выборки, а анализировать строку на необходимость удаления. Зачем Вы делаете искусственные предположения, когда задача ясна из постановки?
35. spacecraft 01.02.18 13:34 Сейчас в теме
(34) мы не обсуждаем сейчас алгоритм автора топика. Мы обсуждаем утверждение, что:
Вообще - то количество строк вычисляется компилятором не при каждом обращении к функции КоличестроСтрок(), а просто возвращается из предвычисленного параметра. Т.к. КоличествоСтрок() - это просто функция которая возвращает свойство таблицы КоличествоСтрок. При удалении строки из этого свойства вычитается 1-ца, а при добавлении строки добавляется единица.

и второе противоречащее утверждение:
Я даже не знаю как это комментировать. Неужели не понятно, что при удалении строки будет пересчет количества строк.

Я привел абстрактный Тест проверки этих утверждений. Оба теста выполняют одинаковую работу. У обоих одинаковая итерация.
Capitullo; +1 Ответить
36. protexprotex 113 01.02.18 13:45 Сейчас в теме
(35) Ну, тогда таких искусственных алгоритмов можно много придумать которые будут быстрее работы некоторого алгоритма но уже в реальных данных. Ценность таких алгоритмов в чем? - просто доказать? - ну хорошо, Вы мне доказали. И?
38. spacecraft 01.02.18 13:52 Сейчас в теме
(36) ок. Вот еще тест:
&НаКлиенте
Процедура Тест3(Команда)
	ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сч = 0;
	Пока (Сч < ТЗРезультат.Количество()) Цикл
		Если Сч < 1000 Тогда
			ТЗРезультат.Удалить(Сч);
		Иначе 
			Прервать;
		КонецЕсли;
		Сч = Сч + 1;
	КонецЦикла;
	ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить("Тест3: Время выполнения: "+(ВремяОкончания - ВремяНачала));

КонецПроцедуры
Показать

Объясню алгоритм. Не важно сколько элементов в ТЗ. Всегда будут выполняться только проход и удаление первых 1000 элементов.
И вот итог:
Кол-во элементов в ТЗ | Время мсек
10 000 | 99
100 000 | 997
1 000 000 | 15 532

Показательно. Каждый раз именно рассчитывается количество элементов.
40. protexprotex 113 01.02.18 14:02 Сейчас в теме
(38) Нет, неправильно. При удалении строки производится перераспределение памяти. Если таблица большая, то и времени на перераспределение памяти больше. Это не относится к расчету кол-ва строк.
Аналог TList в c++ builder. Кстати, в предыдущих Ваших алгоритмах - тоже такая ситуация может быть. Т.к. все зависит от заполненности "кучи" памяти. И для чистоты эксперимента надо прогнать алгоритм раз 50 и потом усреднить.
41. spacecraft 01.02.18 14:13 Сейчас в теме
(40) как это соотносится с:
Т.к. КоличествоСтрок() - это просто функция которая возвращает свойство таблицы КоличествоСтрок. При удалении строки из этого свойства вычитается 1-ца, а при добавлении строки добавляется единица.

Предыдущие тесты (Тест1 и Тест2) оба удаляют строку. Временные затраты на это одинаковые.

Не надо притягивать алгоритмы с++ builder на работу 1С кода.
43. protexprotex 113 01.02.18 14:18 Сейчас в теме
(41) Относится просто - когда Вы удаляете строку из таблицы с кол-вом строк в 1000 - это одно, а когда из таблицы с кол-вом строк в 1000000 - это другое. Накладные расходы на перераспределение памяти в таблицах с разным кол-вом строк - разное. А по поводу c+++ builder - это я Вам пример привел просто для понимания - т.к. ТаблицаЗначений в 1С - это STL - контейнер. А TList в c++ builder - это динамический список очень похожий на STL - контейнер.
46. spacecraft 01.02.18 14:35 Сейчас в теме
(43) очередная попытка притянуть функциональность c++ builder к 1С.
В каком месте мы вызываем delete объекту? Согласно с++ объекты созданные в куче без явного удаления не уничтожаются.
Где мы выделяем память новому объекту?

Не стоит лезть во внутреннее строение платформы, не зная его механизмов.
48. protexprotex 113 01.02.18 14:40 Сейчас в теме
(46) delete вызывается неявно. Иначе бы при удалении строк/таблицы была бы утечка памяти. Это, я думал, все знают и не стал это писать.
То что Вы пишите - "Согласно с++ объекты созданные в куче без явного удаления не ничтожаются." - т.е. Вы хотите сказать, что когда я:
Табл = Новый ТаблицаЗначений
и потом
Табл = НеОпределено
память выделенная под Табл не возвращается операционке?
тогда сделайте миллиард Табл = Новый ТаблицаЗначений и также миллиард Табл = НеОпределено и посмотрите сколько памяти у Вас осталось. Уверяю - столько же.
"Где мы выделяем память новому объекту? " - когда делаете Новый (аналог new c++) - это и есть выделение памяти под новый объект.
49. spacecraft 01.02.18 14:42 Сейчас в теме
(48) ок. Скажу прямо: "сборка мусора" ничего не говорит?
52. protexprotex 113 01.02.18 14:47 Сейчас в теме
(49) Сборка мусора - это когда программа закрывается и планировщик вычищает не возвращенную память.
54. spacecraft 01.02.18 14:49 Сейчас в теме
(52) вот блин. Все программы на java и c# мертворожденные. Не успели загрузиться и уже выгружаются.
Дальше нечего обсуждать...
56. herfis 498 01.02.18 14:57 Сейчас в теме
(52) Ну, примерно в той же степени, как и ядерную атаку можно назвать сборкой мусора - мусор сгорит тоже :)
(53) Я терпел. Оскорблений больше не будет. Не вижу смысла продлжать разговор.
50. spacecraft 01.02.18 14:43 Сейчас в теме
(48)
Вы хотите сказать, что когда я:
Табл = Новый ТаблицаЗначений
и потом
Табл = НеОпределено
память выделенная под Табл не возвращается операционке?

Если вот это дословно перевести на c++, то да. Будет явная утечка памяти.
Потому и говорю, не надо прямую ассоциацию приводить с с++
42. herfis 498 01.02.18 14:16 Сейчас в теме
(40) Какое еще перераспределение памяти в связанных списках?
44. protexprotex 113 01.02.18 14:21 Сейчас в теме
(42) Перераспределение памяти при удалении строки, а не перераспределении в списке. Т.к. память высвобождается и отдается операционке для использования другими процессорами - иначе была бы утечка памяти (хотя, этого добра хватает в 1С :-) ). Или Вы думаете что это бесплатная операция? - и на нее не тратится тактов процессора?
45. herfis 498 01.02.18 14:27 Сейчас в теме
(44) Оставим спорный момент возврата памяти операционке (по каждому чиху этого не делают и уж в одинэсной ТЗ - точно). Каким образом накладные расходы на удаление одной строки зависят от размера таблицы?
47. protexprotex 113 01.02.18 14:36 Сейчас в теме
(45) Зависят очень просто - чем больше сама таблица - тем больше она занимает страниц памяти. При удалении строк которые находятся в разных дампах(страницах) памяти процу приходится активно переключаться между дампами (страницами). Если таблица маленькая, и она убирается в одну страницу, то работа происходит в контексте одной страницы. Это если организована постраничная адресация. Если используется плоская модель памяти - то тут, возможно (надо посмотреть) и не будет увеличения времени удаления. + ко всему прочему надо учитывать объем кеша проца и какой объем данных закеширован.
51. herfis 498 01.02.18 14:45 Сейчас в теме
(47) Еще раз - в (43) было заявлено, что удаление ОДНОЙ строки в таблице бОльшего размера займет больше времени.
И теперь пытаетесь подвести под это утверждение что? Что одна строка в большой таблице будет занимать несколько страниц памяти? И при каждом удалении строки будет осуществляться возврат памяти операционке? Признайтесь, что ошиблись и перестаньте нести бред.
Насчет возврата памяти операционке - ознакомьтесь со значением слова "куча", которое вы тут употребляли и как она работает.
53. protexprotex 113 01.02.18 14:49 Сейчас в теме
(51) Ну не надо кидаться словами "бред". Строка может занимать память между двумя страницами - в конце одной и в начале другой. Давайте без оскорблений.
55. spacecraft 01.02.18 14:56 Сейчас в теме
(53) даже с++ не работает с ячейками памяти напрямую (если только специально взламывать). Она работает с виртуальным адресным пространством, которое ему выделяет ОС.
В итоге много терминов без понимания их сути.
62. Cool_vsi 24.11.21 11:08 Сейчас в теме
(6) для старый платформ вместо Строка = ТаблицаДанных.ПолучитьСтроку (Сч); пишем Строка = ТаблицаДанных.Получить (Сч);

в моей версии платформы нет такого метода для таблицы значений

и спс за это решение!
63. kabantus 14.03.23 14:17 Сейчас в теме
(6)
Строка = ТаблицаДанных.ПолучитьСтроку (Сч);

Без опечатки: Строка = ТаблицаДанных.Получить (Сч);
2. kild 89 31.01.18 21:59 Сейчас в теме
(1) Кусок кода выложите как у вас удаление реализовано из тз
9. Metabos 29 31.01.18 22:32 Сейчас в теме
(2)
Для каждого Строка из ТЗ Цикл 
		НайденнаяСтрока = Список.Найти(Строка.Колонка, "Колонка"); 
		Если НайденнаяСтрока = Неопределено Тогда 
			ТЗ.Удалить(Строка);
		КонецЕсли;
	КонецЦикла;
11. YanTsys 12 31.01.18 22:35 Сейчас в теме
(9)
УдаляемыеСтроки=новый массив;
Для каждого Строка из ТЗ Цикл 
	НайденнаяСтрока = Список.Найти(Строка.Колонка, "Колонка"); 
	Если НайденнаяСтрока = Неопределено Тогда 
              УдаляемыеСтроки.Добавить(Строка);
	КонецЕсли;
КонецЦикла;
Для Каждого УдаляемаяСтрока из УдаляемыеСтроки Цикл
 ТЗ.Удалить(УдаляемаяСтрока);
КонецЦикла;
Показать
4. YanTsys 12 31.01.18 22:17 Сейчас в теме
Самый простой вариант:

УдаляемыеСтроки=новый массив;
Для Каждого СтрокаТЗ из ТЗ Цикл
 Если СтрокаТЗ.Сумма<0 Тогда
  УдаляемыеСтроки.Добавить(СтрокаТЗ);
 КонецЕсли;
КонецЦикла;
Для Каждого УдаляемаяСтрока из УдаляемыеСтроки Цикл
 ТЗ.Удалить(УдаляемаяСтрока);
КонецЦикла;
Показать
klaus38; slitov; PowerBoy; KoC_one; ru_spaiky; pisanko; zba; herfis; +8 Ответить
37. herfis 498 01.02.18 13:51 Сейчас в теме
(4) Тоже всегда делаю именно так. Это самый наглядный и легко читаемый вариант из всех.
KoC_one; YanTsys; +2 Ответить
14. Metabos 29 31.01.18 22:49 Сейчас в теме
Спасибо всем. Нашла решение, которое показалось самым простым.
17. kild 89 31.01.18 23:13 Сейчас в теме
(14) Вот самый быстрый и просто способ из всех:

	 Индекс = ТаблицаЗначений.Количество() - 1; 
	 Пока Индекс >= 0 Цикл   		
	     Если УсловиеДляУдаленияСтроки(ТаблицаЗначений[Индекс]) Тогда      
	    	 ТаблицаЗначений.Удалить(Индекс);                              
	     КонецЕсли;         			
	     Индекс = Индекс - 1;                                                                         
	 КонецЦикла;
Показать
Xershi; YanTsys; +2 Ответить
20. Xershi 1474 01.02.18 09:38 Сейчас в теме
(17) одно из решений ответа из (3)!
22. Metabos 29 01.02.18 10:22 Сейчас в теме
(20) А почему с конца не будет такого?
23. Xershi 1474 01.02.18 10:39 Сейчас в теме
(22) ответ на ваш вопрос дан в (3).
59. ildarovich 7850 01.02.18 16:15 Сейчас в теме
(17) Этот способ только на первый взгляд самый быстрый. Во-первых, его можно записать короче:
   Для Индекс = - РабочаяТаблица.Количество() + 1 По 0 Цикл
		Если РабочаяТаблица[- Индекс][0] = 0 Тогда // условие удаления
			РабочаяТаблица.Удалить(- Индекс)
		КонецЕсли
	КонецЦикла
Во-вторых, даже в таком виде он выполняется примерно столько-же, сколько (7). Метод в (7) экономит на времени итерации переменной цикла, которая оказывается не нужна, когда элемент удален.
Но оба они (7) и (16) сильно проигрывают (примерно в два раза) методу с предварительным отбором списка удаляемых строк через НайтиСтроки() как в (5).
60. herfis 498 01.02.18 16:41 Сейчас в теме
(59)
Но оба они (7) и (16) сильно проигрывают (примерно в два раза) методу с предварительным отбором списка удаляемых строк через НайтиСтроки() как в (5).

А за счет чего такой сильный проигрыш? Доступ по индексу такой медленный?
39. herfis 498 01.02.18 13:54 Сейчас в теме
Если кого-то из академического интереса интересует "самый быстрый" способ, то даже конкурсы проходили - можно найти готовые обработки со сравнительным тестированием различных способов.
57. МихаилМ 01.02.18 15:09 Сейчас в теме
+(39)
на хиппо для 7.7 был первый конкурс на самое быстрое удаление строк из ТЗ с призами году в 2002. потом на мисте был конкурс для 8.1. не увидел метода копирования ТЗ с отбором обратным условием.
ildarovich; +1 Ответить
58. ildarovich 7850 01.02.18 15:29 Сейчас в теме
(57) Этот метод (копирования) самый быстрый, примерно в 10 раз быстрее на миллионе строк:
РабочаяТаблица = РабочаяТаблица.Скопировать(Новый Структура("Колонка1", 1))
Здесь удаляются строки с нулями, оставляются с единицей в Колонке1.
marinelle; Simonov_NPM; +2 Ответить
61. iCortezik 8 04.03.20 07:57 Сейчас в теме
Пока ТаблицаДанных.НайтиСтроки(Новый структура("Сумма", 0)).Количество() > 0 Цикл
	ТаблицаДанных.Удалить(ГруппыНоменклатуры.НайтиСтроки(Новый структура("Сумма", 0))[0]);	
КонецЦикла;


Хоть и поздно, но сейчас тоже гуглил эту проблему, попробовал лучший ответ, не вышло, но нашел свой вариант
kabantus; +1 Ответить
64. Xershi 1474 19.09.23 17:25 Сейчас в теме
Когда строк для удаления мало оптимально такой код.
Мы не гоняем данные в памяти, а просто перебираем.
Как говорится под каждую задачу, свое решение!
	
	Для Каждого Строка Из ОбъектыОшибок Цикл
		
		Если Строка.Ключ = "2" И ТипЗнч(Строка.Объект) = Тип("ДокументСсылка.УстановкаЦенНоменклатуры") Тогда
			
			ТекущийОбъект = Строка.Объект.ПолучитьОбъект();
			
			Если ТекущийОбъект <> Неопределено Тогда
				
				НужноЗаписать = Ложь;
				
				Товары = ТекущийОбъект.Товары;				
				
				КоличествоСтрок = Товары.Количество();
				
				ТекущийИндекс = КоличествоСтрок - 1;
				
				Пока ТекущийИндекс >= 0 Цикл
					
					СтрокаТовары = Товары.Получить(ТекущийИндекс);
					
					Если СтрокаТовары.Номенклатура.ЭтоГруппа Тогда
						
						Товары.Удалить(СтрокаТовары);
						
						НужноЗаписать = Истина;
						
					КонецЕсли;
					
					ТекущийИндекс = ТекущийИндекс - 1;
										
				КонецЦикла;
				
				Если НужноЗаписать Тогда
				
					ТекущийОбъект.Записать();
					
				КонецЕсли;
				
			КонецЕсли;
			
		КонецЕсли;	
		
	КонецЦикла;
Показать

В УПП умудрились папку впихнуть в документ.
65. пользователь 19.09.23 18:29
Сообщение было скрыто модератором.
...
Оставьте свое сообщение
Вакансии
Программист 1С
Москва
зарплата от 180 000 руб. до 220 000 руб.
Полный день

Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)

Программист 1С
Москва
зарплата от 250 000 руб.
Полный день

Программист 1C
Волгоград
зарплата от 200 000 руб.
Полный день

Аналитик
Санкт-Петербург
зарплата от 200 000 руб. до 250 000 руб.
Полный день