Имя: Пароль:
1C
1С v8
Прочитать старые значения реквизитов перед записью
0 ramir
 
12.02.12
13:06
Долго гуглил форум, но ответа так и не нашел. Хочу организовать отслеживание изменений в документах. В подписке на событие "ПриЗаписи" необходимо прочитать старые данные объекта, как это возможно?
1 Рэйв
 
12.02.12
13:09
Процедура ПередЗаписью.

Сравнивайт ЭтотОбъект и Ссылка.
2 Рэйв
 
12.02.12
13:09
*Сравнивай.
3 Рэйв
 
12.02.12
13:09
+(1)В модуле объекта, не формы.
4 zak555
 
12.02.12
13:11
(1) где ещё не записанные данные ?
5 Рэйв
 
12.02.12
13:13
(4)Именно.Как раз можно сравнить со ссылкой
6 zak555
 
12.02.12
13:15
пля, муль в терминале отвалился =(
7 zak555
 
12.02.12
13:18
(5) я запутался : где хранится изменённый объект ?
8 ramir
 
12.02.12
13:26
Заголовок функции подписки выглядит так:
Процедура ПодпискаНаЗаписьОбъектовПриЗаписи(Источник, Отказ) Экспорт

Я пробовал сравнивать значения реквизитов Источник[Реквизит] и Источник.Ссылка[Реквизит] - одно и то же. Только новые данные. Хотя отказаться от записи можно, значит старые данные еще не затерты.
9 Дикообразко
 
12.02.12
13:27
в УПП уже готовый механизм есть..
лисапед?
10 Рэйв
 
12.02.12
13:28
(8)Ты наверное совсем не читаешь , что тебе пишут,да?
Я это дело давным давно реализовал.Заипали меня приходы бухов с утверждениями "Это ваша программа не работает"...Я сделал запись истории на принципе выше указанном.  После 2-3 раз приходить перестали
11 ramir
 
12.02.12
13:32
(10) Я все внимательно прочитал. Документов много и не хочется создавать у каждого обработчик события. В первом сообщении явно указал, что делаю через подписку. Меня интересует, возможно ли это?
12 Рэйв
 
12.02.12
13:38
(11)>>не хочется создавать у каждого обработчик события.
Ну тогда ищи дальше ОПТИМАЛЬНОСТЬ.

Сочувствую.
13 ramir
 
12.02.12
13:43
(12)Надеюсь это искренне) Также создается ощущение, что Вы нашли в жизни оптимальный путь и в поисках его не нуждаетесь. А те, кто его ищет поступают неправильно?))

А вообще для меня более важна приспособленность конфигурации к изменениям, т.к. ни на день она не остается без изменений.
14 Рэйв
 
12.02.12
13:48
(13)>>А те, кто его ищет поступают неправильно?))
Правильно конечно. Только полный идиотизм игнорировать советы тех, кто это все прошел много лет назад.
15 ramir
 
12.02.12
13:51
(14)Много лет назад и 1Ска была другая. С Вами очень приятно разговаривать)
16 H A D G E H O G s
 
12.02.12
17:10
(15) Ты правда не читаешь, что тебе пишут.

В подписке ПриЗаписи() объект уже записался и значения Источник и Источник.Ссылка - одинаковые.
В подписке ПЕРЕДЗаписью() объект ЕЩЕ не записался и значения Источник и Источник.Ссылка - разные.
17 zak555
 
12.02.12
17:12
(16) Источник - это то, что "собирается" записаться ?
18 Дикообразко
 
12.02.12
17:24
(17) это указатель на объект в ОЗУ
19 ramir
 
13.02.12
13:47
(16) Да, в этом я не прав. В списке подписок не было события ПередЗаписью, т.к. указал не только документы. Поэтому понял, что речь идет не о подписках. Почему же тогда есть возможность отказаться от записи в подписке ПриЗаписи?

А вообще вернулся к исходному вопросу и надобность в старых данных пропала, т.к. они сохраняются при предыдущей записи. Спасибо за помощь. :)
20 Ненавижу 1С
 
гуру
13.02.12
13:50
(19) >> Почему же тогда есть возможность отказаться от записи в подписке ПриЗаписи?
потому что транзакция!
21 Shurjk
 
13.02.12
13:52
(3) В  модуле формы тоже можно.
22 fisher
 
13.02.12
13:56
Эффективнее при открытии формы запоминать старые значения реквизитов, чем в БД при записи лезть.
23 Shurjk
 
13.02.12
14:04
(22) Интересное заявление - аргументировать можешь?
24 fisher
 
13.02.12
14:07
(23) Тю. Так аргументация уже в заявлении. Не будет лишних запросов к БД.
25 Shurjk
 
13.02.12
14:13
(24) Вообще  то, документ уже и так в оперативной памяти его ведь уже прочитали один раз - зачем еще раз читать?
26 fisher
 
13.02.12
14:15
(25) Вот и я о том же.
27 Shurjk
 
13.02.12
14:18
(26) То есть при обращении Ссылка.Реквизит думаешь он будет заново перечитывать документ? Учитывая то что этот же экземпляр сам же его заблокировал?
28 fisher
 
13.02.12
14:25
(27) Ага.
29 Shurjk
 
13.02.12
14:26
(28) Как то совсем глупо - даже для 1с-ки выходит. По 8.1 помниться было так называемое динамическое чтение, а 8.2 даже не знаю как это делается.
30 vde69
 
13.02.12
14:27
примерно так:

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


Процедура ПриЗаписиОбъектовСРолевымДоступомПриЗаписи(Источник, Отказ) Экспорт
   ЗаписатьДоступОбъекта(Источник, Отказ);
КонецПроцедуры

Процедура ЗаписатьДоступОбъекта(Источник, Отказ) Экспорт
   УстановитьПривилегированныйРежим(Истина);
   
   Если Источник.ОбменДанными.Загрузка Тогда
       Возврат;
   КонецЕсли;
               
   ОбновитьДоступ = Ложь;
   Источник.ДополнительныеСвойства.Свойство("ОбновитьДоступ", ОбновитьДоступ);
   
   Если не ОбновитьДоступ = Истина Тогда
       Возврат;
   КонецЕсли;
   
   ТипЗначенияИсточника = ТипЗнч(Источник);
   МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗначенияИсточника);
   
   МассивХешей = Ложь;
   Источник.ДополнительныеСвойства.Свойство("МассивХешей", МассивХешей);
   
   Попытка
       // обновим все ролевые права доступа к объекту                                
       Рег = РегистрыСведений.РолевойДоступОбъектов.СоздатьНаборЗаписей();
       Рег.Отбор["Объект"].Использование = Истина;
       Рег.Отбор["Объект"].Значение      = Источник.Ссылка;
       Рег.Отбор["Объект"].ВидСравнения  = ВидСравнения.Равно;
       
       Рег.Прочитать();
       мТЗ = Рег.ВыгрузитьКолонки();  
       
       //---------------------------------------------
       // здесь гарантировано перезапишем весь набор для штатной единицы
       //                                                            
       Для каждого эл Из МассивХешей Цикл
           НоваяСтрока = мТЗ.Добавить();                    
           НоваяСтрока.Доступ = эл;
           НоваяСтрока.Объект = Источник.Ссылка;
       КонецЦикла;
       
       Рег.Загрузить(мТЗ);        
       Рег.Записать(Истина);
       
   Исключение
       Отказ = Истина;
   КонецПопытки;    
   
   УстановитьПривилегированныйРежим(Ложь);

КонецПроцедуры
31 Shurjk
 
13.02.12
14:27
(30) Ты это к чему?
32 Reset
 
13.02.12
14:29
(29) Имхо, она обязана сделать обращение, как минимум чтобы сверить ВерсияДанных (объект в БД могу быть изменен)
33 vde69
 
13.02.12
14:29
(31) к Вашему спору, все чтение и сравнение делается в подписке ДО ЗАПИСИ, потом готовый результат кладешь в ДополнительныеСвойства объекта, и уже в подписке ПРИ ЗАПИСИ берешь все из доп свойств и записываешь
34 H A D G E H O G s
 
13.02.12
14:30
Управляемое приложение всех расставит на свои места...
35 Shurjk
 
13.02.12
14:31
(33) Чем это будет быстрее чем прочитать через ссылку.
36 Shurjk
 
13.02.12
14:32
(32) Зачем ей это делать и как он может быть изменен если он заблокирован.
37 Адинэснег
 
13.02.12
14:33
*лицоладонь*
38 vde69
 
13.02.12
14:35
(35)это и есть прочесть через ссылку, ведь в памяти уже измененный обьект.
Вопрос не в том как сделать, а в том как сделать правильно, а правильно
1. чтение должно быть чистым (в текущей транзакции)
2. должен быть предусмотрен коррекнтый откат
3. сама запись не должна быть избыточной
39 Shurjk
 
13.02.12
14:37
(38) Ты бредишь? Во первых сравнение делаем перед записью, во вторых этотобъект и Ссылка в принципе разные вещи, откат осуществляется возможностями платформы, про избыточность ты тут сам себя перемудрил.
40 vde69
 
13.02.12
14:37
(36) объект в 1с блокируется только в момент записи, при открытии формы он не блокируется а всего-лишь получает новый номер версии. По этому НИКТО не мешает записать открытый у соседа документ.
41 Shurjk
 
13.02.12
14:40
(40) Все не так блокируется в момент внесения данных в форму.
42 vde69
 
13.02.12
14:44
(41) :)))) не блокируется

проверь, открой элемент (и даже измени в нем реквезит, при этом будет сгенерирована версия), и ОБРАБОТКОЙ перезапиши этот элемент

после этого элемент формы тебе не даст сохранить изменения из-за разности версий
43 Shurjk
 
13.02.12
14:50
(42) Если обработкой то да, а если две формы открыть то нет.
44 vde69
 
13.02.12
14:51
(43) это НЕ блокировка, это контроль версий, реализуется не объектом а формой...
45 Shurjk
 
13.02.12
14:53
(44) Хорошо а передзаписью блокируется документ?
46 fisher
 
13.02.12
14:54
(38) Не вижу смысла читать предыдущую версию из базы в транзакции записи.
47 vde69
 
13.02.12
14:56
(45) передЗапиью в модуле формы - нет
перед записью в модуле обьекта (и подписке) - да

для понимания сходи в поиск "план выполнения предопределенных процедур в транзакции записи"

для БП там очень наворочено :)
48 Shurjk
 
13.02.12
14:57
(47) Ну значит в процедуре перед записью уже установлена блокировка - так зачем тогда еще раз читать объект?
49 Shurjk
 
13.02.12
14:58
+(48) И чего ты все транзакции к месту и не к месту вставляешь?
50 vde69
 
13.02.12
15:05
(48) прочитан какой версии? и какой версии он в памяти?

это разные версии, по этому и нужно перечитать....


-------
а транзакции - это все фигня нафиг они не нужны и использовать их нельзя ни при каких условиях, да и в SQL уровень изоляции нужно установить самый низкий, тогда и блокировок не будет и скорость как у самолета будет.

правда косяки полезут, но разве это кого пугает :)
51 _Demos_
 
13.02.12
15:06
(48) проверил объект ОБРАБОТКОЙ перезапиывается.
Значит читать нужно из базы, а не сравнивать объект и ссылка.
52 _Demos_
 
13.02.12
15:07
(1)  ЭтотОбъект.Ссылка = Ссылка
разве не так
53 Shurjk
 
13.02.12
15:07
(51) Оно и понятно просто в таком случае тебе все равно объект не даст записать, вне зависимости от того пройдет он у тебя проверку или нет.
54 Shurjk
 
13.02.12
15:08
(50) Версию контролируются сервером 1с, но не севером БД, зачем чего то читать из базы?
55 hhhh
 
13.02.12
15:09
(52) они другое сравнивают: ЭтотОбъект и ЭтотОбъект.Ссылка. Они не равны. Перед записью ЭтотОБъект в памяти и никуда не записывается. ЭтотОбъект.Ссылка тоже в памяти, где-то в кеше.
56 Shurjk
 
13.02.12
15:11
(55) Вот и я о том же, но тут утверждается что если написать Ссылка. то он прочитает не и памяти а заново из базы.
57 _Demos_
 
13.02.12
15:12
(53) открыл два сеанса в одном изменил одно поле, если попробовать изменить во втором сеансе то пишет объект блокирован. Здесь открываем обработку и "выполнить"(там она перезаписывает) все проходит на ура. Дальше если поробовать записать в первой форме(который блокировал) то ошибка контроля версий!
58 _Demos_
 
13.02.12
15:13
+ (57) платформа 8.1
59 Shurjk
 
13.02.12
15:13
(57) Угу но не дает записать именно сервер 1с, он у нас и отвечает за блокировки. Так что все логично.
60 fisher
 
13.02.12
15:25
(56) Ага. Утверждается. Но на 100% я уже не уверен. Т.к. работает оптимизированная запись объектов, то возможно что в начале транзакции записи движок неявно читает текущую версию объекта из базы в транзакционный кэш. Короче, только эксперимент спасет отца русской демократии.
61 Shurjk
 
13.02.12
15:32
(60) А каким образом его провести? Проверить будут ли обращения к базе? Так там может сервре по каким другим своим нуждам обращался.
62 fisher
 
13.02.12
15:33
(61) Профайлером на пустом демо-доке сравнить обращения к БД.
63 _Demos_
 
13.02.12
15:35
+(57) проверил в файловом и клиент-серверном отрабатывает как в (57) 8.1. 8.2 не знаю
(61) на 8.2 внизу же пишет сколько раз и сколько метров передал
64 fisher
 
13.02.12
15:37
(63) Это обращения к серверу приложений.
65 Shurjk
 
13.02.12
15:52
(63) Ну это понятно, нас обращения к серверу интересуют.
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.