Как поступить если объект на форме изменен "извне" программно? #779358


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

В этой группе 1С