Имя: Пароль:
1C
1С v8
Записать в реквизит справочника ссылку на самого себя
0 Икогнито
 
22.08.11
22:54
Как записать в реквизит нового элемента справочника в модуле объекта ссылку на самого себя? Тут проблемы какие есть?

P.S. Помню в 7.7 это проблемой было.... К сожалению дома проверить не могу...
1 Икогнито
 
22.08.11
22:58
+(0) я знаю, что есть ЭтотОбъект.Ссылка, но мне надо именно в реквизит записать самого себя.
2 Defender aka LINN
 
22.08.11
22:58
Установить ссылку нового перед записью
3 Jstunner
 
22.08.11
22:59
запиши новый, и ставь ссылку куда хочешь
4 Икогнито
 
22.08.11
23:00
(2) Пытался... что-то не получается :(
Образца кодинга нет?

(3) Мне надо в ПередЗаписью() в модуле объекта.
5 Jstunner
 
22.08.11
23:01
(4) "Мне надо в ПередЗаписью() в модуле объекта."

вопрос жизни и смерти?
6 Икогнито
 
22.08.11
23:01
+(4) и чтобы плевать было, ЭтоНовый() или НЕ ЭтоНовый()
7 Икогнито
 
22.08.11
23:02
(5) почти... боюсь завтра часа полтора потерять на этом...
8 Jstunner
 
22.08.11
23:03
(7) ты не бойся, просто сделай
9 Икогнито
 
22.08.11
23:03
(8) было бы лучше, если бы очень опытный чел поделился кодом. Был бы ему благодарен.
10 Икогнито
 
22.08.11
23:04
+(9) я же ламер, полдня провожусь - потом по шее получу :(
11 ilkoder
 
22.08.11
23:04
Ссылка появляется только после записи, или как (2) сначала создаешь ссылку и присваиваешь кому хочешь.
12 Икогнито
 
22.08.11
23:06
(11) т.е. думаешь в ПередЗаписью() в модуле объекта проканает?
13 ilkoder
 
22.08.11
23:10
(12)
Если ЭтоНовый() Тогда
   УИД = Новый УникальныйИдентификатор;
   СсылкаНаТекОбъект = Справочники.Номенклатура.ПолучитьСсылку(УИД);  
    УстановитьСсылкуНового(СсылкаНаТекОбъект);
Иначе
    СсылкаНаТекОбъект = Ссылка;
КонецЕсли;
14 palpetrovich
 
22.08.11
23:10
стесянюсь спросить, а нафига такой изврат?
15 ilkoder
 
22.08.11
23:13
(14) - а я почем знаю... человеку хочется до записи объекта получить на него ссылку...
16 Икогнито
 
22.08.11
23:13
(14) есть супер-универсальная процедура обработки большого массива данных объектов по приналежности к вхождению по определенному типу значений, не хочу её нагружать проверкой
Если Объект.ССылка = СобственноСамТипЗначений.
17 Smallrat
 
22.08.11
23:17
(14) Смешно, но только такой вот изврат во всех типовых 1С. Организация пишет в свой реквизит "головная организация" саму себя, если головной организации нет.
18 Икогнито
 
22.08.11
23:18
(13) Спасибо большое, завтра попробую.
19 Икогнито
 
22.08.11
23:19
(17) наверно, они это для обмена данными через планы обмена придумали.
Смешно нагружать гигантскую выборку измененных объектов проверкой на вхождение в самое себя.
20 Defender aka LINN
 
22.08.11
23:23
(19) Это для отчетов, где выбирается головной контрагент.
21 kuza2000
 
23.08.11
01:53
(13)
Плохой пример. Такой код может боком выйти при большом размере справочника и/или высоконагруженных системах, так как элемент справочника физически будет втыкаться в середину таблицы, а не в конец. Ну таблица справочника из-за этого подраспухнет. По УИД объекта строиться кластерный индекс, лучше не надо его пытаться генерировать самому, это не простой ГУИД. Система это сделает сама гораздо лучше. Нужно использовать ПолучитьСсылкуНового(). Если интересно - могу объяснить подробнее.
22 nicxxx
 
23.08.11
03:27
(21) ты это разработчика ЗиК расскажи и спроси заодно, зачем они так сделали в справочнике Сотрудники
23 Alex375
 
23.08.11
03:36
Я бы код от 1С как пример поостерегся приводить )))
(21) правильно написал - сам использую такой подход и проблем нет.
24 DSatan
 
23.08.11
08:27
с типовой БП в реквизит головной контрагент записывается ссылка на себя, посмотри
25 Defender aka LINN
 
23.08.11
09:34
(21) ЫЫЫЫЫ... "Нужно использовать ПолучитьСсылкуНового()" - я валяюсь пацталом в истерике.
26 Reset
 
23.08.11
09:48
(21) хх... ерунду-с сморозил-с про ПолучитьСсылкуНового
27 Reset
 
23.08.11
09:54
(21)Вероятно, ты имел в виду Справочники.Имя.ПолучитьСсылку() (без параметров)
28 kosts
 
23.08.11
10:02
(0) Попробуй в модуле справочника. сработает если элемент уже в этот момент есть в БД.

Процедура ПриЗаписи()
СсылкаНаСебя = Ссылка;
КонецПроцедуры
29 Reset
 
23.08.11
10:05
(28) C добрым утром.
30 Reset
 
23.08.11
10:07
(0) В общем, я бы написал так: -)

Если ЭтоНовый() тогда
  УстановитьСсылкуНового(Справочники.Имя.ПолучитьСсылку());
  СсылкаНаСебя=ПолучитьСсылкуНового();
Иначе
  СсылкаНаСебя=Ссылка;
31 Hostess_
of_Love
 
23.08.11
10:12
(30) я извращалась по другому

НовыйКонтрагент.Записать();
НовыйКонтрагент.ГоловнойКонтрагент = НовыйКонтрагент.Ссылка;
НовыйКонтрагент.Записать();

потому что ПолучитьСсылкуНового() почему-то хромал
32 Reset
 
23.08.11
10:19
(31) Месье знает толк в извращениях? Понимаешь, что будет, если вызывать запись в, например, ПередЗаписью() ?
:)
33 Reset
 
23.08.11
10:20
(31)(32) Прошу прощения, Мадам )
не обратил внимания.
34 Hostess_
of_Love
 
23.08.11
10:26
(33)конечно мадам знает)) понимаю) но для меня-то это было не принципиально) и почему вдруг понадобилась такая важность пихать именно ПередЗаписью()?
35 Reset
 
23.08.11
10:28
(34) Не приципиально? ) Значит не понимает.
На всякий случай допоясню, что ПредЗаписью() - я имел в виду событие объекта (не формы)
Почему именно в ПередЗаписью? Имхо логично именно там готовить элемент к записи.
36 Hostess_
of_Love
 
23.08.11
10:49
(35)ой, ладно, не буду спорить) иначе вы тут начнете оптимизировать мой код))
37 Reset
 
23.08.11
11:07
(36) Вопрос не в оптимизации, а в фатальной ошибке, которая произойдет, если вызывать запись из обработчика записи. Получится ничто иное, как бесконечная рекурсия. Последствия просто не могут быть "не принципиальными".
Хотя это уже выходит за границы темы (а ТС из нее вообще ушел:)
38 kuza2000
 
23.08.11
18:23
(25),(26)
Да, попутал. Вот что на самом деле я имел ввиду:

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

Ранее предложенный вариант будет работать на небольших базах. А вот если справочник вырастет до сотен тысяч - миллионов записей, то могут быть серьезные проблемы. Да и на несколько меньших объемах будет отрыв по производительности, особенно при добавлении новых записей. Кто не верит - может провести реальный тест.
39 kuza2000
 
23.08.11
18:26
(30)
Точно так! :)
40 Aleksey
 
23.08.11
19:14
(38) не понял какая печалька системы из каких цифр состоит гуид? Т.е. если я гуид сам рисую, будет тормоза? С какого перепуга?
41 agent-J
 
23.08.11
19:22
А я вот не понимаю главный вопрос - нафига?! Зачем в элементе в реквизит записывать ссылку на самого себя? Тем более что это циклическая ссылка и она еще и у к утечкам памяти приводить может
42 kuza2000
 
23.08.11
19:59
(40)
  Печалька в том, что по нему строиться кластерный индекс. При генерации ссылки стандартными средствами это учитывается. Гуиды для ссылок генерируются таким образом, что при сохранении в БД они получаются строго в порядке возрастания. Таким образом новые элементы физически (именно физически - в файле БД или файле SQL) располагаются друг за другом. Накладные расходы при добавлении записи в конец таблицы минимальны. Если генерировать произвольно - то новые записи втыкаются в случайное место таблицы, приходится добавлять новые блоки, разбивать старые, делать кучу лишних телодвижений по перестроению кластерного и других индексов.
  Но есть и еще очень важная вещь, которая может значительно повлиять на производительность не только вставки, но и впоследствии самых различных запросов, в которых будет использоваться этот справочник (и особенно - если это документ). В больших, постоянно растущих, справочниках обращение выполняется, как правило, к более свежим элементам. Если элементы в таблице физически расположены в порядке добавления, то при таком расположении может потребоваться намного меньше дисковых операций, чем если бы они были расположены в таблице случайным образом.
  Кстати, для документов кластерный индекс делается точно так же - по ссылке. Таблица документов растет постоянно, причем обращение тут идет строго к "кучкам" документов (типично выборка - месяц, квартал, год). И если написать такую генерацию ссылки как в первом варианте, то последствия для производительности могут оказаться просто фатальными. Причем выясниться это не сразу, а через годик-другой, когда таблица документов вырастет. Фактически, это получиться просто логическая бомба медленного действия. Причем исправление кода в конфигурации ситуацию не исправит.
43 DrMabuzo
 
23.08.11
20:35
(42) а я согласен с Кузей, во всем кроме логической бомбы. Дело в том, что кластерный индекс даст выигрыш только в том случае, если в результате запроса данные требуются именно в том порядке, в котором были записаны. Как по мне, то таких запросов мало и обычные индексы справятся не хуже
44 milan
 
