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

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

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

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