Блокировка документа

Внимание! Тема закрыта. Добавлять сообщения в закрытую тему запрещено.
1. whtblck 96 16.03.14 20:52 Сейчас в теме
Конфигурация 77.
Документ редактируется интерактивно (т.е. открываем форму и редактируем), либо же, для определенного набора прав, сделана обработка для редактирования документа.
Задача:
Нужно запретить одновременно редактировать один и тот же документ интерактивно (через форму документа) и через обработку.
Пытался:
в процедуре ПриОткрытии() документа делаю
ТекущийДокумент().Блокировка(1);
При попытке редактировать из обработки сначала проверяю, заблокирован ли такой документ:

Если РежимБлокировки = 1 Тогда
	Предупреждение("Документ заблокирован другим пользователем.
			|Изменение невозможно.
			|Попробуйте внести изменения позже", 30);
	Возврат;
КонецЕсли;

Здесь РежимБлокировки - проверяет, заблокирован ли текущий документ, примерно так:
ВремДок = СоздатьОбъект("Документ.Заказ");
ВремДок.НайтиДокумент(ДокЗаказ);
РежимБлокировки = ВремДок.Блокировка();

Не смотря на то, что принудительно было установлено в 1, здесь возвращает 0.
Почему, и как вообще работает Блокировка()?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
4. hogik 443 18.03.14 15:54 Сейчас в теме
(1)
Александр(whtblck).

Мой ответ на пропавшее сообщения:
Я считаю решение из (16) сообщения плохим, т.к.:
1) Не обеспечивает блокировки множества документов.
2) Требует ручного вмешательства, если аварийно завершается "блокирующая" сессия.
3) Не обеспечивает достоверности обновления файла "блокировок".

Решение для "новой" постановки задачи:
Если речь идет о работе в части редактирования, то нет самой задачи/проблемы.
Т.к. система блокирует документ открытый на редактирование и не даёт другой сессии открыть этот документ в режиме редактирования.
А если требуется запретить открытие и в режиме чтения (если в другой сессии редактируют документ), то надо:
Процедура ПриОткрытии() 
	Если Форма.ТолькоПросмотр()=1 Тогда  
		Док=СоздатьОбъект("Документ."+Вид());
		Если Док.НайтиДокумент(ТекущийДокумент())=1 Тогда
			Если Док.Блокировка(1)=0 Тогда 
				Сообщить("Нет доступа!","!");
				СтатусВозврата(0);
				Возврат;
			Иначе
				Док.Блокировка(0);
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры
Показать
2. _Z1 38 18.03.14 12:57 Сейчас в теме
куда то все вчерашние ответы пропали
3. whtblck 96 18.03.14 13:24 Сейчас в теме
(2) во блин :(
а так отписывал всем:(
6. whtblck 96 18.03.14 16:41 Сейчас в теме
(2)
Жаль, что пропало все ранее написанное.
Объясню.
1) Не обеспечивает блокировки множества документов.

Согласен. Но это совсем не сложно доработать - еще несколько строчек в той же глобальной процедуре. И это я уже сделал
2) Требует ручного вмешательства, если аварийно завершается "блокирующая" сессия.

Согласен. В моем случае - это приемлемо. К тому же, при аварийном завершении требуются и другие операции.
3) Не обеспечивает достоверности обновления файла "блокировок".

Тут что-то заумное, я не въехал.

Если речь идет о работе в части редактирования, то нет самой задачи/проблемы.
Т.к. система блокирует документ открытый на редактирование и не даёт другой сессии открыть этот документ в режиме редактирования.
А если требуется запретить открытие и в режиме чтения (если в другой сессии редактируют документ), то надо:

Я неоднократно в пропавших сообщениях говорил, что документ может редактироваться через форму, и, одновременно, через обработку. В обработке форма документа не открывается, я получаю нужный мне документ (Док = создатьОбъект("Документ.МойДокумент")) и делаю с ним, что хочу (Док.Автор = глПользователь; и т.д.). А уже потом, при попытке записать, узнаю, что с ним, оказывается , кто-то работал через форму и записать я его не могу.
При работе с документом через обработку система его никак не блокирует.

(5) была бы sql-ная база, возможно, так и сделал бы.

А вообще:
в сабже была просьба
Почему, и как вообще работает Блокировка()?

Т.е. я хотел узнать, как работает Блокировка(), что и когда она блокирует. И именно этого мне никто не разъяснил
7. hogik 443 18.03.14 17:04 Сейчас в теме
(6)
Придётся повторять потерянные свои сообщения темы.
"Тут что-то заумное, я не въехал."(с)
Что мешает двум сессиям открыть или получить/записать информацию "одновременно"?
Ну, или свалится аварийно, если 1С открывает/записывает этот файл эксклюзивно?
"редактироваться через форму, и, одновременно, через обработку"(с)
В обработке у Вас не вызывается форма документа. Вы используете операторы встроенного языка для нахождения документа, чтения из него реквизитов, размещение их в некой диалоговой форме. Потом из этой формы переносите реквизиты в объект "Документ" и выполняете обновление в базе данных. Так?
Тогда это делается выдачей Блокировка(1) в самом начале Вашей обработки. И при успешном выполнении выдаётся Ваш специфический диалог. После обновления информации в базе данных вызывается Блокировка(0). Всё... :-)
Еще рекомендую охватить "блоком Попытка" все методы обновления базы данных с соответствующей обработкой наступления сбойного события. Да, и метод Блокировать(1) полезно охватить "Попыткой". :-)

"Т.е. я хотел узнать, как работает Блокировка(), что и когда она блокирует. И именно этого мне никто не разъяснил "(с)
А код из (4) сообщения и предыдущий абзац понятен? Спрашиваю, чтобы понять ЧЕГО Вы не понимаете и писать именно об этом.
8. whtblck 96 18.03.14 17:34 Сейчас в теме
(6)
В обработке у Вас не вызывается форма документа. Вы используете операторы встроенного языка для нахождения документа, чтения из него реквизитов, размещение их в некой диалоговой форме. Потом из этой формы переносите реквизиты в объект "Документ" и выполняете обновление в базе данных. Так?
Тогда это делается выдачей Блокировка(1) в самом начале Вашей обработки. И при успешном выполнении выдаётся Ваш специфический диалог. После обновления информации в базе данных вызывается Блокировка(0). Всё... :-)
Еще рекомендую охватить "блоком Попытка" все методы обновления базы данных с соответствующей обработкой наступления сбойного события. Да, и метод Блокировать(1) полезно охватить "Попыткой". :-)

Это все я сделал еще до того, как обратился на форум.
Если бы оно отрабатывало, я бы всего этого не писал.
Об этом я так же упоминал в "пропавших" сообщениях, если мой склероз мне не изменяет.
9. hogik 443 18.03.14 17:48 Сейчас в теме
(8)
Александр (whtblck).
Вы написали другое. И я пытался вытянуть из Вас - ЧТО на самом деле вы делаете в обработке. Вытянул. :-) Осталось, только, "вытянуть из Вас" сам текст обработки, который не работает так как нужно. Т.к. в моей конфигурации ВСЁ построено на "ручных блокировках" подобных Вашей задачи. И всё отлично работает...
P.S.
Для интереса - прочтите, пожалуйста, "общую часть" этой публикации:
http://infostart.ru/public/87339/
11. whtblck 96 18.03.14 19:07 Сейчас в теме
(9)
статью обязательно прочту. Сегодня же, вечером.
Сейчас сильно некогда :(
Похоже, Вы не "понимаете" разницу между использованием метода:
Блокировка(1)
Блокировка()
Да?

Возможно, посему и обращался сюда.
Сейчас в конфигурации все переделано и кода дать не могу. напишу, как делал.
Итак.
Форма документа.
В процедуре ПриОткрытии() я проверял, заблокирован ли кем-то документ. Если нет - блокирую и продолжаю открывать. Примерно так:
ПриОткрытии()
Если ТекущийДокумент().Блокировка() = 1 Тогда
Предупреждение("Документ заблокирован", 60);
СтатусВозврата(0);
Возврат;
Иначе
ТекущийДокумент().Блокировка(1);
КонецЕсли
...
КонецПроцедуры;

...
// при закрытии делаю
ПриЗакрытии()

....
Текущийдокумент().Блокировка(0);

Показать


В обработке я сначала получаю нужный мне документ, его реквизитами заполняю нужные реквизиты на форме обработки. При необходимости редактирую и потом записываю.
Получаю документ. Проверяю его блокировку

Док = создатьОбъект("Документ.МойВидДокумента");
// получаю нужный мне документ и проверяю
Если Док.Блокировка() = 1 Тогда
// не даю с нним работать
иначе
Док.Блокировка(1);
КонецЕсли;


далее работаю с документом и после окончания с ним работы:

Док.Блокировка(0);


Проверяю так:
открываю форму документа одним юзверем
и тут де открываю его в обработке другим юзверем.

О том, что он заблокирован сообщения не получаю ни при таком способе, ни наоборот - открыв сначала обработкой, потом форму
12. hogik 443 18.03.14 19:23 Сейчас в теме
(11)
Александр (whtblck).
Вам надо сделать только ЭТО и только ТУТ:
Док = создатьОбъект("Документ.МойВидДокумента");
// получаю нужный мне документ
Если Док.Блокировка(1) = 0 Тогда
// НЕ даю с ним работать
иначе
// Даю с ним работать
КонецЕсли;
Док.Блокировка(0);

И желательно учесть мою рекомендацию про "блок Попытка".
Например, для блокировки использовать примерно такой код:
Попытка
   Ф=Док.Блокировка(1);
Исключение
   Ф=0;
КонецПопытки;
Если Ф=0 Тогда
// НЕ даю с ним работать
....

Аналогично использовать "попытку" для ВСЕХ методов обновления базы данных. Но, естественно, с другим алгоритмом "исключения".
13. whtblck 96 19.03.14 00:53 Сейчас в теме
(12)
Вам надо сделать только ЭТО и только ТУТ:

Сделал, только в обработке.
В форме документа (если я правильно понял значение "только ТУТ") ничего не делал.
получается:
1. Открыл форму документа. Пока она открыта в обработке этот документ открыть не могу. Т.е. то, что мне и нужно
2. Открыл документ в обработке. И пока он открыт в обработке, могу открыть, изменить, записать, провести и закрыть документ интерактивно, через форму документа. Данные в обработке после этого, конечно же, будут "устаревшими". И второй пользователь, открывший документ обработкой, изменит документ снова. Вот это меня не устраивает
14. hogik 443 19.03.14 02:00 Сейчас в теме
(13)
"Открыл документ в обработке. И пока он открыт в обработке, могу открыть, изменить, записать, провести и закрыть документ интерактивно, через форму документа."(с)
Враки !!! :-)
Я поэтому и прошу ВЕСЬ текст обработки с ЛЮБЫМ вариантом "блокировки". Вы выдали Блокировка(0) раньше чем это надо. Пожалуйста, внимательнее читайте мои сообщения: "После обновления информации в базе данных вызывается Блокировка(0)."(с)
16. whtblck 96 19.03.14 11:06 Сейчас в теме
(14)
я писал в (11)
В обработке я сначала получаю нужный мне документ, его реквизитами заполняю нужные реквизиты на форме обработки. При необходимости редактирую и потом записываю.

