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

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

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

Думаю многие из вас сталкивались с проблемой, когда элемент справочника заблокирован. В сети полно различных разработок, которые позволяют видеть, кто и когда заблокировал объект. Я решил пойти немного в другом направлении. В 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-минут.

17 Comments

  1. Ёпрст

    Ну, ты забыл в описалове, что нужен формекс, это раз.

    Обработку ожидания надо прерывать в Процедура ОткрытьОбъект(), это два.

    Reply
  2. Ёпрст

    П и з д е ц !, чтобы оставить первый камент нужно нажать на подписаться на комментарии.

    Какой му-2 это придумал ?!

    Reply
  3. ShEvOvIcH

    (1) Ёпрст, обновил описание, перенес прерывание обработки ожидания.

    Добавил снятие блокировки при записи элемента.

    Reply
  4. hogik

    (0)

    «Надеюсь, новый велосипед не изобрел :))»(с)

    Это первое, что сделал в «семерке» при первом с ней знакомстве в 2000 году. 🙂

    Без FormEx…

    Рекомендую метод Блокировка() выполнять вот так:

    Попытка Б=Объект.Блокировка(1); Исключение Б=0; КонецПопытки;

    Reply
  5. ShEvOvIcH

    (4) hogik, убрал необходимость использования внешней компоненты. Если честно, то я не помню почему я сразу не воспользовался стандартной процедурой обработки ожидания…

    Reply
  6. hogik

    (5)

    Осталось воспользоваться вторым советом. 😉

    Не знаю как в SQL-ной версии, а в DBF-ной — поставить «попытка» надо обязательно.

    Reply
  7. ShEvOvIcH

    (6) hogik, SQL — полет нормальный, ДБФ — полет нормальный. Я специально после вашего комментария создал пустую конфигурацию и вставил свой код, все работает. Вы случайно ничего не меняли. А что пишет в исключении ?

    Reply
  8. hogik

    (7)

    «Вы случайно ничего не меняли»(с)

    Естественно, ничего не менял, т.к. у меня другой алгоритм. 😉

    Про метод Блокировка() — это общее замечание.

    У меня сейчас не получилось написать (представить) алгоритм, где он заваливается.

    Т.к. занимался этим в 2000 году. Уже все забыл… 🙁

    Заваливался он аналогично, например, методу Записать() если в другой сессии 1С-а выполнялось обращение к объекту в транзакции. Но, это было в 18 версии (или более ранней). Сейчас пробую в 25-ой — не получается завалить.

    Вот, пробую на таком тексте:

    Процедура Выполнить()

    Спр=СоздатьОбъект(«Справочник.Номенклатура»);

    Если Парам=0 Тогда

    Спр.ПорядокКодов();

    Спр.ВыбратьЭлементы();

    Спр.ПолучитьЭлемент();

    Сообщить(Спр.Блокировка(1));

    Иначе

    НачатьТранзакцию();

    Спр.ПорядокКодов();

    Спр.ВыбратьЭлементы();

    Спр.ПолучитьЭлемент();

    Спр.Записать();

    Предупреждение(«Пауза…»);

    ОтменитьТранзакцию();

    КонецЕсли;

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

    Запускаю с Парам=1 до выхода на сообщение «Пауза…», и потом запускаю с Парам=0 в другой сессии 1С-а. Метод Блокировка() возвращает единицу. А раньше заваливался. И это, думаю, было лучше чем возвращать признак успешного завершения. Т.е. хоть, через «Попытка» можно было выяснить, что объект заблокирован. Иначе говоря, если в старой версии была ошибка — метод заваливался. И разработчики исправили ошибку так, что он теперь не заваливается, а возвращает единицу, то они полные ко…ы. Или я — такой. 😉 Уже ничего не понимаю и не соображаю. 🙁

    P.S.

    В моих разработках (в подобных алгоритмах) возвращается значение НОЛЬ.

    http://infostart.ru/public/15211/

    http://infostart.ru/public/14664/

    Reply
  9. kazna2011
    Процедура Выполнить()

    Спр=СоздатьОбъект(«Справочник.Номенклатура»);

    Если Парам=0 Тогда

    Спр.ПорядокКодов();

    Спр.ВыбратьЭлементы();

    Спр.ПолучитьЭлемент();

    Сообщить(Спр.Блокировка(1));

    Иначе

    НачатьТранзакцию();

    Спр.ПорядокКодов();

    Спр.ВыбратьЭлементы();

    Спр.ПолучитьЭлемент();

    Спр.Записать();

    Предупреждение(«Пауза…»);

    ОтменитьТранзакцию();

    КонецЕсли;

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

    Показать

    Не понял, куда этот код прописать?

    Reply
  10. ShEvOvIcH
    Не понял, куда этот код прописать?

    Смотря для чего вам этот код нужен. Автор, кода который вы процитировали, хотел показать что в старых версиях 1С метод Блокировка(1) вызывал исключение.

    Reply
  11. pupkinSana

    Можно, как вариант, такое предложить: давать редактировать только распроведенные документы.

    Тогда можно без изменения прав, а лишь нужным документам в модуль добавить для открытия без блокировки:

    Процедура ПриОткрытии()

    Если Проведен()=1 тогда

    Если глПерем=»123″ Тогда

    глПерем=»»;

    Иначе

    глПерем=»123″;

    СтатусВозврата(0);

    ОткрытьФорму(ТекущийДокумент(),»»,1);

    КонецЕсли;

    КонецЕсли;

    ….

    Если сильно нужно исправить — распроведите, и редактируйте.

    Reply
  12. denklu

    спасибо за идею, а я еще активно стареньким 1срр (1С++) пользуюсь

    Reply
  13. Гость

    Спасибо,очень нужная вещь иногда бывает))

    Reply
  14. flash82

    спасибо иногда нужная вещь…

    Reply
  15. Rockman

    Спасибо нужная вещь.

    Reply
  16. sergur66

    Спасибо!!! Идея полезная.

    Reply
  17. maxim305

    Спасибо, интересная идея!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *