|
Удаление строк из таблицы значений по номеру | ☑ | ||
---|---|---|---|---|
0
Likons
12.01.20
✎
23:53
|
Доброго времени суток , коллеги. Пожалуйста , помогите с простой задачкой :
Есть Таблица Значений в ней есть колонка , значения в которой могут повторятся , но считать такие строки одниковыми нельзя , т.к. значение в других колонках отличаются. Цель - удалить строки с повторяющимися значениями из таблицы. Вот , что у меня получилось : НомераСтрокДляУдаления = ПоискДублейСтрокВТабЧасти(СписокДокументов,Ложь); Для каждого СтрокаСпискаДокументов из СписокДокументов цикл Для каждого Элемент из НомераСтрокДляУдаления цикл СписокДокументов.Удалить(Элемент.Значение); КонецЦикла; КонецЦикла; ПоискДублейСтрокВТабЧасти - Функция , которая возвращает список значений с номерами строк , которые необходимо удалить. СписокДокументов - Таблица , из которой эти самые строки и нужно удалить. При попытке запуска , говорит "Значение индекса выходит за границы диапозона" , хотя номера строк 100% корректны. Подскажите , пожалуйста , что я не так делаю ?( |
|||
1
acht
13.01.20
✎
00:07
|
(0) У вас же, Андрей Николаевич, после удаления номера строк в таблице меняются. Вот удалили вы девятую, и хоп - на ее место встала новая, которая раньше десятая была. И все осатльны также. А вы их у себя по прежним номерам учитываете.
|
|||
2
Garykom
гуру
13.01.20
✎
00:30
|
(0) В хз какой раз повторю: Не надо удалять строки из ТЗ. Просто копируй только нужные строки в НОВУЮ ТЗ.
|
|||
3
Фрэнки
13.01.20
✎
00:38
|
и программировать намного проще - строк меньше
|
|||
4
GreyK
13.01.20
✎
01:14
|
(0) Это ты таблицу запроса редактируешь?
|
|||
5
Likons
13.01.20
✎
01:27
|
(2) (1) Спасибо вам , добрые люди , помогли ) Теперь выгружаю данные запроса во временную таблицу , а в основную таблицу добовляю строки только по условию) Еще раз , спасибо большое )
|
|||
6
Chameleon1980
13.01.20
✎
04:57
|
удали с конца
|
|||
7
NUser
13.01.20
✎
05:13
|
(0)Нужен массив с индексами строк которые нужно удалить и уже при его обходе удалять
|
|||
8
NUser
13.01.20
✎
05:13
|
..из таблицы значений
|
|||
9
RomaH
naïve
13.01.20
✎
07:08
|
(2) почему?
(0) ТаблицаЗначений (ValueTable) Удалить (Delete) Вариант синтаксиса: Удаление по объекту Синтаксис: Удалить(<Строка>) МассивКУдалению.Добавить(ТЗ[]); Для каждого СтрокаТЗ Из МассивКУдалению Цикл ... |
|||
10
mzelensky
13.01.20
✎
07:58
|
(2) Даже если в таблице 1000 строк, а удалить нужно только 1 ?
|
|||
11
Сияющий в темноте
13.01.20
✎
08:59
|
обычно,если хочется чего-то поудалять,то или обход таблицы значенийис конца или сбор удаляемых строк в массив,а потом удаление проходом по этому массиву.
|
|||
12
Фрэнки
13.01.20
✎
09:01
|
(10) так ее не только удалить нужно, но и обойти весь массив, причем, не один раз.
|
|||
13
mzelensky
13.01.20
✎
09:18
|
(12) Почему не один?
(11) (12) Делаешь обход таблицы с конца к началу и просто удаляешь строки, без каких либо массивов, в один проход. |
|||
14
Garykom
гуру
13.01.20
✎
10:11
|
(9) (13) Потому что пора бы уже знать что платформа 1С при удалении каждой строки по одной копирует ТЗ в новое место в оперативке без этой удаленной.
|
|||
15
mikecool
13.01.20
✎
10:22
|
(14) шикарно! а это где то описано или из личных наблюдений?
|
|||
16
Garykom
гуру
13.01.20
✎
10:26
|
(15) Проведи тестирование с засеканием времени на скорость копирования ТЗ и удаления строки
|
|||
17
DES
13.01.20
✎
10:28
|
а метод Свернуть() не поможет?
|
|||
18
Garykom
гуру
13.01.20
✎
10:28
|
(16)+ Еще занятую оперативку контролируй, сделай большую ТЗ и удаляй строчек много - офигеешь как оперативка будет того ))
|
|||
19
Garykom
гуру
13.01.20
✎
10:30
|
(17) Предлагаешь добавить колонку, пронумеровать нужные строки а все ненужные свернуть в одну? Так последнюю строчку схлопнутую один хрен надо удалить потом.
Ну и Свернуть() тоже работает на копировании. |
|||
20
Garykom
гуру
13.01.20
✎
10:30
|
(19)+ Точнее не копировании а на создании новой ТЗ
|
|||
21
DES
13.01.20
✎
10:36
|
(19) зачем что то еще удалять? Это аналогично Запрос различные.
|
|||
22
Garykom
гуру
13.01.20
✎
10:37
|
(19)+ Но метод с добавлением новой колонки правильный.
Туда пишем 1 которые нужны и 0 которые не нужны это один проход будет. Затем ТЗ = ТЗ.Скопировать(Новый Структура("ИмяКолонки", 1)) |
|||
23
DES
13.01.20
✎
10:52
|
(22) Метод Свернуть() сам удаляет ненужные.
|
|||
24
Garykom
гуру
13.01.20
✎
10:53
|
(23) Подумай слегка или попробуй сделать
|
|||
25
DES
13.01.20
✎
11:02
|
ТаблицаОтбора = Новый ТаблицаЗначений();
ТаблицаОтбора.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); ТаблицаОтбора.Колонки.Добавить("ПутьКДанным", Новый ОписаниеТипов("Строка")); ТаблицаОтбора.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка")); ТаблицаОтбора.Колонки.Добавить("ВидСравнения", Новый ОписаниеТипов("ВидСравнения")); ТаблицаОтбора.Колонки.Добавить("Значение"); ТаблицаОтбора.Колонки.Добавить("ЗначениеС"); ТаблицаОтбора.Колонки.Добавить("ЗначениеПо"); ТаблицаОтбора.Свернуть("Имя,ПутьКДанным,Представление,ВидСравнения,Значение,ЗначениеС,ЗначениеПо",""); |
|||
26
DES
13.01.20
✎
11:03
|
Надеюсь что дублей не будет, а ты что скажешь?
|
|||
27
Garykom
гуру
13.01.20
✎
11:05
|
(25) (26) Мы друг друга не поняли.
Согласен что для задачи ТС твой вариант лучше. Я же говорил про произвольное удаление строк а не удаление дублирующихся по данным строк. |
|||
28
1Сергей
13.01.20
✎
11:08
|
(0)
НомераСтрокДляУдаления = ПоискДублейСтрокВТабЧасти(СписокДокументов,Ложь); //Для каждого СтрокаСпискаДокументов из СписокДокументов цикл Для каждого Элемент из НомераСтрокДляУдаления цикл СписокДокументов.Удалить(Элемент.Значение); КонецЦикла; //КонецЦикла; |
|||
29
Злопчинский
13.01.20
✎
14:00
|
а можно отсортировать ТЗ, пройти, проставить в допколонек 1 для удаляемых (суммируем заодно счетчик удаляемых), отсортировать по возрастанию Допколонки и тупо обрезать ТЗ.КоличествоСтрок(ТЗ.КоличествоСтрок()-КолвоУдаляемых).
. или так в 8-ке не прокатит? |
|||
30
mikecool
13.01.20
✎
14:02
|
(16) ага, я же и говорю - в документациях такого не встречал
|
|||
31
dk
13.01.20
✎
14:20
|
переходите на 1с 77 - там нормально все с удалением из тз )
|
|||
32
victuan1
13.01.20
✎
19:39
|
(31) Нет, не нормально, тоже тормоза при удалении строки из середины ТЗ. Если речь о стандартной ТЗ, а не ИТЗ.
|
|||
33
Garykom
гуру
13.01.20
✎
19:45
|
(32) Там ТЗ тоже не на связанных списках реализована а на массивах указателей, которые ссылаются на строки.
Поэтому там в 1с 7.7 тоже самое шустрое удаление это через копирование нужных строк в новую ТЗ. Доказано неоднократно. |
|||
34
GreyK
13.01.20
✎
20:21
|
(29) В 8ке немного попроще, можно создать массив строк и удалить их не по номеру строки, а массив можно создать поиском в тз с отборами.
|
|||
35
Злопчинский
13.01.20
✎
22:03
|
(33) и как такое "копирование" выглядит в виде прикладного кода?
напрямую из одной ТЗ в другую ТЗ простым "копированием" - я навскидку в 77 не знаю. без извращений - только перебором по колонкам текущей строки Цикл По Колонкам ТЗПолучатель.УстановитьЗначение(текстрока, текколонка,ТЗИсточник.ПолучитьЗначение(текстрока0,текколонка) КонецЦикла; . или как-то хитрее можно?!?! . можно конечно выгруизть одну строку из тзисточник в тзбуфер, а потом тзполучатель.заполнить(тзбуфер...) . но я как-то замеров не производил по сравнению быстродействия, сказать что быстрее - не могу... |
|||
36
dk
14.01.20
✎
07:18
|
(32) (33) что-то вы гоните товарищи, никакого копирования тз при удалении строки не происходит, по крайней мере память в диспетчере не меняется у процесса
|
|||
37
dk
14.01.20
✎
07:20
|
в 1с 77
|
|||
38
dmpl
14.01.20
✎
07:45
|
(31) В 7.7 программное (средствами языка 1С) сворачивание оказывается быстрее, чем методом Свернуть(), если в ТЗ примерно 1000 строк и более. Причем разница в разы. На ТЗ из нескольких сотен тысяч строк метод Свернуть() выполняется часами, а на встроенном языке - около 1 минуты.
|
|||
39
Garykom
гуру
14.01.20
✎
07:55
|
(36) Копируются не данные в ТЗ а только таблица указателей на строки.
Данные строк на своих местах остаются лежать до момента работы сборщика мусора. Чтобы было заметно надо сотни тысяч и миллионы строк в ТЗ и из нее удалять. |
|||
40
dk
14.01.20
✎
08:01
|
(39) короче нормально все работает
ясень пень если удалить надо 90% то быстрее 10% загрузить в новую вместо удаления |
|||
41
Garykom
гуру
14.01.20
✎
11:09
|
(40) Нет, если удалить надо 10% то быстрее 90% загрузить в новую.
|
|||
42
ДенисЧ
14.01.20
✎
11:11
|
(38) "Программное (средствами языка 1С) сворачивание оказывается быстрее, чем методом Свернуть()"
А свернуть() - это не средствами языка? |
|||
43
Wist
14.01.20
✎
11:13
|
Через перебор строки из таблицы удаляются в обратном цикле (от последней строки к первой). Не благодарите
|
|||
44
Wist
14.01.20
✎
11:17
|
Если есть массив с номерами строк для удаления, то аналогично, сортируете его по убыванию и последовательно удаляете от наибольшего индекса к наименьшему
|
|||
45
Злопчинский
14.01.20
✎
11:32
|
(38) пример кода такой свертки, плиз
|
|||
46
Калиостро
14.01.20
✎
11:41
|
(38) Это что-то типа процедуры РассчитатьИтогиПоГруппам в отчете ОстаткиТМЦ в типовой ТиС?
|
|||
47
dmpl
14.01.20
✎
12:56
|
(42) Свернуть() - это средствами платформы.
|
|||
48
dmpl
14.01.20
✎
13:00
|
(45)(46) Этому коду уже лет 15, найти будет сложно. Там принцип, НЯП, был отсортировать исходную таблицу и потом обойти ее, добавляя строки в новую таблицу при изменении какого-нибудь из сворачиваемых полей и суммируя группируемые поля.
|
|||
49
Злопчинский
15.01.20
✎
01:08
|
(48) мутный алгоритм. смысл ясен, но навкидку даже туго соображаю. это по сути рекурсиваная группировка получится...
|
|||
50
Сияющий в темноте
15.01.20
✎
09:09
|
копирование таблицы указателей илм перенос указателей со сдвигом операции не столь затратные
а строка таблицы это отдельный обьект,поэтому он отдельно в памяти живет. |
|||
51
dmpl
15.01.20
✎
10:55
|
(49) Штатный метод свертки имеет степенную зависимость времени исполнения от количества строк в таблице (т.е. при увеличении количества строк в 2 раза время выполнения увеличивается в 4 раза, при увеличении количества строк в 10 раз - время увеличивается уже в 100 раз, в итоге достаточно быстро мы упираемся в время порядка часов и дней). За показатель степени 2 не ручаюсь (давно дело было), это просто чтобы показать принцип. При программной реализации зависимость почти линейная, т.к. сортировка выполняется за достаточно малое время (в процентном отношении), а основное время занимает обход таблицы, у которого зависимость от количества строк линейная.
|
|||
52
LOLYBUF
15.01.20
✎
11:09
|
А можно занать ТЗ в менеджер временных таблиц и сделать запрос с группировкой?
|
|||
53
LOLYBUF
15.01.20
✎
11:09
|
(52) Загнать*
|
|||
54
Злопчинский
15.01.20
✎
12:51
|
(51) а попытаться найти код упоминаемый все-таки?
|
|||
55
Garykom
гуру
15.01.20
✎
13:24
|
(52) В 1С 7.7?
И даже в 1С 8 нет смысла использовать ВТ и запросы, там будут дикие потери времени на передачу в запрос и получение назад данных. |
|||
56
Сияющий в темноте
15.01.20
✎
18:24
|
а что мы хотим от свертки?
свернуть и просуммировать или только свернуть? опять же,линейной зависимости быть не может,нужно отсортировать,а потом пройти если просто проходом,то будет поиск по уже существующим строкам,он хоть и индексированный,но тоже время займет. |
|||
57
LOLYBUF
15.01.20
✎
19:54
|
(55) Понял, принял, обработал
|
|||
58
Garykom
гуру
15.01.20
✎
20:52
|
Самый быстрейший способ удаления множества строк из ТЗ (по сложному условию) или свертки ТЗ (с суммированием особо) это пока остается сериализация/десериализация средствами платформы и обработка чем то внешним.
ВК или еще что. Если просто удалять много строк по номерам (простое условие) то копирование нужных строк в новую ТЗ по скорости равно сериализации/десериализации и внешней обработке. Где проходит граница % строк к удалению как лучше только тестами, причем в разных версиях платформы возможно оно будет по разному. |
|||
59
Garykom
гуру
15.01.20
✎
21:23
|
Интересно потестить когда ТЗ кидаем в ХранилищеЗначения, затем это хранилище в файл и дальше обрабатывать уже файл внешним.
Например код для 100к строк отрабатвыет у меня мгновенно
|
|||
60
Garykom
гуру
15.01.20
✎
21:25
|
(59)+ Для миллиона строк 20 секунд
15.01.2020 21:24:24 Начали тест, КоличествоСрок = 1 000 000 15.01.2020 21:24:24 Заполнение ТЗ, начало 15.01.2020 21:24:35 Заполнение ТЗ, конец 15.01.2020 21:24:35 Запись ТЗ в хранилище, начало Имя файла: C:\Users\Gary\AppData\Local\Temp\v8_B07B_67.tmp 15.01.2020 21:24:43 Запись ТЗ в файл, начало 15.01.2020 21:24:44 Запись ТЗ в файл, конец 15.01.2020 21:24:44 Закончили тест, КоличествоСрок = 1 000 000 Размер файла 103 метра |
|||
61
Garykom
гуру
15.01.20
✎
21:27
|
(60)+ Осталось расхреначить формат ТЗ внутри хранилища чтобы обработать некой ВК и обратная загрузка сча потестю.
|
|||
62
Garykom
гуру
15.01.20
✎
21:31
|
(61) Читает тоже замечательно в ТЗ из файла, всего 4 секунды для ляма строк
|
|||
63
Garykom
гуру
15.01.20
✎
21:34
|
Для хранилища поставил сжатие 0, но файл непонятного вида
https://i.paste.pics/b0c7691f94720bcd708587bdeba4b30f.png Как бы это дело того, внутри ТЗ лежит. |
|||
64
Garykom
гуру
15.01.20
✎
21:44
|
(63)+ Хехе, для двух строчек:
{"#",acf6192e-81ca-46ef-93a6-5a6968b78663, {9, {2, {0,"", {"Pattern"},"",0}, {1,"", {"Pattern"},"",0} }, {2,2,0,0,1,1, {1,2, {2,0,2, {"S","c3fd8ff4-f441-4190-bc9e-7fc523d12e0a"}, {"N",1},0}, {2,1,2, {"S","3eb5a58a-7f9f-4956-af80-5355ee24dca5"}, {"N",1},0} },-1,1}, {0,0} } } Короче base64 это если начало отрезать, странно что сам не догадался раз XMLСтрока А внутри обычное ЗначениеВСтрокуВнутр |
|||
65
Злопчинский
17.01.20
✎
20:24
|
ну это ты потестил только один вариант...
а удалить по массиву удаляемых строк? а удалить сортировокй, поиском первого отрезаемого и отрезкой количествоСтрок(сколькооставить) если такое работает в 8-ке? .. и прочие варианты? |
|||
66
Garykom
гуру
17.01.20
✎
21:20
|
(65) Глубоко пофиг.
Если все эти действия выполнять снаружи чем то типа С++ то там от 1С уже не зависит и можно добиться максимально возможной на железе скорости. |
|||
67
Злопчинский
17.01.20
✎
22:03
|
(66) ну так речь про то чтобы выполнять внутри 1С
|
|||
68
Garykom
гуру
17.01.20
✎
22:44
|
(67) Тогда нет ничего лучше чем копировать нужные строки в новую ТЗ тупо по одной.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |