Имя: Пароль:
1C
1С v8
Установка GUID в ссылку нового не срабатывает ☑
0 ezhikofff
 
06.05.20
✎
10:42
При записи система формирует свою ссылку взамен нужной. Ссылки с данным GUID в базе нет, проверял. Почему не удается установить? Куда копать? Хелп!

        ТекущаяСсылка = Справочники.Контрагенты.ПолучитьСсылку(СтрДанные.КонтрагентGUID);
    Если ТекущаяСсылка.ПолучитьОбъект() = Неопределено Тогда
        ТекущийОбъект = Справочники.Контрагенты.СоздатьЭлемент();
        ТекущийОбъект.УстановитьСсылкуНового(ТекущаяСсылка);
    Иначе
        ТекущийОбъект = ТекущаяСсылка.ПолучитьОбъект();
    КонецЕсли;    
    
    ЗаполнитьЗначенияСвойств(ТекущийОбъект, СтрДанные, , "Ссылка");
    
    ТекущийОбъект.Записать();
1 fisher
 
06.05.20
✎
10:46
Какой тип данных у КонтрагентGUID? Сравни с типом данных, который требует ПолучитьСсылку.
2 ezhikofff
 
06.05.20
✎
10:48
С типами порядок, КонтрагентGUID - УникальныйИдентификатор

ПолучитьСсылку (GetRef)
Синтаксис:
ПолучитьСсылку(<УникальныйИдентификатор>)
3 mzelensky
 
06.05.20
✎
10:50
(0) Зачем вот это мракобесие:

"Если ТекущаяСсылка.ПолучитьОбъект() = Неопределено Тогда"

?
4 Franchiser
 
06.05.20
✎
10:53
Справочники.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор)
У тебя вероятно тип строка.
5 ezhikofff
 
06.05.20
✎
10:54
функция ведет себя так, как будто уже существует ссылка с таким GUID, но это точно не так..

Синтаксис:
УстановитьСсылкуНового(<Ссылка>)

Описание:
Устанавливает значение для нового (созданного и еще не записанного) объекта, которое будет назначено при записи в качестве ссылки.
Значение не может равняться ссылке какого-либо из имеющихся в базе данных объекта данного типа.
Уникальность ссылки проверяется при записи объекта.
6 ezhikofff
 
06.05.20
✎
10:54
(4) СтрДанные.КонтрагентGUID    6645b72d-5489-11e6-803b-5439dfca5678    УникальныйИдентификатор
7 Cyberhawk
 
06.05.20
✎
10:55
Возможно ссылка нового безусловно переопределяется прикладным кодом (не учитывает, что она может быть ранее уже установлена), в линейке "УТ 11 - КА 2 - ЕРП" по крайней мере такое замечено
8 ezhikofff
 
06.05.20
✎
10:55
(3) чтоб определить записана ли данная ссылка
9 Franchiser
 
06.05.20
✎
10:57
убери этот трэш:
Если ТекущаяСсылка.ПолучитьОбъект() = Неопределено Тогда
10 ezhikofff
 
06.05.20
✎
10:58
(9) а как ты отличишь новое от существующей?
11 mzelensky
 
06.05.20
✎
10:58
(8) Есть такая крутая штука "ЗначениеЗаполнено()". Предположим, что такая ссылка в базе уже ЕСТЬ, тогда ты в своем коде "Если ТекущаяСсылка.ПолучитьОбъект() = Неопределено Тогда" ПОЛУЧИШЬ объект по ссылке, а потом "ТекущийОбъект = ТекущаяСсылка.ПолучитьОбъект();" получишь его еще раз!!! Попахивает гомнокодом!!!
12 ezhikofff
 
06.05.20
✎
10:59
(7) на соседний справочник Партнеров данная конструкция прекрасно отрабатывает, все ссылочки с нужными GIUDами..
13 mzelensky
 
06.05.20
✎
11:02
(12) Проверь отладчиком  какая ссылка у объекта в событии "ПередЗаписью" и "ПриЗаписи", когда выполняется "ТекущийОбъект.Записать();"
14 ezhikofff
 
06.05.20
✎
11:03
(11) вы уходите от темы, вопрос был не об этом...

а раз вам так интересно, то попробуйте подумать, что вернет конструкция ЗначениеЗаполнено(БитаяСсылка)...
15 ezhikofff
 
06.05.20
✎
11:04
(13) проверено, генерирует свою ссылку
16 hhhh
 
06.05.20
✎
11:05
(11) ЗначениеЗаполнено() не прокатит. Правильный ответ как в (0), это из типовой.
17 hhhh
 
06.05.20
✎
11:07
(16) хотя насчет "= Неопределено" сомневаюсь
18 ezhikofff
 
06.05.20
✎
11:11
(17) если ссылка не записана, вернет Неопределено, к этой конструкции у меня нет вопросов..
19 mzelensky
 
06.05.20
✎
11:13
(16) Кто сказал, что в типовой все правильно?

Если речь про текстовку "ОбъектНеОбнаружен", то можно получить строку по ссылке через "Строка(ТекущаяСсылка )" и далее найти текст "ОбъектНеОбнаружен". Это будет гораздо ЛУЧШЕ, чем двойное получение объекта.
20 Franchiser
 
06.05.20
✎
11:14
ТекущийОбъект.ОбменДанными.Загрузка = Истина;
21 mzelensky
 
06.05.20
✎
11:14
(15) Получается в событиях "ПередЗаписью" и "ПриЗаписи" ссылка верная, а ПОСЛЕ "ТекущийОбъект.Записать();" другая?

Подписок нет?
22 Franchiser
 
06.05.20
✎
11:15
(17) в типовой так же
23 PR
 
06.05.20
✎
11:15
(19) Ты наркоман что ли?
Тебе уже несколько раз сказали, что правильно через получение объекта, а ты снова про ЗначениеЗаполнено, про текст ОбъектНеОбнаружен
Спрячься уже и тихонечко почитай материалы
24 mzelensky
 
06.05.20
✎
11:16
(23) Давай ссылку на материалы, о просветленный!?
25 PR
 
06.05.20
✎
11:17
(17) Не сомневайся, так и будет, объекта же нет
26 PR
 
06.05.20
✎
11:17
(24) Ща подожди, шнурки завяжу
27 ezhikofff
 
06.05.20
✎
11:19
(19) speshially for mzelensky, проблема не тут:

        ТекущаяСсылка = Справочники.Контрагенты.ПолучитьСсылку(СтрДанные.КонтрагентGUID);
    //Если ТекущаяСсылка.ПолучитьОбъект() = Неопределено Тогда
    Если СтрНайти(ТекущаяСсылка, "Объект не найден") <> 0 Тогда
        ТекущийОбъект = Справочники.Контрагенты.СоздатьЭлемент();
        ТекущийОбъект.УстановитьСсылкуНового(ТекущаяСсылка);
    Иначе
        ТекущийОбъект = ТекущаяСсылка.ПолучитьОбъект();
    КонецЕсли;    
    
    ЗаполнитьЗначенияСвойств(ТекущийОбъект, СтрДанные, , "Ссылка");
    
    ТекущийОбъект.Записать();
28 Franchiser
 
06.05.20
✎
11:19
ТекущийОбъект может быть зарезервиованным, поменяй название
29 mzelensky
 
06.05.20
✎
11:19
(23) Объясни мне, наркоману, о великий ГенеральныйДиректор-ПрофессиональныйПрограммист1С

Что будет если последовательно выполнить сперва это

"Если ТекущаяСсылка.ПолучитьОбъект() = Неопределено Тогда"

а потом это

"ТекущийОбъект = ТекущаяСсылка.ПолучитьОбъект();"

При условии, что объект с такой ссылкой в базе ПРИСУТСТВУЕТ?

разумеется после того, как со шнурками проект закроешь.
30 mzelensky
 
06.05.20
✎
11:20
(27) Я знаю, что описанная тобой проблема не в этом.

ТЫ подписки проверил?
31 dezss
 
06.05.20
✎
11:22
(23) Так в БСП же есть вроде функция СсылкаСуществует, там вроде запросом определяется существование записи в базе. Разве это не кошерней?
32 ezhikofff
 
06.05.20
✎
11:24
(29) прекрасно все отрабатывает, проблем не обнаружено..
33 ptiz
 
06.05.20
✎
11:26
(0) Код верный, проходи отладчиком и проверяй типы и пр.
34 Franchiser
 
06.05.20
✎
11:26
(32) тебе не нужно 2 раза получать объект, считай в переменную
35 mzelensky
 
06.05.20
✎
11:26
(32) Вот ты тугой, а .... Прикинь, если сделать так:

ТекущийОбъект  = ТекущаяСсылка.ПолучитьОбъект();
ТекущийОбъект  = ТекущаяСсылка.ПолучитьОбъект();
ТекущийОбъект  = ТекущаяСсылка.ПолучитьОбъект();
ТекущийОбъект  = ТекущаяСсылка.ПолучитьОбъект();
ТекущийОбъект  = ТекущаяСсылка.ПолучитьОбъект();
ТекущийОбъект.Записать();

