Имя: Пароль:
1C
1С v8
Как быстро и красиво сравнить ВСЕ реквизиты документа?
0 Shved_72
 
28.11.15
10:11
Пишу перенос в 8ку. Ессно приходится по 48 раз елозить взад-вперед.
Хотелось бы уже загруженные документы и НЕ измененные в текущей загрузке не записывать и не проводить.
Вижу тока перебором по метаданным.
Но есть ли более красивый код.

Тип есть же звездочка в Зарпросе:
Выбрать * из Документ....

а можно ли сравнить звездочки запросом не перебирая все реквизиты + все табличные части?
1 Горогуля
 
28.11.15
10:14
а можно повторить вопрос?
2 Shved_72
 
28.11.15
10:19
Есть переменная ДокОбъект с заполненными программно реквизитами и пока не записанная.
Как быстро и красиво проверить ДокОбъект и Объект в БД, и если ничо не изменилось, то и не записывать ваще.
3 Горогуля
 
28.11.15
10:21
а может взять и записать? в режиме ОбменДанными.Загрузка
4 Горогуля
 
28.11.15
10:22
и куда ты собрался прикладывать звёздочку к незаписанному объекту?
5 Shved_72
 
28.11.15
10:26
(3) фу. потом больше трахаца, лучше сразу при загрузке по уму.
да и не в этом вопрос. как красиво сравнить

про звездочку. может можно както незаписаный объект присунуть в виртуальную таблицу и тогда структуры сущности будут одинаковые и проверять * = *. не?

вопрос скорей не по скорости, а по красивому изврату.

ибо выгружать из бд в структуру и потом перебором сравнивать по реквизитно както длинно
6 Горогуля
 
28.11.15
10:27
значениевстрокувнутр
7 Горогуля
 
28.11.15
10:28
ещё можно не выгружать лишнее
8 Мимохожий Однако
 
28.11.15
10:29
Самое красивое - использовать Планы обмена. Не измененные объекты не попадут в выборку и их не надо будет ни с чем сравнивать.
9 Shved_72
 
28.11.15
10:33
(8) чото в этом есть. это же на уровне платформы будет проверятся
10 Shved_72
 
28.11.15
10:33
(6) попробую щас
11 Горогуля
 
28.11.15
10:34
(9) регистрироваться
12 Shved_72
 
28.11.15
10:39
чото не.
при обмене же запись всеравно происходит в БД, а уж потом проверяется надо ли ее в пакет обмена.
цель же исключить ваще запись объектов которые не изменились при загрузке
13 Горогуля
 
28.11.15
10:41
чего там у тебя проверяется?
14 Shved_72
 
28.11.15
10:44
(13) ну платформа проверяет надо включать записанный объект в план обмена. не так?
15 Горогуля
 
28.11.15
10:45
не так
16 Горогуля
 
28.11.15
10:45
она тупо регистрирует факт записи объекта
17 RomaH
 
naïve
28.11.15
11:29
в версионировании посмотри
там перед созданием версии - объекты сериализуются и сравниваются
18 b_ru
 
28.11.15
11:48
>>ибо выгружать из бд в структуру и потом перебором сравнивать по реквизитно както длинно

Так функцию напиши - будет в одну строчку всё.
19 qwerty
 
28.11.15
11:50
Все уже сделано до вас. Флаг "Записывать только измененные объекты" в обработке "Универсальный обмен данными" на закладке "Загрузка"
20 kofeinik
 
28.11.15
11:53
Если ничего не изменилось, то тогда какая разница, записывать объект, или нет? Результат будет одинаковый.
21 Shved_72
 
28.11.15
11:54
(20) на запись уходит время
(19) посмотрю как сранивают
пока (17) проверяю. там можно в двоичные данные конвертнуть объекты в БД и в переменной
22 Shved_72
 
28.11.15
11:58
нашел в (19) строчку
"Если Не НужноЗаписатьОбъект Тогда
                            
                            НужноЗаписатьОбъект = (Объект[Имя] <> Значение);
                            
                        КонецЕсли;
"

вот так хочу.
но что в сравниваемых значениях пока не понял
23 Shved_72
 
28.11.15
11:59
НужноЗаписатьОбъект = (Объект[Имя] <> Значение);
Строка 7023 в (19) из БП30
24 qwerty
 
28.11.15
12:03
Посказка. Ограничь кол-во выгружаемых объектов. На этих данных отладь перенос. После этого перенеси один раз все объекты в рабочую базу, а не "елозь туда-сюда".
25 Shved_72
 
28.11.15
12:07
в (23) фу. там пореквизитно
26 Shved_72
 
28.11.15
12:08
(24) да на каждой порции чонить да новое вылазит постоянно. надо за 15 лет перенести из самописек 77 в 83
27 Горогуля
 
28.11.15
12:12
изобретаешь свою КД?
28 Shved_72
 
28.11.15
12:33
просто ОЛЕ
29 Shved_72
 
28.11.15
12:46
вроде работает

ЗаписьXML = Новый ЗаписьFastInfoset;
    ЗаписьXML.УстановитьДвоичныеДанные();
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    ДокБД =  Документы[Вид].НайтиПоНомеру(оНомер,оДата).ПолучитьОбъект();
    ЗаписатьXML(ЗаписьXML, Док, НазначениеТипаXML.Явное);
    
    ДанныеДвоичныеТут = ЗаписьXML.Закрыть();
    
    ЗаписьXML = Новый ЗаписьFastInfoset;
    ЗаписьXML.УстановитьДвоичныеДанные();
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    ЗаписатьXML(ЗаписьXML, ДокБД, НазначениеТипаXML.Явное);
    
    ДанныеДвоичныеБД = ЗаписьXML.Закрыть();

    Изменен = ДанныеДвоичныеТут = ДанныеДвоичныеБД;
30 Shved_72
 
28.11.15
12:48
там сверяются бесконечные строки вида "E0 00 00 01 00 78 CF 02 78 73 69 28 68 74 74 70 3A 2F 2F 77 77 77 2E 77 33 2E 6F 72 67 2F 32 30 30 31 2F 58 4D 4C 53 63 68 65 6D 61 2D 69 6E 73 ...."
31 Shved_72
 
28.11.15
12:49
посмотрю теперь скоко занимает времени такая сериализация. не быстрей ли просто записывать всегда
32 sda553
 
28.11.15
14:29
(0) Прием заключается в том, что каждому документу при записи вычисляется по значимым реквизитам и приписывается хэш код.
33 Shved_72
 
28.11.15
15:23
вообщем сказка. Спасибо (17).
Оттуда дернул три строки.

Красота же:

Изменен = НЕ (ДанныеДвоичныеТут = ДанныеДвоичныеБД);

проверил. работает в обе стороны - при изменении документа юзером в базе и при программном дописывании реквизитов.
34 Горогуля
 
28.11.15
16:00
красота. именно я так подумал, когда проникся КД
35 Горогуля
 
28.11.15
16:01
КД и СКД - это следующие по значимости изобретения после огня и колеса
36 Shved_72
 
28.11.15
16:10
(34) может. чото я 48 раз садился за изучение КД.. но пива не хватило

в оле я сижу в одном окне.
нету 48 обработок выгрузок, загрузок, файлов правил, выгруженных модулей....
вынос мозга помоему.
37 Горогуля
 
28.11.15
16:13
ты не постиг дао конвертации. объекты переносятся сами. превращаются в то, что я им повелю. и мне плевать, сколько там процедур, правил и т.п....
38 Рэйв
 
28.11.15
16:14
(0)Нет
39 Shved_72
 
28.11.15
16:22
(38) можно. одной строчкой. предварительно обе сущности перевести в двоичные данные
40 Лефмихалыч
 
28.11.15
22:20
(0) При записи во время загрузки можно записывать куда-нибудь значение хитрожопого реквизита ВерсияДанных. Потом при повторной загрузке те, у которых это реквизит совпадает с записанным при обмене, не трогать.
41 Иде я?
 
28.11.15
22:41
Если СравнитьВсеРеквизиты(Док1,Док2) Тогда printfn "%s" "все реквизиты равны"
42 Shved_72
 
28.11.15
23:20
(40) хорошая идея на предмет проверки повторной записи, а то иногда документы основания проводят подчиненные и программная запись матерится.
но в (0) вопрос как переменную сравнить до первой записи.