23.08.11
21:06
(43) кластерный индекс будет использоваться почти всегда.
45 kuza2000
 
23.08.11
21:17
(43)
  Насчет бомбы - это я про документы. Там данные почти всегда требуются за месяц, квартал и т.д. То есть как раз те, которые были записаны подряд. Важен не порядок, а что они будут в кучке. В одном блоке, или в некотором количестве подряд идущих. Система считает их "одним махом". А если данные рассеяны по всей таблице, системе придется прочесывать всю таблицу (или ее значительную часть), и выбирать документы среди множества блоков, считывая с диска огромное количество не нужных данных. И системный индекс по периоду тут не сильно поможет.
  А вот для справочника - как повезет, насколько будут кучковаться данные.
  Самое главное преимущество кластерного индекса - это возможность собрать в кучку данные, которые используются вместе и считывать их разом, очень быстро, сразу все, и не обрабатывать ненужные участки таблицы, не искать среди других данных.
46 Икогнито
 
23.08.11
23:12
(42) как все сложно...
Чувствую себя полным ламером.

(13) Спасибо, друг! Подошло с первого раза.
47 Икогнито
 
23.08.11
23:13
(45) это на каких объемах БД работать приходится, чтобы обладать такими знаниями?
48 ilkoder
 
23.08.11
23:21
Я таки думаю, что если объем базы данных приблизится к терабайту, то может быть тогда и придется думать про кластерные индексы, только тогда придется использовать не 1С. А когда вся база в принципе может влезти в кэш памяти sql сервера, то там тормоза возникают по другим причинам...
49 Икогнито
 
23.08.11
23:24
(48) тема про ссылку на самого себя, при чем тут клистирные индексы?
50 kuza2000
 
24.08.11
01:42
(48)
  Скорость обработки транзакций в правильно спроектированной базе данных не должна зависеть от объема БД - хоть терабайт, хоть сто терабайт. 1С может работать с любыми объемами БД. Но вот что бы так было, НАДО думать и про кластерные индексы, и про не кластерные. Примерно представлять, как устроены реляционные базы данных и т.д.
  Прошу прощения, что увел тему в сторону. Просто я увидел довольно серьезный и не очевидный ляпус в приведенном фрагменте кода, и рассказал про него. Надеюсь, кому нужно, поставили себе галочку - авось, пригодится.
51 Икогнито
 
24.08.11
02:14
(50) глобализм - современная проблема, бери террабайтный диск
52 Defender aka LINN
 
24.08.11
08:26
(50) При переносе документов из складской БД в 1С вполне себе генерим UUID'ы. Все живы.
53 kuza2000
 
24.08.11
09:51
(52) Разве кто-то против генерации гуидов?
54 Defender aka LINN
 
24.08.11
10:16
(53) Ты :) Ты ж ужасы рассказываешь, что на больших объемах все вымрет :)
55 kuza2000
 
24.08.11
10:26
(54) Да генерируй сколько хочешь :)

Но только вот так:

   НоваяСсылка = Справочники.Номенклатура.ПолучитьСсылку()

А вот так лучше не надо:

   УИД = Новый УникальныйИдентификатор;
   НоваяСсылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);
56 kuza2000
 
24.08.11
10:28
Ну или можно самому генерировать последовательно, разобравшись в структуре системных ИД, там ничего сложного нет, цифры по возрастанию, но придется некоторые байты гуида местами переставить.
57 Defender aka LINN
 
24.08.11
10:29
(55) Дык вот именно вот так мы и генерируем. Только УИД получаем сами. 2Тб - полет нормальный )
58 kuza2000
 
24.08.11
11:00
(57) А сами - это как? По какому принципу? Большой объем документов за месяц таким образом грузиться? Сколько лет базе уже?
59 Defender aka LINN
 
24.08.11
12:17
(58) Тупо берется ИД (числовой) из базы склада и приводится к строке вида "00000000-0000-0000-aaaa-xxxxxxxxxxxx".
Документов - несколько тысяч в месяц, 500 пользователей. Вроде ворочается :)
60 kuza2000
 
24.08.11
12:47
(59) Если aaaa - это тип, а xxxxxxxxxxxx - это номер, генерируемый последовательно, то все должно быть хорошо. Правда, 1С переставляет байты, и в базу пойдет так:

aaaa-xxxxxxxxxxxx-00000000-0000-0000

Но все равно документы "лягут" в базу друг за другом.
61 kuza2000
 
24.08.11
12:49
Кстати, разницу в значениях, создаваемых системой можно увидеть, выполнив несколько раз такой код:

Сообщить(Справочники.Номенклатура.ПолучитьСсылку().УникальныйИдентификатор());

а потом такой:

Сообщить(Новый УникальныйИдентификатор());
62 Defender aka LINN
 
24.08.11
13:11
(60) aaa - это aaa :) Если ИД<0, то там "bbb" :)
63 kuza2000
 
24.08.11
13:17
(60) Ясно. Главное, что все равно тут документы будут рядом. База живет и будет жить долго и счастливо. И умрет не из-за плохих гуидов :)
64 kuza2000
 
24.08.11
13:20
(62) -> (63)