То тоже " прекрасно все отрабатывает" и даже ни одной ошибки не будет!
36 mzelensky
 
06.05.20
✎
11:27
(0) Вот так должно выглядеть:

    ТекущаяСсылка = Справочники.Контрагенты.ПолучитьСсылку(СтрДанные.КонтрагентGUID);
    ТекущийОбъект = ТекущаяСсылка.ПолучитьОбъект();
    Если ТекущийОбъект  = Неопределено Тогда
        ТекущийОбъект = Справочники.Контрагенты.СоздатьЭлемент();
        ТекущийОбъект.УстановитьСсылкуНового(ТекущаяСсылка);
    КонецЕсли;    
    
    ЗаполнитьЗначенияСвойств(ТекущийОбъект, СтрДанные, , "Ссылка");
    
    ТекущийОбъект.Записать();
37 PR
 
06.05.20
✎
11:27
(29) Объясняю
ПолучитьОбъект() - это функция, я не процедура
Поэтому, если ты 84 раза получишь объект, но присвоишь полученный результат в ТекущийОбъект только 85 раз, то значит 84 раза ты поработал в холостую и никому ничего плохого не сделал, и только в 85 раз что-то поменял в своем контексте
38 ezhikofff
 
06.05.20
✎
11:28
(20) спасибо за здравую мысль, видимо действительно идет пересвоение ссылки дальше..

ТекущийОбъект.ОбменДанными.Загрузка = Истина; - оказалось достаточно
39 mzelensky
 
06.05.20
✎
11:28
(36) НО это НЕ РЕШИТ твою проблему.

Скорее всего у тебя присутствуют ПОДПИСКИ на этот справочник, которые меняет ссылку. Тебе об этом уже говорили в (7)
40 Franchiser
 
06.05.20
✎
11:29
получение объекта влечен получение всех ревизитов, это может быть долго. Поэтому в БСП сделать функции ЗначениеРеквизтовОбъекта(), могул ссылку на ИТС дать.
41 PR
 
06.05.20
✎
11:29
(31) Конечно же кошерней
Потому что быстрее
Но как бы геморней слегка

Еще не уверен, но вроде можно использовать XMLСтрока
Но, еще раз, тут не уверен, надо проверить
42 mzelensky
 
06.05.20
✎
11:30
(37) А вот теперь давай ссылку на официальную статью про это!
43 mzelensky
 
06.05.20
✎
11:32
(42) + т.к. выдуманное тобой правило "Если вызову функции не приравнять переменную, то и вызова функции не произойдет" мне прям ооочень интересно
44 ezhikofff
 
06.05.20
✎
11:34
(36) ок, переделал, есть в этом здравый смысл тоже:

        ТекущаяСсылка = Справочники.Контрагенты.ПолучитьСсылку(СтрДанные.КонтрагентGUID);
    ТекущийОбъект = ТекущаяСсылка.ПолучитьОбъект();
    Если ТекущийОбъект = Неопределено Тогда
        ТекущийОбъект = Справочники.Контрагенты.СоздатьЭлемент();
        ТекущийОбъект.УстановитьСсылкуНового(ТекущаяСсылка);
    КонецЕсли;
    
    ЗаполнитьЗначенияСвойств(ТекущийОбъект, СтрДанные, , "Ссылка");
    
    ТекущийОбъект.ОбменДанными.Загрузка = Истина;
    ТекущийОбъект.Записать();

Всем спасибо за содействие.
45 mzelensky
 
06.05.20
✎
11:35
Ток ветку не закрывайте, я пруфы жду от ГенеральногоДиректора
46 mzelensky
 
06.05.20
✎
11:36
(44) т.е. подписки тебе все-таки лень проверить отладчиком. Гораздо проще тыкнуть на абум. А ты в курсе, что по "ТекущийОбъект.ОбменДанными.Загрузка = Истина;" скорее всего отключается ряд программных проверок?!
47 Aleksey
 
06.05.20
✎
11:36
(44) и что это работает? Да ну бред какой то
48 hhhh
 
06.05.20
✎
11:37
(38) вообще-то

https://yandex.ru/yandsearch?&clid=2186620&text=Установка%20GUID%20в%20ссылку%20нового%20не%20срабатывает&lr=10752

первая ссылка. Вы похоже даже не пытались научиться гуглить.
49 Franchiser
 
