gifts2017

Как уменьшить количество заблокированных объектов

Опубликовал Александр Шевченко (ShEvOvIcH) в раздел Программирование - Практика программирования

История о том как я решил пересобрать форму справочника клиентов и чем это все закончилось...

После удачного упорядочения формы я решил добавить новые возможности или нечто подобное. Долго думать не пришлось, и идея родилась моментально.

Думаю многие из вас сталкивались с проблемой, когда элемент справочника заблокирован. В сети полно различных разработок, которые позволяют видеть, кто и когда заблокировал объект. Я решил пойти немного в другом направлении. В 90% случаев объект открывается только для того что бы уточнить какие то реквизиты. Но каждые такие открытия блокируют объект и как часто бывает человек заблокировавший объект не очень, то и торопится его освободить.

Что можно сделать ? Первая мысль была изменить пользователям параметр "Режим открытия объектов" с "Редактирование" на "Просмотр". Но тут, же появилась вторая мысль, а что делать, если нужно все-таки редактировать объект, а не смотреть на него. Не очень удобно.

Вот так и родилась моя идея. (Надеюсь, новый велосипед не изобрел :))

Суть состоит в том, что бы по умолчанию открывать объект на просмотр, а при необходимости нажать на соответствующую кнопку на форме для редактирования. При сохранении объекта сбрасывается режим редактирования, объект становится открытым только для чтения.

В итоге получилось: две переменки и три процедуры. Смотрим ниже. Алгоритм работает как для справочников, так и для документов.


Глобальный модуль:

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Перем гОбъект, гРежимОбъекта Экспорт;
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Процедура ОткрытьОбъект()

ОбъектОткрыто = 0;
ТипОбъекта = ТипЗначенияСтр(гОбъект);
Если ТипОбъекта = "Справочник" Тогда

ОбъектОткрыто = ОткрытьФорму(гОбъект.ТекущийЭлемент(),,гРежимОбъекта);

ИначеЕсли ТипОбъекта = "Документ" Тогда

ОбъектОткрыто = ОткрытьФорму(гОбъект.ТекущийДокумент(),,гРежимОбъекта);

КонецЕсли;

Если ОбъектОткрыто = 1 Тогда

гОбъект = 0;
ОбработкаОжидания("ОткрытьОбъект", 0);

КонецЕсли;

КонецПроцедуры
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Процедура РедактироватьОбъект(Кт) Экспорт

гОбъект = 0;
гРежимОбъекта = 0;
ТипОбъекта = "";
ВидОбъекта = Кт.Вид();

Попытка

Объект = Кт.ТекущийЭлемент();
ТипОбъекта = "Справочник";

Исключение

Объект = 0;

КонецПопытки;

Если Объект = 0 Тогда

Попытка

Объект = Кт.ТекущийДокумент();
ТипОбъекта = "Документ";

Исключение

Объект = 0;

КонецПопытки;

КонецЕсли;

Если Объект = 0 Тогда

Возврат;

КонецЕсли;

гОбъект = СоздатьОбъект(ТипОбъекта + "." + ВидОбъекта);
Если ТипОбъекта = "Справочник" Тогда

гОбъект.НайтиЭлемент(Объект);

ИначеЕсли ТипОбъекта = "Документ" Тогда

гОбъект.НайтиДокумент(Объект);

КонецЕсли;

Если гОбъект.Блокировка(1) = 0 Тогда

Предупреждение("Объект заблокирован другим пользователем.", 60);
Возврат;

Иначе

гОбъект.Блокировка(0);
Кт.Форма.Закрыть();

КонецЕсли;

ОбработкаОжидания("ОткрытьОбъект", 1);

КонецПроцедуры
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Процедура ПосмотретьОбъект(Кт) Экспорт

гОбъект = 0;
гРежимОбъекта = 1;
ТипОбъекта = "";
ВидОбъекта = Кт.Вид();

Попытка

Объект = Кт.ТекущийЭлемент();
ТипОбъекта = "Справочник";

Исключение

Объект = 0;

КонецПопытки;

Если Объект = 0 Тогда

Попытка

Объект = Кт.ТекущийДокумент();
ТипОбъекта = "Документ";

Исключение

Объект = 0;

КонецПопытки;

КонецЕсли;

Если Объект = 0 Тогда

Возврат;

КонецЕсли;

гОбъект = СоздатьОбъект(ТипОбъекта + "." + ВидОбъекта);
Если ТипОбъекта = "Справочник" Тогда

гОбъект.НайтиЭлемент(Объект);

ИначеЕсли ТипОбъекта = "Документ" Тогда

гОбъект.НайтиДокумент(Объект);

КонецЕсли;

Кт.Форма.Закрыть();

ОбработкаОжидания("ОткрытьОбъект", 1);

КонецПроцедуры
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


Модуль "Справочника\Документа":

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Процедура кРедактировать()

РедактироватьОбъект(Контекст);

КонецПроцедуры

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

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

ПосмотретьОбъект(Контекст);

КонецПроцедуры
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


Теперь для того что б это все заработало нужно:

1. Установить параметр "Режим открытия объектов" = "Просмотр" для всех пользователей;

2. На форму "справочника\документа" повесить "кнопку\перехватчик сочетания клавиш" и привязать к процедуре кРедактировать();

3. В процедуру при призаписи добавляем ссылку на ПосмотретьОбъект(Контекст);

4. Наличи внешней компоненты "1ссрр\formex". (У меня 1срр версия 2.0.3.7) (Больше не требуется)

Вот собственно и все. Надеюсь этот алгоритм приглянется кому то еще.

1. В ближайшем будущем планирую добавить режим сброса блокировки если в объекте, открытом на редактирование, нажата кнопка записать. (Записал - освободил) (Выполнил)

2. В ближайшем будущем планирую добавить режим сброса блокировки если в объекте нет активности в течении N-минут.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Епрст (Ёпрст) 13.01.12 11:16
Ну, ты забыл в описалове, что нужен формекс, это раз.
Обработку ожидания надо прерывать в Процедура ОткрытьОбъект(), это два.
2. Епрст (Ёпрст) 13.01.12 11:17
П и з д е ц !, чтобы оставить первый камент нужно нажать на подписаться на комментарии.
Какой му-2 это придумал ?!
3. Александр Шевченко (ShEvOvIcH) 13.01.12 12:31
(1) Ёпрст, обновил описание, перенес прерывание обработки ожидания.
Добавил снятие блокировки при записи элемента.
Ёпрст; +1 Ответить
4. Владимир (hogik) 13.01.12 19:35
(0)
"Надеюсь, новый велосипед не изобрел :))"(с)
Это первое, что сделал в "семерке" при первом с ней знакомстве в 2000 году. :-)
Без FormEx...
Рекомендую метод Блокировка() выполнять вот так:
Попытка Б=Объект.Блокировка(1); Исключение Б=0; КонецПопытки;
5. Александр Шевченко (ShEvOvIcH) 14.01.12 01:51
(4) hogik, убрал необходимость использования внешней компоненты. Если честно, то я не помню почему я сразу не воспользовался стандартной процедурой обработки ожидания...
6. Владимир (hogik) 14.01.12 02:34
(5)
Осталось воспользоваться вторым советом. ;-)
Не знаю как в SQL-ной версии, а в DBF-ной - поставить "попытка" надо обязательно.
7. Александр Шевченко (ShEvOvIcH) 14.01.12 11:48
(6) hogik, SQL - полет нормальный, ДБФ - полет нормальный. Я специально после вашего комментария создал пустую конфигурацию и вставил свой код, все работает. Вы случайно ничего не меняли. А что пишет в исключении ?
8. Владимир (hogik) 14.01.12 21:37
(7)
"Вы случайно ничего не меняли"(с)
Естественно, ничего не менял, т.к. у меня другой алгоритм. ;-)
Про метод Блокировка() - это общее замечание.
У меня сейчас не получилось написать (представить) алгоритм, где он заваливается.
Т.к. занимался этим в 2000 году. Уже все забыл... :-(
Заваливался он аналогично, например, методу Записать() если в другой сессии 1С-а выполнялось обращение к объекту в транзакции. Но, это было в 18 версии (или более ранней). Сейчас пробую в 25-ой - не получается завалить.
Вот, пробую на таком тексте:

Процедура Выполнить()
Спр=СоздатьОбъект("Справочник.Номенклатура");
Если Парам=0 Тогда
Спр.ПорядокКодов();
Спр.ВыбратьЭлементы();
Спр.ПолучитьЭлемент();
Сообщить(Спр.Блокировка(1));
Иначе
НачатьТранзакцию();
Спр.ПорядокКодов();
Спр.ВыбратьЭлементы();
Спр.ПолучитьЭлемент();
Спр.Записать();
Предупреждение("Пауза...");
ОтменитьТранзакцию();
КонецЕсли;
КонецПроцедуры

Запускаю с Парам=1 до выхода на сообщение "Пауза...", и потом запускаю с Парам=0 в другой сессии 1С-а. Метод Блокировка() возвращает единицу. А раньше заваливался. И это, думаю, было лучше чем возвращать признак успешного завершения. Т.е. хоть, через "Попытка" можно было выяснить, что объект заблокирован. Иначе говоря, если в старой версии была ошибка - метод заваливался. И разработчики исправили ошибку так, что он теперь не заваливается, а возвращает единицу, то они полные ко...ы. Или я - такой. ;-) Уже ничего не понимаю и не соображаю. :-(
P.S.
В моих разработках (в подобных алгоритмах) возвращается значение НОЛЬ.
http://infostart.ru/public/15211/
http://infostart.ru/public/14664/
9. Дима Димыч (kazna2011) 22.01.12 15:34
Процедура Выполнить()
Спр=СоздатьОбъект("Справочник.Номенклатура");
Если Парам=0 Тогда
Спр.ПорядокКодов();
Спр.ВыбратьЭлементы();
Спр.ПолучитьЭлемент();
Сообщить(Спр.Блокировка(1));
Иначе
НачатьТранзакцию();
Спр.ПорядокКодов();
Спр.ВыбратьЭлементы();
Спр.ПолучитьЭлемент();
Спр.Записать();
Предупреждение("Пауза...");
ОтменитьТранзакцию();
КонецЕсли;
КонецПроцедуры


Не понял, куда этот код прописать?
10. Александр Шевченко (ShEvOvIcH) 22.01.12 16:03
Не понял, куда этот код прописать?
Смотря для чего вам этот код нужен. Автор, кода который вы процитировали, хотел показать что в старых версиях 1С метод Блокировка(1) вызывал исключение.
11. Саня Пупкин (pupkinSana) 24.01.12 14:58
Можно, как вариант, такое предложить: давать редактировать только распроведенные документы.

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

Если сильно нужно исправить - распроведите, и редактируйте.
12. Денис Клюшин (denklu) 02.02.12 11:11
спасибо за идею, а я еще активно стареньким 1срр (1С++) пользуюсь
13. Гость 07.02.12 20:41
Спасибо,очень нужная вещь иногда бывает))
14. Ruslan (flash82) 24.02.12 14:18
спасибо иногда нужная вещь...
15. Алексей (Rockman) 14.03.12 16:29
16. cергей г (sergur66) 26.03.12 13:16
Спасибо!!! Идея полезная.
17. Максим (maxim305) 13.11.13 06:59
Спасибо, интересная идея!
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа