Имя: Пароль:
1C
1C 7.7
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ИЗТЗ()  думаешь как укладывает? Ничего быстрее булков пока не придумали.
2 + 2 = 3.9999999999999999999999999999999...