06.05.20
✎
11:37
50 mzelensky
 
06.05.20
✎
11:39
(49) Даааа, про это я в курсе. Но малоуважаемый мной ГенеральныйДиректор-ПрофессиональныйПрограммист1С утверждает в (37) обратное:

"если ты 84 раза получишь объект, но присвоишь полученный результат в ТекущийОбъект только 85 раз, то значит 84 раза ты поработал в холостую и никому ничего плохого не сделал, и только в 85 раз что-то поменял в своем контексте"
51 hhhh
 
06.05.20
✎
11:40
(46) наверно так


   ТекущийОбъект.ОбменДанными.Загрузка = Истина;
    ТекущийОбъект.Записать();
   ТекущийОбъект.ОбменДанными.Загрузка = Ложь;
    ТекущийОбъект.Записать();

должно сработать
52 Franchiser
 
06.05.20
✎
11:42
(46) скорее всего там пишутся какие-нибудь подчиненные справочники (например, договоры) или независимые регистры, поэтому код не отрабатывает по присвоению новой ссылки.
53 mzelensky
 
06.05.20
✎
11:43
(51) Тогда уж лучше так:

ТекущийОбъект.ОбменДанными.Загрузка = Истина;
ТекущийОбъект.Записать();
ТекущийОбъект.ОбменДанными.Загрузка = Ложь;
ТекущийОбъект.Записать();
ТекущийОбъект = ТекущийОбъект.Ссылка.ПолучитЬОбъект();
ТекущийОбъект.Записать();

НУ прям вот на ВСЯКИЙ СЛУЧАЙ, что уж там... где 2 записи, там и третью не грех впендюрить :)
54 mzelensky
 
06.05.20
✎
11:45
(41) ГенеральныйДиректор-ПрофессиональныйПрограммист1С, ааааууууу?!?!?! Как там проект со шнурками??? Еще не разрулил???
55 Fedor-1971
 
06.05.20
✎
11:50
(52) Давно была тема, получается примерно следующее:

1. УстановитьСсылкуНового (версия данных 1)
2. Подписка что-то изменяет, например, генерирует наименование (версия данных 2)

при физической записи выясняется что версия данных изменилась и генерится новая ссылка,
в результате - в п.1 получена битая ссылка
56 ezhikofff
 
06.05.20
✎
11:52
(46) нет смысла лезть в подписки, это разовое наполнение НСИ, как раз подходит вариант с отключенными проверками.
57 mzelensky
 
06.05.20
✎
11:54
(56) "это разовое наполнение НСИ" - так писать об этом надо СРАЗУ...а не через час обсуждения.
58 mzelensky
 
06.05.20
✎
11:55
Жалко ГенеральныйДиректор-ПрофессиональныйПрограммист1С слился....похоже со "шнурками" что-то у него не вяжется....
59 Franchiser
 
06.05.20
✎
11:57
(55) да,  у меня  тоже так было. Как правило после записи нужно получать объект, т.к. в случае ошибки в транзакции записи версия данных может слететь.
60 Aleksey
 
06.05.20
✎
11:58
(55) Поэтому обмен данными загрухка
61 PR
 
06.05.20
✎
12:01
(42) Рукалицо
Статью про что?
Про то, что если ты в отдельном адресном пространстве получил объект в никуда, то ты никакую переменную не перезатер?
62 PR
 
06.05.20
✎
12:02
(43) Ты точно не наркоман?
Зачем ты мне приписываешь то, что я не говорил?
Вызов функции произойдет, но возвращенное значение никуда не присвоится, потому что нечему его присваивать
63 PR
 
06.05.20
✎
12:04
(58) Не суетись, нервозный
64 mzelensky
 
06.05.20
✎
12:05
(61) Наркоман лопоухий здесь только ТЫ. Т.к. явно на этом слове ты просто зациклен.

"Вызов функции произойдет, но возвращенное значение никуда не присвоится, потому что нечему его присваивать" - вызов функции получения объекта привете к считыванию этого объекта. В любом случае. Хоть приравнивай к переменной, хоть нет! На это тебе выше человек дал ссылку.

"Зачем ты мне приписываешь то, что я не говорил?" - твой бред я процитировал.

Так что захлопнись со своими советами, скройся и таки "почитай материалы"
65 mzelensky
 
06.05.20
✎
12:06
(64)  + Оптимизатор хренов....не позорился бы лучше с подобными заявлениями:

"Поэтому, если ты 84 раза получишь объект, но присвоишь полученный результат в ТекущийОбъект только 85 раз, то значит 84 раза ты поработал в холостую и никому ничего плохого не сделал, и только в 85 раз что-то поменял в своем контексте"
66 PR
 
06.05.20
✎
12:07
(64) И к чему плохому приведет _считывание_ объекта? Какие переменные твоего контекста будут изменены?
67 PR
 
06.05.20
✎
12:09
(65) Ладно, заканчивай, уже все поняли, что ты просто не знал про то, как работает ПолучитьОбъект для битой ссылки
Бывает
Ничего страшного
68 mzelensky
 
06.05.20
✎
12:14
(66) Исходя из этой тупой логики, то код

ТекущийОбъект.ОбменДанными.Загрузка = Истина;
ТекущийОбъект.Записать();
ТекущийОбъект.ОбменДанными.Загрузка = Ложь;
ТекущийОбъект.Записать();
ТекущийОбъект = ТекущийОбъект.Ссылка.ПолучитЬОбъект();
ТекущийОбъект.Записать();

Тоже ни к чему ПЛОХОМУ не приведет. Совершенно ни к чему плохому. Я теперь понимаю, какой там продукт своим клиентам ты впариваешь...
69 Aleksey
 
06.05.20
✎
12:19
(68) Планета не упадет, звезда не взорветься. Т.е. ничего плохого не произойдет. Ну кроме того что комп сожрет лишние полвата из розетки
70 Aleksey
 
06.05.20
✎
12:20
мы про какой уровень угрозы говорим? Будет ли блокировка в файловой базе при массовой паралельной записи контрагентов?
Или как поведет себя скуль когда в базе будет один робот который запускает обработку и больши никого не будет?
71 Aleksey
 
06.05.20
✎
12:22
И да не поверишь, но я так делаю, когда когда гружу данные в УТ11, и никто не умер, никто не жалуеться
72 PR
 
06.05.20
✎
12:28
(68) Ну вот в кого ты такой тугой, а?
Записать — это запись конкретно объекта ТекущийОбъект
А ПолучитьОбъект — это чтение объекта из базы в отдельный объект, который никак не используется, кроме как сравнивается с Неопределено

Поскольку ты явно нацелился на ДДС, то я уточню для тугоплавких, я _не_ утверждал, что нельзя технически переломать все нахрен в текущем контексте, вызвав функцию без присваивания слева
Конечно же, ты в принципе можешь при вызове функции БезобиднаяФункция переломать все нахрен, потому что в этом вызове у тебя может быть, например, удаление всех объектов в базе
Но в данном конкретном случае мы говорим про функцию ПолучитьОбъект, в которой ничего такого нет
73 Cyberhawk
 
06.05.20
✎
17:49
(12) Это к чему?
74 Конструктор1С
 
06.05.20
✎
19:09
ТвояТаблица.Колонки.Добавить("Контрагент", Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));

// Создание ссылок
Для Каждого СтрДанные Из ТвояТаблица Цикл
  СтрДанные.Контрагент = Справочники.Контрагенты.ПолучитьСсылку(СтрДанные.КонтрагентGUID);
КонецЦикла;

// Поиск в БД
СоответствиеКодов = ОбщегоНазначения.ЗначениеРеквизитаОбъектов(ТвояТаблица.ВыгрузитьКолонку("Контрагент"), "Код");

// Проверка ссылок
Для Каждого СтрДанные Из ТвояТаблица Цикл
   Если СоответствиеКодов.Получить(СтрДанные.Контрагент) = Неопределено Тогда
      // Контрагента нет, нужно создать
   Иначе
      // Контрагент существует
   КонецЕсли;
КонецЦикла;

как-то так
75 Конструктор1С
 
06.05.20
✎
19:12
Код не проверял, но должно работать. Так ты за один запрос проверишь существование всех элементов
76 palsergeich
 
06.05.20
✎
19:20
(72) Не ссорьтесь.
ОбщегоНазначения.СсылкаСуществует(объект.Ссылка)
Решит Вашу дискуссию
77 Конструктор1С
 
06.05.20
✎
19:23
(76) в контексте (0) получится запрос в цикле. Если мне память не изменяет, СсылкаСуществует юзает ЗначениеРеквизитаОбъектА(). Поэтому лучше сразу проверить все ссылки
78 Cyberhawk
 
07.05.20
✎
08:02
(77) Нет, никакой реквизит там не получается
79 AneJIbcuH
 
07.05.20
✎
08:59
голосую за (74)
80 Конструктор1С
 
07.05.20
✎
19:27
(78) действительно, не получается. Но запрос выполняется
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.