щас уперся что в табличные части загружаю, очисткой ТЧ и повторной добавкой.
а так по (33) двоичные данные оказываются разные.

буду переписывать сравнением тч перед заполнением
43 Отладчик
 
28.11.15
23:24
(0) сравнить звездочки запросом? Легко!
Ну, не понимаете? Конечно по количеству! Звездочек. Ну, а если равное - это уже сложнее. В следующий раз расскажу. Всем спокойно ночи!
44 Garykom
 
гуру
28.11.15
23:24
Э мне кажется изначальное ТЗ не прописано до конца.
Суть "не переносить" измененные документы? Или наоборот сделать даже если изменили в новой или просто отличается в источнике, то перезаписать из источника?

Почему простейшим образом по периоду не делать?
45 Shved_72
 
29.11.15
07:27
(44) суть: есть переменная ДокОбъект с заполненными данными, и есть Объект в базе. надо сравнить без записи первого
46 Рэйв
 
29.11.15
07:46
(0)Сравнивай данные объекта и ссылки. Пример тут:
http://catalog.mista.ru/public/118839/
47 Shved_72
 
29.11.15
07:59
(46) нету абонемента.
ну коли там сравнение по-реквизитно, значит перебором по метаданным?

меня устроило сравнение объектов целиком в одну строку

Изменен = НЕ (ДанныеДвоичныеТут = ДанныеДвоичныеБД);

у вас будет короче?
48 Рэйв
 
29.11.15
08:18
(47)Хоть какое свертывание объекта будет отличаться от такого же свертывения ссылки даже если ничего не изменено.Просто потому что это разные типы.
Так что только по метаданным и реквизитам
49 Shved_72
 
29.11.15
08:45
(48) сорри, не понимаю "свертывения ссылки"
50 Рэйв
 
29.11.15
08:46
(49)Ну типа
ЗначениеВСтрокуВнутр()
Или
ЗначениеВФайл()
Иили как у тебя в двоичные данные.
51 Shved_72
 
29.11.15
08:53
(50) ну у меня двоичные прекрасно сравниваются. несохраненный объект в переменной и объект в бд.
код взят из типового версионирования.
52 Рэйв
 
29.11.15
08:54
(51)Чет мне кажется не прекрасно. Просто ты не проверял на критичных значениях когда они конкретно различаются.
53 Рэйв
 
29.11.15
08:55
(51)Ссылка и объект очень похожи.пока Объект не изменили
54 Рэйв
 
29.11.15
08:57
(51)И насчет "прекрасно сравниваются" - код бы в студию
55 Shved_72
 
29.11.15
09:03
&НаСервере
Функция СравнитьОбъекты(Объект1,Объект2)

    ЗаписьXML = Новый ЗаписьFastInfoset;
    ЗаписьXML.УстановитьДвоичныеДанные();
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    ЗаписатьXML(ЗаписьXML, Объект1, НазначениеТипаXML.Явное);     
    ДанныеДвоичные1 = ЗаписьXML.Закрыть();
    
    ЗаписьXML = Новый ЗаписьFastInfoset;
    ЗаписьXML.УстановитьДвоичныеДанные();
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    ЗаписатьXML(ЗаписьXML, Объект1, НазначениеТипаXML.Явное);
    ДанныеДвоичные2 = ЗаписьXML.Закрыть();

    Возврат (ДанныеДвоичные1 = ДанныеДвоичные2);

КонецФункции // СравнитьОбъекты()
56 Shved_72
 
29.11.15
09:05
СравнитьОбъекты (ДокОбъект, Дкументы[ДокОбъект.Метаданные().Имя].НайтиПоНомеру(ДокОбъект.Номер,ДокОбъект.Дата))
57 Shved_72
 
29.11.15
09:06
(56) СравнитьОбъекты (ДокОбъект, Дкументы[ДокОбъект.Метаданные().Имя].НайтиПоНомеру(ДокОбъект.Номер,ДокОбъект.Дата).ПолучитьОбъект())
58 Shved_72
 
29.11.15
09:06
ссылку не пробовал. попробую
59 Shved_72
 
29.11.15
09:07
&НаСервере
Функция СравнитьОбъекты(Объект1,Объект2)

    ЗаписьXML = Новый ЗаписьFastInfoset;
    ЗаписьXML.УстановитьДвоичныеДанные();
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    ЗаписатьXML(ЗаписьXML, Объект1, НазначениеТипаXML.Явное);    
    ДанныеДвоичные1 = ЗаписьXML.Закрыть();
    
    ЗаписьXML = Новый ЗаписьFastInfoset;
    ЗаписьXML.УстановитьДвоичныеДанные();
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    ЗаписатьXML(ЗаписьXML, Объект2, НазначениеТипаXML.Явное);
    ДанныеДвоичные2 = ЗаписьXML.Закрыть();

    Возврат (ДанныеДвоичные1 = ДанныеДвоичные2);

КонецФункции// СравнитьОбъекты()
60 Shved_72
 
29.11.15
09:34
при переносе только пришлось переписать загрузку в табличные части.
раньше чистил их и добавлял строки.
щас пишу в тз, сравниваю тз и тч ОбщегоНазначения.КоллекцииИдентичны(тзТек,Док.ТЧ) и если равны то не трогаю тч.
Тогда (59) корректно проходит
61 Лефмихалыч
 
29.11.15
09:37
(42) оставь затею сравнивать в лоб всё со всем. На сранении убьешь времени больше, чем на повторной загрузке. В разы.
Думай в сторону кэширования момента загрузки - версия данных или планы обмена или еще как-то.
Прямолинейное решение в лоб - обычно самое затратное и не надежное.
62 Shved_72
 
29.11.15
09:38
я проверял (59) программным измененим ДокОБъекта и в базе руками в режиме пользователя. вроде всё корректно отрабатывает.
есть какая то доля сомнения, что гдето когдато будет не айс, но пока робит.

хотел также тз сравнивать, но (59) ругается что может только объектные данные переводить в двоичные
63 Лефмихалыч
 
29.11.15
09:38
(59) ты уверен, что это проверка равенства содержимого двоичных данных, а не ссылок на область памяти, где лежат двоичные данные?
64 Shved_72
 
29.11.15
09:40
(63) уверен. проверял 48 раз. сам чую подвох, но пока не нашол
65 Лефмихалыч
 
29.11.15
09:41
(64) с таким подходом в любом случае ты бесчеловечески пожертвуешь быстродействием и оперативной памятью.
66 Shved_72
 
29.11.15
09:42
(61) замерю потом отладчиком на большом объеме. пока стало в разы быстрей, за счет пропуска записи не измененных объектов
67 Shved_72
 
29.11.15
09:43
(65) ну это разовый перенос, хоть и приходится елозить в момент отладки. перенесу и забуду
68 hhhh
 
29.11.15
10:52
(67) если разовый, то не парься, не проверяй, просто записывай каждый раз. Твоя запись хмл по-любому раз в 50 будет медленнее, чем простая команда Записать().
69 Shved_72
 
29.11.15
10:59
(68) быстрей. незнаю что делает
ЗаписатьXML(ЗаписьXML, Объект1, НазначениеТипаXML.Явное);    
ДанныеДвоичные1 = ЗаписьXML.Закрыть();

но в бд она пишет. это методы 1с.
чо они делают не знаю.

ЗаписатьXML (WriteXML)
Вариант синтаксиса: Записать без имени

Синтаксис:

ЗаписатьXML(<ЗаписьXML>, <Значение>, <НазначениеТипа>, <Форма>)
Параметры:

<ЗаписьXML> (обязательный)

Тип: ЗаписьУзловDOM, ЗаписьFastInfoset, ЗаписьXML.
Объект, через который осуществляется запись XML.
<Значение> (обязательный)

Записываемое в поток XML значение. Тип параметра определяется совокупностью типов, для которых определена XML-сериализация.
70 Shved_72
 
29.11.15
11:00
но в бд она НЕ пишет. и потому быстрей
71 Мимохожий Однако
 
29.11.15
11:36
(67)Если разовый перенос, то сабж не нужен. Смотри (24)
72 GenV
 
29.11.15
11:39
(0)В типовом версионировании данных данные сериализуются и по ним рассчитывается хэш-строка MD5. Эта сумма сохраняется для версии и испольуется для дальнейшего сравнения. Т.о. не нужно каждый раз сравнивать весь объект, а только его хэш-строку, что выполняется быстро. А хэш-строка храниться в базе после расчета.