|
v7: Быстрый вариант сравнить справочник с ТЗ. | ☑ | ||
---|---|---|---|---|
0
bizon2008
23.07.12
✎
14:13
|
День добрый. Подскажите люди добрые быстрый вариант сравнить справочник с ТЗ. Грубо горя вот примет. Есть ТЗ с загружены в нее списком код, значение. Надо по коду найти элемент справочника, и сравнить значение, ели отличаются записать из ТЗ. В лоб это цикл в цикле, дороговато будет.
Заранее благодарен. |
|||
1
1Сергей
23.07.12
✎
14:17
|
не нужен там цикл в цикле
|
|||
2
Classic
23.07.12
✎
14:17
|
Так как вариантов пока нет, предложу Сортировать + ПорядокКодов(). Достаточно будет одного обхода. Особенно если сразу в ТЗ сортированно по коду писать
|
|||
3
ptrtss
23.07.12
✎
14:23
|
Я делаю ТЗ с доп. колонкой "Версия". С Версия=-1 кидаю в неё например справочник,а с версия=+1 кидаю исходную ТЗ. Потом сворачиваю.
Версия=0: все ок Версия=1: есть в ТЗ, нет в справочнике Версия=-1: есть в справочнике, нет в ТЗ |
|||
4
ptrtss
23.07.12
✎
14:24
|
В некоторых случаях, когда надо разово сравнить, удобно пользоваться сводными таблицами Екселя
|
|||
5
Cthulhu
23.07.12
✎
14:26
|
"сравнить значение..." - как ссылку на данные (агрегатного типа)
"сравнить значения реквизитов найденного по коду элемента справочника ..." - другое дело. чонадото? |
|||
6
bizon2008
23.07.12
✎
14:27
|
(1)Как это? В цикле идем по ТЗ, в каждой итерации еще цикл опрашиваем справочник, надо как-то ТекущийЭлемент() получить? Ну или запрос, еще можно.
|
|||
7
1Сергей
23.07.12
✎
14:30
|
(6) НайтиПоКоду, НайтиПоНаименованию, НайтиПоРеквизиту, НайтиЭлемент, НайтиЗначение
|
|||
8
bizon2008
23.07.12
✎
14:31
|
(5)Надо. Есть данные в ТЗ, код и значение, надо найти элемент справочника с таким кодом и проверить значение, если значение отличается, то записать значение в справочник из ТЗ
|
|||
9
Aleksey
23.07.12
✎
14:31
|
Запросом?
|
|||
10
bizon2008
23.07.12
✎
14:31
|
(7)НайтиПоКоду ни разу не цикл? А что-то то медленно работает.
|
|||
11
Classic
23.07.12
✎
14:32
|
(8)
ТЗ сортирована? Можно ли ее заполнять уже сортированной? |
|||
12
Cthulhu
23.07.12
✎
14:32
|
(8): ещё раз. по слогам. что такое "проверить значение"?
|
|||
13
bizon2008
23.07.12
✎
14:32
|
(9)Запросом нельзя записать.
|
|||
14
bizon2008
23.07.12
✎
14:33
|
(12)На равенство. Если не равны, записать в справочник из ТЗ.
|
|||
15
Cthulhu
23.07.12
✎
14:36
|
(14): ещё раз. по слогам. даже по буквам. перечитать три раза прежде чем отвечать:
на равенство чего? наименований? кодов? непериодических реквизитов? истории периодических реквизитов? значений периодических реквизитов на конкретную дату? внутренних ИД (ссылок на объектные тирпы данных)? |
|||
16
Aleksey
23.07.12
✎
14:39
|
(13) Запросом можно отобрать нужные элементы, которые надо записать
|
|||
17
bizon2008
23.07.12
✎
14:42
|
(15)Пусть будет, для простоты, просто реквизит, целочисленный. Дальше посмотрим.
(16)И опять цикл, для записать. |
|||
18
Aleksey
23.07.12
✎
14:44
|
Как хочешь, просто так тебе нужно получать все объект с сервера, а так ты получишь только те которые нужно менять
|
|||
19
bizon2008
23.07.12
✎
14:47
|
(18)Хочу быстро. Пока получается медленно.
|
|||
20
varelchik
23.07.12
✎
14:48
|
(0)
Какой же вы тупой(С легким паром.) Тебеж сказали 1.Цикл по ТЗ. 2.В цикле Спр.НайтиПоКоду(ТЗ.Код) 3. Если Спр.НужноеЗначение<>ТЗ.Значение Тогда Спр.НужноеЗначение=ТЗ.Значение Спр.Записать() КонецЕсли |
|||
21
Classic
23.07.12
✎
14:49
|
(20)
Это и есть цикл в цикле |
|||
22
Cthulhu
23.07.12
✎
14:49
|
(17): тогда один проход по ТЗ с поиском элемента и сравнением "одного реквизита целочисленного" элемента из ТЗ и найденного по коду элемента. но, блин, я даже боюсь предположить, как на основании равенства значения не(!)уникального в общем случае реквизита делать вывод об "равенстве элементов"..
|
|||
23
bizon2008
23.07.12
✎
14:49
|
(20)И 12 часов подождать.
|
|||
24
varelchik
23.07.12
✎
14:50
|
Вот только на сколько я понял вы уважаемый не верно вопрос сформулировали (тему)
|
|||
25
Cthulhu
23.07.12
✎
14:50
|
(23): по 50$/час - сколько угодно.
|
|||
26
Cthulhu
23.07.12
✎
14:50
|
(24): о. и ты заметил?.. )))
|
|||
27
bizon2008
23.07.12
✎
14:50
|
(22)Для ключа сравнения используется код, он уникальный.
|
|||
28
varelchik
23.07.12
✎
14:50
|
Дану?
И что ж это за такая ТЗ и Справочник? |
|||
29
Classic
23.07.12
✎
14:51
|
(23)
Ответь на (11) Для двух сортированных массив достаточно n+m обходов |
|||
30
bizon2008
23.07.12
✎
14:52
|
(29)Можно отсортировать по коду. По возрастанию или убыванию.
|
|||
31
varelchik
23.07.12
✎
14:52
|
Это ж какая тз должна быть (а справочник темболее), что бы перебор строк тз занимал 12 часов?
|
|||
32
bizon2008
23.07.12
✎
14:53
|
(31)Пару миллиардов записей устроит?
|
|||
33
Classic
23.07.12
✎
14:58
|
(30)
Семерку уже забыл. Вроде есть такая фигня как ПорядокКодов() для выборки. Если есть то алгоритм приблизительно такой. ТЗ.ВыбратьСтроки(); ТЗ.ПолучитьСтроку(); Спр.ВыбратьЭлементы(); Спр.ПолучитьЭлемент(); Пока 1 = 1 Цикл Если ТЗ.Код < Спр.Код Тогда Если ТЗ.ПолучитьСтроку() = 0 Тогда Прервать Иначе Продолжить КонецЕсли КонецЕсли; Если ТЗ.Код > Спр.Код Тогда Если Спр.ПолучитьЭлемент() = 0 Тогда Прервать Иначе Продолжить КонецЕсли; КонецЕсли; Если ТЗ.Код = Спр.Код Тогда /// делаем что нам надо КонецЕсли; КонецЦикла; |
|||
34
bizon2008
23.07.12
✎
15:00
|
(33)Хм. Пойду попробую. что-то в этом есть.
|
|||
35
Classic
23.07.12
✎
15:02
|
(34)
Ну само собой что ТЗ должна быть отсротирована по возрастанию кодов. И выборка справочника должна идти тоже по возрастанию |
|||
36
Aprobator
23.07.12
✎
15:04
|
не понял. В одной колонке код справочника, а в другом значение и не сравнить
КолонкаСКодом.Значение = КолонкаСоЗначением.Значение.Код? |
|||
37
varelchik
23.07.12
✎
15:05
|
(32)
А сколько тоди в справочнике? (33) Вы что с дубу съехали? Вот туто тормоза и будут. НайтиПоКоду() самый быстрый из вариантов. Спр=СоздатьОбъект("Справочник.Мой"); ТЗ.ВЫбратьСтроки(); НачатьТранзакцию(); Пока ТЗ.ПолучитьСтроку()=1 Цикл ЕСли Спр.НайтиКоду(ТЗ.Код)=0 тогда сообщить("Не нашли по коду"+ТЗ.Код); КонецЕСли; ЕСли ТЗ.Значение<>Спр.ТоЧтоБудемСравникать Тогда Спр.ТоЧтоБудемСравникать=Тз.Значение; Спр.Записать(); КОнецЕсли; КонецЦикла; ЗафиксироватьТранзакцию(); |
|||
38
Cthulhu
23.07.12
✎
15:06
|
(35): "синхронный перебор отсортированных списков с поиском совпадения по ключу сортировки" называется. в принципе вряд ли быстрее перебора одного списка с поиском по первичному ключу в другом списке.
|
|||
39
Classic
23.07.12
✎
15:07
|
(38)
Я в терминологии не силен :) |
|||
40
Cthulhu
23.07.12
✎
15:10
|
(39): это скорее "называние вещей своими именами".
как в той притче про китайского императора. "ну сам подумай - если мы с тобой не будем знать, как это правильно называется - то откуда мы сможем догадаться, что с этим можно сделать???" (с) |
|||
41
Aprobator
23.07.12
✎
15:10
|
во народ отжигает.
|
|||
42
Aprobator
23.07.12
✎
15:11
|
зачем искать по коду то?
|
|||
43
Прохожий
23.07.12
✎
15:12
|
Запросом найти различия и тупо записать строки, полученные запросом в соответствующие элементы. Не забывать про транзакции...
|
|||
44
Cthulhu
23.07.12
✎
15:12
|
(42): точно. ".НайтиЭлемент()" и сравнить коды. )))
|
|||
45
Cthulhu
23.07.12
✎
15:13
|
а ещё можно попробовать использовать рекурсию... для особо нуждающихся в извращениях...
|
|||
46
Aprobator
23.07.12
✎
15:14
|
(44) он уже есть - рядом!!!!
|
|||
47
Classic
23.07.12
✎
15:14
|
(44)
А что в качестве параметры НайтиЭлемент() писать? В ТЗ только код и мифическое значение(я так понял, что не ссылка) |
|||
48
Aprobator
23.07.12
✎
15:14
|
колонка код и колонка значение. Чего еще искать то?
|
|||
49
Aprobator
23.07.12
✎
15:14
|
или ТС что то другое имел ввиду?
|
|||
50
Classic
23.07.12
✎
15:15
|
+(47) Потому что если ссылка, то конечно жесть :)
|
|||
51
vde69
23.07.12
✎
15:16
|
http://programmist1c.ru/st_programming/st_algoritm_sinhron_2_table.html
почему-то СВОЮ статью нашел не на мисте а там :( |
|||
52
Aprobator
23.07.12
✎
15:18
|
а вообще прикольно, как значение в ТЗ, в данном случае, может отличаться от значения справочника с тем же кодом? Перенумерация что ли какая странная?
|
|||
53
Aprobator
23.07.12
✎
15:18
|
(51) тема то по 7 ке вроде.
|
|||
54
vde69
23.07.12
✎
15:19
|
||||
55
vde69
23.07.12
✎
15:19
|
(53) на семерке то-же работает
|
|||
56
Aprobator
23.07.12
✎
15:20
|
тут то немного другое. Я вообще толком не пойму чего ТС хочет.
|
|||
57
Classic
23.07.12
✎
15:21
|
(55)
Собственно то же самое, что и в (33) |
|||
58
Classic
23.07.12
✎
15:22
|
(57) к (54)
|
|||
59
Cthulhu
23.07.12
✎
15:22
|
(56): "следующий!"
|
|||
60
vde69
23.07.12
✎
15:25
|
(57) в (33) похоже, но не совсем то...
|
|||
61
Classic
23.07.12
✎
15:26
|
(56)
Ну например у тебя есть справочник Номенклатура, в котором один из реквизитов - Цена. Манагеры каждый день приносят файлик "Изменение цены", где валяется код номенклатуры и новая цена. Твоя задача - загрузить новые цены в справочник. Желательно грузить только те цены, которые реально отличаются (ну мало ли, может там УРБД) |
|||
62
Serginio1
23.07.12
✎
15:27
|
Посмотри http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2019 там есть сравнение 2 ТЗ аналог джойнов
|
|||
63
Aprobator
23.07.12
✎
15:28
|
(61)а млин, значение не есь тип справочник ))))) Тогда понял )))
|
|||
64
bizon2008
23.07.12
✎
15:29
|
(61)Ага. Как-то так. И пару миллиардов строк.
Вариант (33) запустил, реально быстрей. По расчету на 40 минут. Годится. |
|||
65
vde69
23.07.12
✎
15:34
|
(64) посмотри еще вариант (54), дело в том, что в (33) есть мелкие дырки
1. сравнении целиком поля а не посимвольно (что при определенных настройках системы может давать провалы в сравнении) 2. не отрабатывается попадание в бесконечный цикл |
|||
66
Classic
23.07.12
✎
15:35
|
(65)
2. не отрабатывается попадание в бесконечный цикл. Отрабатывается :) |
|||
67
Classic
23.07.12
✎
15:37
|
Хотя конечно если в
/// делаем что нам надо Сбивается выборка справочника или ТЗ (грохаем например что-то и), тогда да, нехорошо |
|||
68
Classic
23.07.12
✎
15:38
|
(33)
Кстати да, там в конце цикла надо поставить Если ТЗ.ПолучитьСтроку() = 0 Тогда Прервать КонецЕсли; (65) Прав |
|||
69
bizon2008
23.07.12
✎
15:45
|
(68)Я догадливый. Проверку на конец сделал.
|
|||
70
varelchik
23.07.12
✎
15:49
|
(0)
Ты хоть вариант (37) пробовал? |
|||
71
bizon2008
23.07.12
✎
16:00
|
(70)И чем он уникален? НайтиПоКоду долго работает.
|
|||
72
Cthulhu
23.07.12
✎
16:02
|
(71): далаадно...
|
|||
73
Serginio1
23.07.12
✎
16:04
|
Если у тебя SQL то самым быстрым будет прямым запросом с условием IN
|
|||
74
bizon2008
23.07.12
✎
16:05
|
(72)12 часов.
|
|||
75
bizon2008
23.07.12
✎
16:05
|
(73)Угу. Но на это у меня мозга не хватит.
|
|||
76
Serginio1
23.07.12
✎
16:11
|
Вернее через булки загрузить в темповую таблицу. Можно добавить индекс по коду и сделать джойн по коду с условием на неравность цен. Ну для семерочников 1С++ наше все Книга знаний: Эффективное использование MSSQL с помощью ВК 1C++
|
|||
77
Босечка
23.07.12
✎
16:19
|
(71) Из справочника занеси информацию в ТаблицуЗначений, и будет у тебя 2 таблицы. Потом сделай тоже самое что и (37) только с таблицами значений, используя ТЗ.НайтиЗначение(,,).
С ТаблицамиЗначений будет работать намного быстрее. |
|||
78
Serginio1
23.07.12
✎
16:33
|
Либо если не хочешь сравнивать сделай с запрос с выборкой нужных кодов типа
ТекстЗапроса = " |SELECT | Спр.Code as Код, | $Спр.Цена as Цена |FROM | $Справочник.ТвойСпр as Спр |WHERE | $Спр.Code IN ('код1','код2','код3')"; |
|||
79
Ыщъ
23.07.12
✎
16:37
|
ИТЗ.
Перебирать элементы и искать в ИТЗ. |
|||
80
Serginio1
23.07.12
✎
16:41
|
Блин недавно перешел из 8 ки в 7. в 7 ке есть условие в запросе "Условие (А в Б)". Сравнивать ТЗ быстрее чем справочник
|
|||
81
Serginio1
23.07.12
✎
16:42
|
(79) А ему не надо индексированной ТЗ, главное что бы были отсортированы и алгоритм типа 33 очень быстро проходит. Таким алгоритмом и джойны по индесам в реальных БД проходят
|
|||
82
Classic
23.07.12
✎
16:48
|
(81)
Кстати очень сильно зависит от входных данных будет быстрее (33) или (20) Вариант а) ТЗ совпадает со справочником. (33) отработает явно быстрее потому что на каждую строку ТЗ надо сделать всего лишь один инкремент выборки, что априори быстрее любого (даже индексированного) поиска по всему справочнику Вариант б) В ТЗ один элемент и он совпадает с последним в выборке. Тогда (20) будет быстрее, потому что поиск из (33) будет происходить тупым перебором всего справочника, что априори медленнее чем поиск по индексированному полю |
|||
83
varelchik
23.07.12
✎
16:53
|
(77) А вот тута вы не правы.
Луче тоди использовать ИндексированнуюТаблицу. Потому как НайтиЗначение() выполняется Перебором строк! Читайте доку по 1С++ Класс ИндексированнаяТаблица. (78) тоже не полохо ном (0) утверждает что унего в ТЗ миллиард строк. в чем я глубоко сомневаюсь. |
|||
84
Serginio1
23.07.12
✎
16:53
|
(82) Смотря, что мы ищем. Если ищем на соответствие с ТЗ, то можно сразу ограничить запросом нужные нам коды, на максимум и минимум из этой ТЗ.
Если мы хотим сделать полный джойн то только 33 без предварительных условий |
|||
85
varelchik
23.07.12
✎
16:53
|
А код в Справчонике разве не индексированный?
|
|||
86
Serginio1
23.07.12
✎
16:54
|
(83) тогда 76, либо на минимум максимум
|
|||
87
Classic
23.07.12
✎
16:58
|
(84)
Угу. Если в ТЗ первый элемент совпадает с первым в выборке, а последний - с последним, то запрос - лишнее колесо. Но в принципе я про то и говорю. Я описал две крайние ситуации. Что будет посрединке - надо думать:) |
|||
88
varelchik
23.07.12
✎
17:08
|
Во!
Идея. А ведь если вывалить это ТЗ во временную таблицу SQL а потом сделать Запрос с соединением Справочника и этой ТЗ по Коду и с условием что значения в полученной таблице не равны то получим ТЗ с готовыми расхождениями! |
|||
89
Serginio1
23.07.12
✎
17:09
|
(87) Запрос в любом случае лучше чем курсор, говоря об SQL. Он единственно правильное решение. Конечно лучше через булки создать временную таблицу и сравнить через SQL, но автор говорит, что до этого он не дойдет. Но у меня сравнение с индексацией миллионых прайсов по трем полям были в районе минуты. Но у меня там было не чистое сравнение а merge. Просто когда мало измененных записей то можно косвенно сравнить.
|
|||
90
varelchik
23.07.12
✎
17:15
|
В виду (88)
Впросю ясно (0) выложить структуру ТЗ Поля и Размерность и Тип. Щас быренько навояем. |
|||
91
varelchik
23.07.12
✎
17:15
|
для этого (0) потребуется 1С++.
|
|||
92
varelchik
23.07.12
✎
17:16
|
она в базе подключена?
|
|||
93
Classic
23.07.12
✎
17:16
|
(89)
Нештатные варианты я вообще не рассматриваю, потому что шарю в них приблизительно как ТС :) Да и проблема мне интересна чисто с алгоритмической точки зрения |
|||
94
varelchik
23.07.12
✎
17:18
|
(93) Так для меня 1С++ это уже неотъемлимая часть 1С.
|
|||
95
Serginio1
23.07.12
✎
17:21
|
(91) Еще бы в 1С былабы функция "УложитьТЗ" типа как в 8 ке поместить из.
Можешь создавать темповую из текстового файла с файлом описания полей SELECT a.* FROM OPENROWSET( BULK 'c:\test\values.txt', FORMATFILE = 'c:\test\values.fmt') |
|||
96
Classic
23.07.12
✎
17:21
|
(94)
Отъемлемая :) |
|||
97
varelchik
23.07.12
✎
17:23
|
(94) я ж сказал для МЕНЯ.
(95) Почему нету? ВыполнитьSQLИЗТЗ() токо в 1С++ |
|||
98
varelchik
23.07.12
✎
17:25
|
(95) только если мы имеем миллиард записей то недумаю уложить в текстовик у нас займет мало времени.
|
|||
99
varelchik
23.07.12
✎
17:26
|
У не тама где основатель темы со структурой задачи?
А то мене через полчаса до дому. |
|||
100
Serginio1
23.07.12
✎
17:27
|
(97) Вот спасибо. Забыл. А ВыполнитьSQLИЗТЗ() думаешь как укладывает? Ничего быстрее булков пока не придумали.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |