Имя: Пароль:
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) действительно, не получается. Но запрос выполняется