т.е. в обработке саму форму документа я не открываю.
все, что нужно сделать с реквизитами документа делается реквизитами на форме обработки (табличная часть выгружается в таблицу значений, реквизиты шапки, доступные для редактирования пользователю так же присваиваются реквизитам на форме обработки). При необходимости внести изменения в документ значения реквизитов из формы обработки присваиваются соответствующим реквизитам в документе. Объект-документ записывается.
Все.
17. hogik 443 19.03.14 18:24 Сейчас в теме
(16)
"я писал в ..."(с)
Александр (whtblck).
Вы писали много разного в этой теме. :-) А т.к. в 1С-а два способа работы с информацией, то и рекомендации для них разные. Я в теме выдал Вам рекомендации по обоим способам. Но, самое "сложное" это совмещение обоих способов в одном алгоритме/коде. И Ваши тексты постоянного на это намекают... И получается две темы: суть/проблема блокировки и сам Ваш алгоритм (пусть и без блокировки - однопользовательский). Моё (14) сообщение - по первой "теме", а сообщение (15) - по второй. Но, вы отвечаете "перекрестно"... :-(
И, к делу. ;-)
Работает алгоритм из (12) сообщения?
У меня работает !!!
18. whtblck 96 19.03.14 18:57 Сейчас в теме
(17)
Владимир, мне симпатизирует Ваше бескорыстное желание мне помочь, но я уже не знаю, как еще объяснить. Или что именно непонятно я рассказываю.

Еще раз.
Документ можно изменить 2-мя способами:
1. Стандартной формой документа: открываю форму документа и меняю.
2. Обработкой. Создаю объект "документ". Нахожу нужный мне документ. НЕ открывая его формы получаю доступные для изменения пользователю реквизиты. Присваиваю эти значения реквизитам на форме обработки, не форме документа. Меняю их. Присваиваю эти значения реквизитам полученного объекта-документа. Записываю документ. Все. Форму документа в этом случае не открывал.

Мне нужно запретить одновременную работу двум (или более) пользователям с одним и тем же документом. А мы знаем, что документ можно изменять через его форму и, в это же время, через обработку.

Алгоритм из (12) работает так, как написано в (13).
На (14) отвечу - из обработки вообще убрал Блокировка(0), не важно менял или нет документ.
Результат рассказывать?
весь текст обработки - 5 тыщ строк, оно Вам нужно?
19. hogik 443 19.03.14 19:22 Сейчас в теме
(18)
"Или что именно непонятно я рассказываю."(с)
Александр (whtblck).
Я от Вас балдею. :-) Алгоритм из (12) работает так как Вам нужно!
И если он не работает, то Вы в своих "5 тыщ строк"(с) делаете ещё нечто, что его нарушает.
Надо либо смотреть эти строки моими или Вашими глазами, либо Вам написать тест этого алгоритма на простой обработке. И убедиться в его работоспособности.
20. hogik 443 19.03.14 19:44 Сейчас в теме
(18)
Александр (whtblck).
Скачайте конфигурацию. Изучайте, пробуйте...
Документ и обработка под названием "Тест".
Прикрепленные файлы:
1Cv7.zip
21. _Z1 38 19.03.14 20:34 Сейчас в теме
(18) Зачем такие сложности.
Пусть при вызове обработки открывается документ в спецрежиме
и в этом спецрежиме отображается только табличная часть. Все.

