|
Как поступить если объект на форме изменен "извне" программно? | ☑ | ||
---|---|---|---|---|
0
toypaul
гуру
25.08.16
✎
09:12
|
По логике работы некоторая информация в документе может измениться программно извне - регламентным заданием или еще как. Если попытаться записать такой объект, выдается ошибка, что запись изменена. По правильному если делать, то нужно все это вынести в отдельные регистры/объекты, но это придется лопатить половину конфы.
Возможен ли такой вариант - мы сохраняем данные реквизитов формы, читаем объект из базы в форму (возможно такое?), заменяем сохраненные поля, кроме тех, которые (мы определяем какие) могут меняться программно. Если это проделать, можно будет далее записать объект? |
|||
1
Stepa86
25.08.16
✎
09:19
|
Вынести изменяемые поля в отдельные таблицы выглядит попроще, чем предложенный вариант.
|
|||
2
Cyberhawk
25.08.16
✎
09:21
|
Почему бы просто не обновить данные формы или перечитать объект в форме?
|
|||
3
toypaul
гуру
25.08.16
✎
09:26
|
(1) вот поверь. нифига не проще. там куча логики на эти поля завязана и отчетов. умрешь переделывать
(2) ну перечитать каждый дурак сможет :) надо еще сохранить то, что пользователь в документе поменял |
|||
4
Stepa86
25.08.16
✎
09:27
|
(2) Если изменения произошли через регл. задание, то на какое событие завязаться? Ну и перечитывание сбросит пользовательские изменения.
(0) В этом "извне" на изменяемые объекты вешается блокировка? По идее регл. задание должно посмотреть, что этот объект не используется, залочить его, поменять и разлочить, а клиент просто не сможет открыть форму залоченного объекта |
|||
5
toypaul
гуру
25.08.16
✎
09:28
|
(4) при попытке записи. или вообще вручную (по кнопке) если документ не записывается.
|
|||
6
Cyberhawk
25.08.16
✎
09:29
|
(3) Тогда сохраняй то, что навводил пользователь, в доп. свойства объекта, перечитывай объект чтобы не было оптимистической блокировки при его записи, а в модуле объекта уже возвращай сохраненные в доп. свойствах значения реквизитов
|
|||
7
toypaul
гуру
25.08.16
✎
09:29
|
(4) скажем так. в регл задании можно проверять. но есть другие места, где ну никак не проверишь - то есть надо менять поле сразу.
|
|||
8
Cyberhawk
25.08.16
✎
09:30
|
(4) "на какое событие завязаться?" // На то, при котором у него вылезает оптимистическая объектная блокировкка
|
|||
9
toypaul
гуру
25.08.16
✎
09:30
|
(6) примерно так и хочу сделать
|
|||
10
Cyberhawk
25.08.16
✎
09:31
|
(9) Затык будет в том, если данные, введенные в форме, преобразуются алгоритмами самой формы и в объект идет уже что-то пережеванное. Тогда придется и в модуле объекта этот алгоритм повторять
|
|||
11
toypaul
гуру
25.08.16
✎
09:32
|
только вот вопрос ... в каком месте программно поймать эту ошибку
|
|||
12
toypaul
гуру
25.08.16
✎
09:33
|
можно ли будет сравнить перед записью в форме версию объекта на форму и версию объекта в базе?
|
|||
13
Cyberhawk
25.08.16
✎
09:35
|
(12) Не лучший вариант - версия объекта (подгруженного в память) кэшируется и не обновляется даже при его изменении
|
|||
14
Cyberhawk
25.08.16
✎
09:37
|
Хотя вот тут пишут, что можно сравнивать версию данных в памяти и версию данных в БД: https://its.1c.ru/db/pubessence#content:149:hdoc
|
|||
15
Cyberhawk
25.08.16
✎
09:41
|
По (13) не совсем точно выразился: кэш не обновляется при вызове метода "Прочитать()", а метод "ПолучитьОбъект()" получает данные из объектного кэша, а не из БД
|
|||
16
toypaul
гуру
25.08.16
✎
09:47
|
"Теперь перед записью разработчик может самостоятельно сравнить версию редактируемых данных и версию данных, хранящихся в базе данных, и реализовать программный алгоритм их объединения и записи."
вроде как раз то, что мне надо |
|||
17
Cyberhawk
25.08.16
✎
10:00
|
(16) Только получай версию данных запросом, а не через точку
|
|||
18
Serg_1960
25.08.16
✎
10:04
|
Имхо: в "общем виде" задача сложно решаемая, а для конкретного документа - легко реализуемая.
Поясню: при интерактивном изменении пользователем элементов формы, связанных с данными, могут быть вызваны действия, которые изменяют другие элементы формы (как связанные с данными так и нет). При программном изменении данных, вышеуказанные действия, потребуется инициализировать программно. Сложно сказал? Тогда короче: программные изменения не равны интерактивным изменениям. Так понятнее? |
|||
19
toypaul
гуру
25.08.16
✎
10:07
|
(18) причем тут это? у нас есть объект в форме (перед записью) со всеми своими реквизитам и отработанной логикой и есть объект в базе со своими реквизитами и отработанной программной логикой. я знаю какие реквизиты я беру из объекта базы, а какие из формы. объединяю. перед записью перечитываю объект, объект записывается в базу.
причем тут интерактивные изменения? |
|||
20
toypaul
гуру
25.08.16
✎
10:09
|
другой вопрос ... зайду ли я в обработчики перед записью, если версии отличаются.
|
|||
21
Cyberhawk
25.08.16
✎
10:09
|
(18) Я про это в (10) тоже говорил
|
|||
22
zak555
25.08.16
✎
10:12
|
пользователь забивает данные в реквизиты формы (не связанные с основным реквизитом)
перечитываем основной реквизит |
|||
23
toypaul
гуру
25.08.16
✎
10:13
|
вот опа ... в перед записью не заходит до выдачи сообщения об ошибки. как быть?
|
|||
24
EugeniaK
25.08.16
✎
10:13
|
(0) Логичнее в фоновом задании проверять, не заблокирован ли объект формой.
И если заблокирован, то программно не менять. |
|||
25
toypaul
гуру
25.08.16
✎
10:13
|
(24) уже писал про это
|
|||
26
Cyberhawk
25.08.16
✎
10:17
|
(23) Попробуй перед записью вызвать метод формы ОбновитьОтображениеДанных
|
|||
27
Serg_1960
25.08.16
✎
10:17
|
(19) Причем, причем... при том :( Ты почему-то только один вариант обдумал: "микшируем" объект, записываем и закрываем форму. А если пользователь нажал кнопку "Записать" и не собирается закрывать форму, а желает продолжить редактирование? Придётся или "переоткрывать" форму... или то, о чём я предупреждал.
|
|||
28
Cyberhawk
25.08.16
✎
10:17
|
(ну или Обновить, если форма обычная, а не управляемая)
|
|||
29
toypaul
гуру
25.08.16
✎
10:17
|
(23) так не заходит в обработчик. сразу ошибку выдает
|
|||
30
toypaul
гуру
25.08.16
✎
10:18
|
(27) а в чем проблема-то? ну вызову я обработчики у измененных полей. я же не писал что мне универсальный механизм нужен.
|
|||
31
Serg_1960
25.08.16
✎
10:20
|
(29) Это на уровне платформы. Обработчики (как и подписки на события) вызываются позднее.
|
|||
32
Cyberhawk
25.08.16
✎
10:30
|
(29) Блокировка срабатывает до вызова события "ПередЗаписью" _формы_? Тогда тормозной костыль: в обработчике ожидания получать версию объекта в БД. Если отличается от версии, что на клиенте, то вызывать обновление данных формы...
|
|||
33
Cyberhawk
25.08.16
✎
10:31
|
+(32) Вместо последнего действия можно просто блокировать кнопку записи с подсказкой, чтобы пользователь сам обновил данные формы
|
|||
34
Serg_1960
25.08.16
✎
10:35
|
"Будь проще и к тебе потянутся люди" :) Сделай кнопку на форме "Обновить" и пусть юзверь жмёт её после получения ошибки.
|
|||
35
Serg_1960
25.08.16
✎
11:01
|
(уже уходя)
"Возможен ли такой вариант - мы сохраняем данные реквизитов формы[1], читаем объект из базы в форму (возможно такое?)[2], заменяем сохраненные поля, кроме тех, которые (мы определяем какие) могут меняться программно[3]. Если это проделать, можно будет далее записать объект?[4]" 1. Да, можно. Или Скопировать() в переменную, или сохранить в хранилище данных (можно подсмотреть алгоритмы работы версионирования). 2. Да, возможно. Например, в обычных формах достаточно изменить значение ДокументОбъект на объект из базы. 3. Цикл по метаданным объекта и сравнение значений. 4. Да. По сути дела, объект, считанный из базы в форму, изменён программно (модифицирован) и может быть записан как обычно. |
|||
36
Cyberhawk
25.08.16
✎
13:02
|
(35) Думаю, в 4 он именно про записью объекта из формы, отсюда и вся боль
|
|||
37
toypaul
гуру
25.08.16
✎
14:16
|
(35) 1. блин надеялся что простой способ получить копию текущего объекта РеквизитФормыВЗначение будет работать. зараза. не работает если версии отличаются.
|
|||
38
Torquader
25.08.16
✎
14:31
|
А в чём проблема - создать отдельный объект, и сверить его свойства с теми, которые есть на форме.
Проблема только в том, что мы не знаем, что поменяли мы, а что поменяли из-вне - то есть нужно ещё и версию документа на момент начала изменения хранить. |
|||
39
toypaul
гуру
25.08.16
✎
15:10
|
вот такое извращение получилось
|
|||
40
toypaul
гуру
25.08.16
✎
15:10
|
Процедура ПроверитьВерсиюОбъекта()
Если ЗначениеЗаполнено(Объект.Ссылка) Тогда Если Объект.ВерсияДанных <> Объект.Ссылка.ПолучитьОбъект().ВерсияДанных Тогда КопироватьДанныеФормы(Объект,КопияОбъекта); Прочитать(); КопияОбъекта.Состояние = Объект.Состояние; КопироватьДанныеФормы(КопияОбъекта,Объект); КонецЕсли; КонецЕсли; КонецПроцедуры |
|||
41
toypaul
гуру
25.08.16
✎
15:10
|
вызывается по обработчику ожидания, чтобы не жмакать кнопку обновления
|
|||
42
Cyberhawk
25.08.16
✎
21:27
|
(40) "Если Объект.ВерсияДанных <> Объект.Ссылка.ПолучитьОбъект().ВерсияДанных Тогда"
// Напиши обработку, которая программно перезаписывает объект. Запусти ее в другом сеансе - твой обработчик ожидания в первом сеансе сработает (ветка Если выполнится). Сразу после этого запусти обработку из другого сеанса еще раз - в ветку Если уже не попадешь, правильно? |
|||
43
Serg_1960
25.08.16
✎
21:47
|
(40) Поставь точку останова и посмотри значения "ВерсияДанных". Увидишь пустую строку в обоих объектах - сделай заключение "Вот опа... как быть?"(цы) - оно не пригодно для твоих целей.
|
|||
44
Либерал
25.08.16
✎
21:52
|
(38) +1, а проблем никаких и нет - ТС говорит, есть пара реквизитов служебных, которые программно меняются регламентами - их исключить из сравнения, и всё.. (0) - так?
|
|||
45
Лефмихалыч
25.08.16
✎
22:06
|
(0) блокируй объект перед открытием, чтобы ни кто не мог изменить
|
|||
46
toypaul
гуру
26.08.16
✎
07:49
|
(43) откуда пустое-то. ничо не пустое. все работает как надо.
|
|||
47
toypaul
гуру
26.08.16
✎
07:58
|
(42) с чего бы это?
тут проблема вылезла КопироватьДанныеФормы копирует целиком объект. включая версию данных. придется думаю как копировать без версии данных. |
|||
48
smartu
26.08.16
✎
07:59
|
нужно убрать изменяемые реквизиты за объект, например в регистры сведений ... объект должен менять пользователь лично и интерактивно.
Регламентное задание и тому подобные действия снимают ответственность за правильность данных в объекте. |
|||
49
toypaul
гуру
26.08.16
✎
08:01
|
(48) читаем всю ветку
|
|||
50
toypaul
гуру
26.08.16
✎
08:26
|
(42) все проверил. все работает. хоть сколько раз в обработке меняй объект. хоть записывай в форме, хоть не записывай.
|
|||
51
toypaul
гуру
26.08.16
✎
08:41
|
ошизеть. обнаружил глюк обработчика ожидания.
итак. 1. есть пустой обработчик ожидания, который вызывается все время 2. в форме редактируем поле, но никуда с него не уходим. то есть документ пока не отмечается модифицированным. 3. вызывается обработчик и текст, который был введен в поле заменяется старым значением (до изменения) 4. если текст изменить и успеть перейти на другое поле - все нормально. при этом документ становится модифицированным |
|||
52
toypaul
гуру
26.08.16
✎
08:42
|
(52) важное замечание - обработчик вызывает серверную процедуру (с контекстом)
|
|||
53
Cyberhawk
26.08.16
✎
10:31
|
(52) Размести серверную процедуру в общем модуле
|
|||
54
toypaul
гуру
26.08.16
✎
14:23
|
(53) точно будет работать? или просто попробовать? извращение какое-то. почему такой вариант будет работать?
|
|||
55
Cyberhawk
26.08.16
✎
14:24
|
(54) Потому что не будет дергаться форма при уходе на сервер
|
|||
56
Cyberhawk
26.08.16
✎
14:25
|
+(55) в СП почти у каждого обработчика формы в примечании написано "В обработчике данного события нельзя использовать серверные методы формы с директивой компиляции &НаСервере. "
|
|||
57
Cyberhawk
26.08.16
✎
14:25
|
Вместо общего модуля конечно покатит и модуль формы, но неконтекстный
|
|||
58
toypaul
гуру
26.08.16
✎
14:27
|
так мне надо чтобы форма дергалась. как иначе-то?
|
|||
59
Cyberhawk
26.08.16
✎
14:34
|
(58) Так у тебя там в (40) код, который может работать и на клиенте
|
|||
60
Cyberhawk
26.08.16
✎
14:35
|
+(59) на клиенте + на сервере без контекста формы
|
|||
61
toypaul
гуру
26.08.16
✎
14:43
|
так как форму не дергать, если главный объект формы меняется?
|
|||
62
toypaul
гуру
26.08.16
✎
14:44
|
хотя ... щяс уже лень в удаленку лезть. Прочитать и КопироватьДанныеФормы разве клиентские методы?
|
|||
63
toypaul
гуру
26.08.16
✎
14:44
|
если так, надо попробовать переделать на клиенте
|
|||
64
Cyberhawk
26.08.16
✎
15:16
|
(62) И клиентские, и серверные. Другое дело, что для изменения объекта формы может потребоваться серверный вызов, но это ты сам проверишь уже
|
|||
65
hitodom
26.08.16
✎
15:23
|
проще всего добавить кнопочку "Обновить". если пользователь не смог, то назимает ее и может
|
|||
66
Cyberhawk
26.08.16
✎
15:24
|
(65) Мы тут ищем вариант для самых "взыскательных" пользователей ))
|
|||
67
toypaul
гуру
31.08.16
✎
08:04
|
переделал обработчик полностью на клиенте. все методы или на клиенте или на сервере без контекста. работает.
|
|||
68
Cyberhawk
31.08.16
✎
09:58
|
Аминь!
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |