Имя: Пароль:
1C
1C 7.7
v7: ID незаписанного документа
0 Стрелок
 
21.12.12
11:34
Доброго дня. Ломаю голову как сделать такое - надо в некий справочник записать ссылку на документ в момент "ПриЗаписи" не только тогда когда он уже "Выбран()=1" но и при самой первой записи. Но так, чтобы когда запись уже отработает и документ попадёт в базу - в справочнике была бы ссылка на него а не ID. Как? возможно ли такое в принципе?
24 Mikeware
 
21.12.12
11:54
(23) что-то не помню такого
25 Стрелок
 
21.12.12
11:54
(23) не понимаешь - твои проблемы. я достаточно ясно объяснил условие задачи и то почему мне не подходит обработка в ПриЗакрытии. мало?
26 Aleksey
 
21.12.12
11:54
(20)
ПриЗаписи
СписокСохраненыхРеквизитов=СоздатьОбъект("СписокЗначений");
СписокСохраненыхРеквизитов.Добавить()
....


Вариант1
ПриЗакрытии
Если Новый=1 тогда
//нужно записать в справочник

Вариант2
ПриЗакрытии
Если СписокСохраненыхРеквизитов.РазмерСписка()>0 тогда
//нужно записать в справочник
27 Aleksey
 
21.12.12
11:55
(25) А ты не хами, а послушай что тебе другие говорят
28 Стрелок
 
21.12.12
11:55
(21) вот вот но как мне его получить? и как записать? может и приснилось такое, но кажется я встречал прямую запись ссылки в таблицу 1С так, что при открытии таблицы в 1С 9например справочника) отображается уже объект
29 Надсмотрщик
 
21.12.12
11:55
Доп реквизит в доке - GUID
И пиши его куда хочешь, а при проведении кидай саму ссылку
30 Стрелок
 
21.12.12
11:55
(27) я тебя послушал и высказал своё мнений. спасибо не надо. что непонятно? сказать есть что? не умничай
31 Стрелок
 
21.12.12
11:56
мля баран. поясняю для тех кто в пронепоезде МНЕ НАДО ПОЛУЧИТЬ ССЫЛКУ НА ДОКУМЕНТ ПРИ ПЕРВОЙ ЕГО ЗАПИСИ ЧТОБЫ ЗАФИКСИРОВАТЬ ПЕРВОНАЧАЛЬНЫЕ ЗНАЧЕНИЯ РЕКВИЗИТОВ!!!!
32 Aleksey
 
21.12.12
11:56
(24)
Перем Новый;

Процедура ВводНаОсновании(ДокументОснование) //предопределенная
 Новый = 1;
...

////////////////////////////////////////////////////////////
// ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ
//************************************************************Новый = 0;
33 Стрелок
 
21.12.12
11:56
(29)каком проведении? куда кидать?
34 Aleksey
 
21.12.12
11:57
(31) Не ори. Ссылка в при закрытии НЕ меняется, поэтому тупо бери ссылку в призакрытии
35 Стрелок
 
21.12.12
11:57
(32) заканчивай зас ирать ветку тупыми копипастом со своих поделок.
36 Стрелок
 
21.12.12
11:58
(34) И куда я её вставлю? во блин. читай внимательно задачу!!!
37 Эльниньо
 
21.12.12
12:00
Транзакия
Записать()
Отменить
38 йети
 
21.12.12
12:02
(31) совсем не изменился :)
39 Ёпрст
 
21.12.12
12:02
(0)
ну пиши туда НовыйИД() объекта sqllock
40 Стрелок
 
21.12.12
12:02
Вот чего нарыл

SQLLock

НовыйИД / GetNewID

Синтаксис: НовыйИД()

Возвращает: тип: Строка. Новый идентификатор (строка 9 символов).

Описание: позволяет получить новый идентификатор объекта.
41 Ёпрст
 
21.12.12
12:03
(40) :)
42 Стрелок
 
21.12.12
12:03
(39) вооо !!!

а теперь вопрос - получается мне надо сделать так чтобы у этого документа был точно этот новый ID. Как? и как этот новый ID записать в справочник так чтобы потом при открытии справочника был документ а не строка?
43 Стрелок
 
21.12.12
12:04
в базе одновременно работает 10-15 человек которые работают с документами очень активно (в этом и причина дополнительного логирования изменений в документах)
44 Стрелок
 
21.12.12
12:04
(37) что это даст?
45 Стрелок
 
21.12.12
12:05
(38) горабатого могила... ну ты в курсе
46 Aleksey
 
21.12.12
12:09
(36) я как раз внимательно читаю, а ты неочень

Перем СписокСохраненыхРеквизитов

Процедура ПриЗаписи()

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

// ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ
СписокСохраненыхРеквизитов = =СоздатьОбъект("СписокЗначений");
47 Ёпрст
 
21.12.12
12:10
(44) сможешь получить ссылку на объект..
пробуй:
НачатьТранзакцию()
Записать();
Ссылка  = ТекущийДокумент();// (ТекущийЭлемент())
ОтменитьТранзакцию();
Сообщить(Ссылка);
ну и в объект пихай ссылка
48 ЧеловекДуши
 
21.12.12
12:10
(31)Дятел :(
И грубиян!!!
49 Стрелок
 
21.12.12
12:10
(47) хорошо. отменилась транзакция и в этот момент кто то лупанул записать в другом документе? что тогда будет?
50 ЧеловекДуши
 
21.12.12
12:11
(47)А смысл? от такой ссылки?
Она будет реально ссылаться на липовый объект, который БУДЕ еже создан далее :)
51 Ёпрст
 
21.12.12
12:11
всё это в приЗаписи, к примеру.. ну или, где тебе там надо.

Всё, в реквизите другово объекта, где будет ссылка - уссё будет хорошо, если не запишешь - там будет битай ссылка с <объект не найден>
52 Aleksey
 
21.12.12
12:11
(47) Зачем транзакцию? Почему просто нельзя в при записи без транзакции записать? Но автор же не хочет это делать, типа не кошерно
53 trad
 
21.12.12
12:12
(47) сильно сомневаюсь, что при "настоящей" записи будет сформирован тот же ИД.
54 Ёпрст
 
21.12.12
12:12
(49) нормально всё будет, счетчик уникальных ид ужо увеличился, по идее будет создан документ с другим iddoc
55 Стрелок
 
21.12.12
12:12
(46) хорошо - ещё раз

первый раз записали объект. значение поля "Кво"=1 потом НЕ ЗАКРЫВАЯ изменили "Кво". Что запишется в качестве значения поля Кво в ПриЗакрытии?
56 Ёпрст
 
21.12.12
12:12
(53) ща проверим.. в демке.
57 ЧеловекДуши
 
21.12.12
12:12
(52)Потому, что автору в (0), нужен какой-то изврат.
И к тому же он не понимает, что команда "НачатьТранзакцию" будет вешать всю БД :)
58 Aleksey
 
21.12.12
12:13
(55) Ровно то, что у тебя будет в СписокСохраненыхРеквизитов
59 Aleksey
 
21.12.12
12:13
пихай туда всё что тебе нужно, включая выгруженную в ТЗ ТЧ
60 ЧеловекДуши
 
21.12.12
12:13
(55) Последняя "Кво". А если еще и в модуль проведения вставишь, то последняя при проведении "Кво"
61 trad
 
21.12.12
12:14
(56) не забудь в демке задействовать два сеанса, которые одновременно заходят в ПриЗаписи()
62 Aleksey
 
21.12.12
12:14
Другой вопрос, нафига козе баян?
Т.е. я создал документ и записал его, не заполняя. Потом начинаю заполнять его. Смысл в том что у меня было в первой записи?
63 Стрелок
 
21.12.12
12:15
(52) вот блин.... кошерно, но оставляю на последок этот метод. проще всего добавить в ПриЗаписи условие на Выбран и Записать.

(60) БИНГО!!!!! а мне надо НАЧАЛЬНЫЕ значения. теперь понятен гнев в 31? чел говорит правильные вещи но они неприменимы в данном случаи
64 ЧеловекДуши
 
21.12.12
12:15
+(56)А лучше 10 или 50, как в реальной работе :)
65 trad
 
21.12.12
12:15
(61) + при этом заходят туда в одном порядка, а выходят в обратном
66 Стрелок
 
21.12.12
12:15
(62) Есть смысл есть....
67 Aleksey
 
21.12.12
12:16
(63) Дятел, читай что я тебе пишу, если ты у меня спрашиваешь
68 Aleksey
 
21.12.12
12:17
А потом кричишь, что я не читаю. По себе людей не судят
69 Стрелок
 
21.12.12
12:18
ВОт смотрим схему Алексея

1. первая запись 00:00:01 (значения реквизитов залили в ТЗ и отложили её до закрытия)
2. изменения документа и вторая запись (объект выбран) 00:00:05 - запись в журнал регистрации изменённых реквизитов
3. закрытие документа 00:00:10 - запись в журнал первоначальных значений с признаком "новый документ"

Классно - телега впереди лошади?
70 Стрелок
 
21.12.12
12:19
(68) смотри внимательно 69. внимательно внимательно
71 Aleksey
 
21.12.12
12:19
(69) Причем тут ЖР и справочник? Ручь изначально про справочник был

Туту телепатов нет, что спросил, то и получил
72 Стрелок
 
21.12.12
12:20
(71) а говоришь внимательно читаешь ;) ;)

  Стрелок
7 - 21.12.12 - 11:45
   (4) всё просто - надо в альтернативном журнале регистрации фиксировать запись нового документа с содержимым. Проблема только в одном - ссылка на этот документ в этом самом журнале
73 Стрелок
 
21.12.12
12:21
(+72) ну теперь чего скажешь?
74 Aleksey
 
21.12.12
12:22
(72)  И? Тогда вопрос, Какая релищия тебе мешает в СписокСохраненыхРеквизитов писать и время?
75 Mikeware
 
21.12.12
12:22
(49) нормально будет. следующему документу уже выделен следущий ид.
а вот как система себя будет вести после отмены транзакции - хез.  Делал нечто подобное, так падала...
76 ADirks
 
21.12.12
12:22
Если надо альтернативный журнал регистрации, то может перехватить события регистрации? Ну и при "Записан новый документ" писать в свой лог.
77 Стрелок
 
21.12.12
12:23
(74) ага я ждал этого.. время, позицию, что ещё? а если я добавлю что этот альтернативный журнал мониторится постоянно и записи туда должны попадать реальным временем.... как в стандартный журнал....
78 Стрелок
 
21.12.12
12:24
(+77) а ведь ты начинал просто со списка реквизитов ;)

ты пойми я задаю вопросы только тогда когда перепробовал кучу вариантов....
79 Mikeware
 
21.12.12
12:24
Этто, а не проще ли перехватчик заюзать, и в перехвате записи журнала регистрации, если событие "запись нового документа" - делать все, что надо
80 Стрелок
 
21.12.12
12:25
(76) дело то не в перехвате - он и так срабатывает в ПриЗаписи. дело в ссылке
81 Aleksey
 
21.12.12
12:25
(77) я тебе уже сказал по этому поводу, либо ты полностью озвучиваешь задачу, либо не истиришь по поводу того что никто не догадался что тебе нужно
82 Стрелок
 
21.12.12
12:25
(79) как? до перехватчиков я небрался... что почитать? заюзать? и как мне из этого перехватчика получить ссылку на новый документ?
83 Mikeware
 
21.12.12
12:26
(76) :-)
84 Стрелок
 
21.12.12
12:26
(81) задача полностью озвучена в (0). В самом необходимом объёме. Я не просил альтернативных вариантов. я чётко задал вопрос.
85 Стрелок
 
21.12.12
12:27
журнал - применение не более. меня реализация изложенного в (0) интересовала
86 Mikeware
 
21.12.12
12:27
(82) что почитать? документацию, вестимо...
http://www.1cpp.ru/docum/icpp/html/Hooker.html#addevent-reporteventa
87 Aleksey
 
21.12.12
12:27
(84) В рамках этой задачи мой вариант полностью подходит, но ты же к 50 посту начал уточнять,
88 Стрелок
 
21.12.12
12:30
(87) ты предложил альтернативу применения а вопрос был про ссылку незаписанного документа
89 Ёпрст
 
21.12.12
12:32
(61) не не вышло, обломсъ

выдается тот-же айди в другом сеансе и при попытке записи - объект заблокирован :)
90 Стрелок
 
21.12.12
12:33
(89) плохо.. ладно видать прийдётся заюзать Записать в ПриЗаписи если Выбран()=0 всем спасибо... на досуге ковырну перехватчиков - может чего и получится альтернативное
91 ADirks
 
21.12.12
12:34
(84) в таком то виде тебе уж сказали единственное верное решение - свой реквизит со своим ИДшником, GUID к примеру.
92 trad
 
21.12.12
12:36
(89) так то есть потенциально не безнадежный способ, но надо проверять
93 Стрелок
 
21.12.12
12:38
(91) И? дальше то что? ну будет свой код. запишу я его в справочник. а при открытии справочник что? исать док и коду и выводить его?
94 ADirks
 
21.12.12
12:39
(93) именно так
95 Стрелок
 
21.12.12
12:42
(94) долго и неэффективно имхо
96 Стрелок
 
21.12.12
12:42
(+95) даже если это делать только один раз для новых документов
97 Ёпрст
 
21.12.12
12:43
(95) да ну ?
поиск мгновенный по индексированному значению ид
98 ADirks
 
21.12.12
12:43
(95) а по IDDoc искать - это быстро и эффективно?
99 trad
 
21.12.12
12:44
(92)+ годный правда только для sql
примерная схема такая:
В ПриЗаписи
1. set implicit_transactions on
2. exec _1sp_МДИД_TLockX
3. получаем ИД при помощи того же SQLLock или сами вычисляем - это не сложно
4. пользуем этот ИД где надо
все
после завершения процедуры ПриЗаписи начнется алгоритм штатной записи, который представляет из себя те же пп. 1-3, но на этот раз транзакция новая не будет начата, т.к. уже начата наша и вторая блокировка - тоже в пустоту. Далее запись данный. И наконец при @@trancount>0 commit tran
100 1Сергей
 
21.12.12
12:46
cto
101 Стрелок
 
21.12.12
12:46
(99) база скуль.. а подробнее можно?
102 trad
 
21.12.12
12:47
(101) куда еще подробнее. подробнее это уже написание кода. И то он уже наполовину написан :)
103 Стрелок
 
21.12.12
12:48
(102) ладно спасибо
104 trad
 
21.12.12
12:51
у меня по такому принципу сделана запись номенклатур с заполнением дыр в кодах.

Процедура ПриЗаписи()

   //прочее

   Если Выбран()=0 Тогда
       //при записи нового элемента назначаем новый код с заполнением "дыр"
       рс=СоздатьОбъект("ODBCRecordset");
       рс.ВыполнитьИнструкцию("
       |set implicit_transactions on
       |exec _1sp_"+рс.мд.ИмяТаблицыСправочника("Номенклатура")+"_TLockX
       |");
       ТекстЗапроса="
       |select min(cast(code as int)) + 1
       |from $Справочник.Номенклатура (nolock)
       |where cast(code as int) + 1 not in (select cast(code as int) from $Справочник.Номенклатура)
       |";
       Код=рс.ВыполнитьСкалярный(ТекстЗапроса);
   КонецЕсли;
КонецПроцедуры
105 Эльниньо
 
22.12.12
10:39
Чем дело кончилось?
106 Мимохожий Однако
 
22.12.12
13:31
ПолуОФФ:Однажды понадобилось сохранять информацию о несохраненных чеках. При считывании сканером продавец определял стоимость товара, называл сумму клиенту и потом... не сохранял чек. Добавил при закрытии запись нужных данных в текстовый файл. Владельца бизнеса это устроило. Через пару смен он чётко определил продавца, который торговал леваком.
107 Стрелок
 
22.12.12
14:51
(106) Другой случай. Тут сохраняют 100 % но могут изменить первоначальный документ между сохранением и закрытием
108 Mikeware
 
22.12.12
14:55
(107) ну так зачем тебе _первоначальные_ данные?
тебе достаточно иметь  "было-стало". Если объект уже есть в базе, значит, это перезапись - ну и вычисляй и пиши на здоровье _изменения_.
109 Стрелок
 
22.12.12
14:57
(108) было-стало уже рализовано. Надо фиксировать факт записи нового документа с его содержимым на момент первой записи. Всё. точка. так в ТЗ клиента (его пожелание)....
110 Torquader
 
22.12.12
14:57
Если идёт работа из формы документа, то можно сделать так:
1) Переменную модуля - Перем НужноСохранить;
2) В ПриЗаписи после того, как успешно записали:
Если Выбран()=0 Тогда
НужноСохранить="ЗаписатьВСправочник";
КонецЕсли;
Форма.Закрыть(0);
3) В ПриЗакрытии:
Если НужноСохранить="ЗаписатьВСправочник" Тогда
СтатусВозврата(0);
ВыполнитьЗаписьВСправочник();
НужноСохранить=0;
Возврат;
КонецЕсли;
111 Mikeware
 
22.12.12
14:58
(109) гавновопрос. если у тебя _первое_ изменение - вычисляй и пиши первоначальный вариант.
112 Стрелок
 
22.12.12
15:01
(111) да со значениями всё понятно. мне бы ссылку на документ получить в ПриЗаписи
113 Torquader
 
22.12.12
15:05
(112) Система производит запись документа только после успешного выполнения ПриЗаписи (если там статус возврата не поменяли) и в случае многопользовательского доступа система узнает ID только после записи, так как исключить вклинивание другого сеанса нельзя, а счётчик идентификатора для всех документов один и тот же.
Всякие хитрости иногда приводят к тому, что несколько документов получают одинаковый ID - это приводит к тому, что в базе остаётся только последний документ.
114 Стрелок
 
22.12.12
15:06
(113) это понятно. в лоб к задаче не подойдёшь. точнее можно сделать просто но хотелось более красивый вариант чем Записать в ПриЗаписи
115 Torquader
 
22.12.12
15:06
P.S. у меня используется Записать в ПриЗаписи, причём, чтобы два раза в базу не писать, также используется и СтатусВозврата(0).
116 ADirks
 
22.12.12
15:07
(109) Клиенты они такие клиенты...
Но при такой постановке вопроса всёж разумнее перехватить событие записи в журнал регистрации. Потому что в ПриЗаписи ещё нет полной ясности, а запишется ли.
117 Torquader
 
22.12.12
15:07
(114) Чем тебя (110) не устраивает ?
118 Torquader
 
22.12.12
15:08
(116) Кстати да - если будет ошибка записи в базу, то система об этом сообщит, но ПриЗаписи отработает без ошибок.
В случае открытия транзакции в другом сеансе могут быть отказы в записи документов из-за блокировки журнала другой транзакцией.
119 Стрелок
 
22.12.12
15:09
(117) тем что

2) В ПриЗаписи после того, как успешно записали:

подразумевает Записать в ПриЗаписи

а это значит что всё остальные телодвижения из 110 не имею смысла. У меня последней строкой в ПриЗаписи идёт запись данных в альтернативный журнал регистрации. нет необходимости выполнять код

Если Выбран()=0 Тогда
НужноСохранить="ЗаписатьВСправочник";
КонецЕсли;
Форма.Закрыть(0);
3) В ПриЗакрытии:
Если НужноСохранить="ЗаписатьВСправочник" Тогда
СтатусВозврата(0);
ВыполнитьЗаписьВСправочник();
НужноСохранить=0;
Возврат;
КонецЕсли;
120 Стрелок
 
22.12.12
15:09
(116) почему нет?
(118) что значит "ошибка записи"?
121 Стрелок
 
22.12.12
15:10
ладно..пошёл я плитку в ванной класть. А то супруга рычит ;)
122 Torquader
 
22.12.12
15:14
(120) Предположим, один сеанс открыл транзакцию записи документов - она заблокировала журнал.
Теперь в нашем сеансе выполняется запись.
Сначала успешно отработала "ПриЗаписи" потом система переходит к непосредственной записи и генерации ID.
Записать в журнал она не может и ждёт какое-то время освобождения транзакции (время ожидания настраивается) а после этого времени просто выдаётся ошибка - документ не будет записан.

P.S. у меня тоже есть журнал регистрации изменений, но он как раз работает с помощью записать в ПриЗаписи, так как до записи можно найти элемент в базе (если он ранее был записан) и через этот объект получить все данные документа до записи, а через контекст мы получаем всё, что есть на данный момент - просто нужно пройти по метаданным и выполнить сравнение.

Удачи - да, кстати, выходной - нужно к компьютеру меньше подходить, а то всю неделю на него смотрел.
123 Torquader
 
23.12.12
14:18
Кстати, для тех, кто хочет быть похожим на восьмёрку:

Процедура ПриЗаписи()
СтатусВозврата(0);
Если МожноЗаписать()<>1 Тогда Возврат;КонецЕсли;
ВыполнитьЗапись();
ОбработкаПослеЗаписи();
КонецПроцедуры

Ну и написать три функции - будет чем-то похоже на восьмёрку.
P.S. не забыть, что в ВыполнитьЗапись нужно сделать Записать для элемента.