два сложных способа работы с одной сущностью ( документом ) очень трубно реализуемы.
23. hogik 443 19.03.14 21:51 Сейчас в теме
(21)
"Зачем такие сложности."(с)
Для изучения инструмента блокировки в 1С-е. :-)
22. hogik 443 19.03.14 21:50 Сейчас в теме
(18)
Александр (whtblck).
Осмелюсь предположить ошибку в Ваших "5 тыщ строк"(с) не изучая их. :-)
Вы выдаёте Блокировать(1) относительно некого объекта (в смысле - СоздатьОбъект) в процедуре/функции. А реальную работу с документом производите относительно другого объекта вне этой процедуре/функции. Так?
15. hogik 443 19.03.14 02:06 Сейчас в теме
(13)
И, еще. Давайте использовать термины/понятия одинаково во всех сообщениях.
Ну, фраза "Открыл документ в обработке"(с) подразумевает использование ОткрытьФорму(). Я ВСЮ тему добиваюсь от Вас точного описания постановки задачи. И в каждом своём сообщении Вы опровергаете предыдущее. Сколько можно, же....
28. whtblck 96 20.03.14 01:49 Сейчас в теме
Владимир (hogik).
"Признаю свою вину.
Меру, степень, глубину..." (с)Л.Филатов
Я действительно в обработке блокировал другой объект. Создавал, находил, присваивал... перемудрил короче.
Теперь все работает, кал и было Вами описано в (12).
Еще раз спасибо за терпение и выдержку.
Думаю, тему можно закрывать?
10. hogik 443 18.03.14 18:04 Сейчас в теме
(8)
"Это все я сделал еще до того, как обратился на форум."(с)
Александр (whtblck).
Опять. :-) Вроде начинаю понимать...
Вы НЕ делали того, что я написал про метод "Блокировка" выше по теме.
Похоже, Вы не "понимаете" разницу между использованием метода:
Блокировка(1)
Блокировка()
Да?
5. _Z1 38 18.03.14 16:16 Сейчас в теме
(0) надо делать с помощью sql таблицы.

Сделать блокировку через файл очень сложно - практически невозможно ( если делать хорошо и учитывать что пользователей больше 20 )
24. _Z1 38 19.03.14 22:08 Сейчас в теме
Даже не знаю кому адресовать этот пост.
тогда надо изучить объект *FILE языка С.
как бы в этом объекте внешне ничего вообще не изменилось от момента первого unix.
Есть два вызова WIN API блокировать разблокировать участок файла. Как бы все.
Причем разблокировать может только процесс наложивший блокировку.
25. hogik 443 19.03.14 22:22 Сейчас в теме
(24)
В сУБД всё чуть-чуть сложней. :-)
Ну, хоть на это посмотрите: http://infostart.ru/public/15577/
А в СУБД ещё мудрее всё сделано...
26. _Z1 38 19.03.14 23:01 Сейчас в теме
(25) Да вроде если говорить о стандартной 1с блокировке документа и о Блокировка()
то они написаны как раз на LockFile() и UnlockFile()

(25) а можно вопрос может и off в этой ветке
Иногда в терминале падает сессия и при этом остается висеть блокировка на документе.
(пока всех не выгонишь и не расшаришь и снова не зашаришь папку документ блокирован ).
Если какое решение этого вопроса ? Заранее спасибо за ответ.может есть какое либо решение.
27. hogik 443 19.03.14 23:53 Сейчас в теме
(26)
Андрей (_Z1).
Я так понимаю, что речь идет об MS SQL версии 1С-а? Я не работаю с этой СУБД в контексте "1С 7.7". Но, если мне не изменяет память, то для SQL-ной "семерки" используется "внешняя блокировка" для блокировки на уровне записей. Т.е. обычный файл (или файлы) в каталоге рядом с MD файлом. И блокируется некоторый байт этого файла сопоставленный с ID объекта. В этом направлении и надо копать, если есть уверенность в аварийном завершении самой сессии 1С-а. А как копать - ХЗ... ;-) Но, по идеи, при аварийном завершении процесса должны закрываться все его HANDLE вместе с блокировками через некоторый интервал времени.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот