Кто заблокировал объект ? 7.7 (SQL/DBF)
Обработка блокировки объекта в базе для SQL/DBF варианта.
- Описание
- Подробнее
Описание
При многопользовательском режиме, пользователи часто видят перед собой картинку

При этом, выяснить, какой же пользователь держит объект открытым, довольно проблематично. Приходится открывать журнал регистрации, долго и нудно искать нужный объект и по событиям журнала пытаться определить, кто же все же открыл данный объект.
Данная метода позволяет автоматом получить имя пользователя в окошке сообщений:

Для её реализации требуется загрузка внешних компонент:
для DBF версии еще и
Идея очень простая — при начале работы системы проверяется наличие таблички в базе (в SQL — табличка на сервере SQL, для DBF — база sqlite и таблички в ней), в предопределенных событиях формекса пишется имя пользователя и ид-объекта в табличку блокировок, при обработке блокировки — показывается этот пользователь.
Метода не новая, просто мало кто выкладывал готовых решений.
Для реализации, нижеследующий код нужно поместить в глобальный модуль.
Успехов.
ЗЫ: для любителей «универсальности», предлагаю объединить оба метода в один самостоятельно.
ЗЫЫ: в монопольном режиме, база блокировок не нужна, как и их обработка в нижеописаных процедурах. Для этого
в ПриНачалеРаботыСистемы нужна всего лишь проверка на
Если МонопольныйРежим()=0 Тогда
//тут создать объекты запроса/базы /табличек и прочий мусор
База = ;
Запрос = ;
ТекстГм = » сюда пишем текст процедур ПриНачалеБлокировкиОбъекта и ОбработкаБлокирокиОбъекта»;
гСервис= СоздатьОбъект(«Сервис»);
гСервис.ДобавитьГлобальныйМодуль(ТекстГМ);
КонецЕсли;
ЗЫЫЫ: принимаю пожертвования в качесте благодарности на
яндекс деньги 41001277400750
wmr R285258832971
Версия для DBF-варианта:
Перем запросSQLLite;
Перем глМД;
//======================================================================
Процедура ПриНачалеБлокировкиОбъекта(Объект)
Тип = ТипЗначенияСтр(Объект);
Если (Тип = «Документ»)или(Тип=«Справочник») Тогда
ИДОбъекта = глМД.ЗначениеВДлиннуюСтрокуБД(Объект);
ТекстЗапроса = «
| INSERT or REPLACE INTO БазаБлокировок
| VALUES (‘»+ИДОбъекта+«‘,'»+ПолноеИмяПользователя()+«‘)
|— для типовой торговли можно пользовать глПользователь:
|— VALUES (‘»+ИДОбъекта+«‘,'»+глПользователь.Наименование+«‘)
|»;
фл = 0;
Пока фл=0 Цикл
Попытка
запросSQLLite.ВыполнитьЗапрос(ТекстЗапроса);
фл=1;
Исключение
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
//======================================================================
Процедура ОбработкаБлокировкиОбъекта(Объект, Повторить, ДопТекст)
Тип = ТипЗначенияСтр(Объект);
Если (Тип = «Документ»)или(Тип=«Справочник»)Тогда
ИДОбъекта = глМД.ЗначениеВДлиннуюСтрокуБД(Объект);
фл=0;
Пока фл=0 Цикл
Попытка
ИмяВредителя = запросSQLLite.ВыполнитьЗапрос(«Select База.Пользователь From БазаБлокировок База Where База.ИДОбъекта = ‘»+ИДОбъекта+«‘»,0);
фл=1;
Исключение
КонецПопытки;
КонецЦикла;
Сообщить(«» + Объект + » открыт пользователем » + ИмяВредителя,«!»);
//для красоты, можно писать так, заместо Сообщить:
ДопТекст =«» + Объект + » открыт пользователем » + ИмяВредителя;
КонецЕсли;
КонецПроцедуры
//======================================================================
Процедура ПриНачалеРаботыСистемы()
ЗагрузитьВнешнююКомпоненту(«1cpp.dll»);
ЗагрузитьВнешнююКомпоненту(«formex.dll»);
ЗагрузитьВнешнююКомпоненту(«1sqlite.dll»);
база = СоздатьОбъект(«SQLiteBase»);
Если ФС.СуществуетФайл(КаталогИБ()+«ExtForms\»)=0 Тогда
ФС.СоздатьКаталог(КаталогИБ()+«ExtForms\»);
КонецЕсли;
Если ФС.СуществуетФайл(КаталогИБ()+«ExtForms\DB_SQLite\»)=0 Тогда
ФС.СоздатьКаталог(КаталогИБ()+«ExtForms\DB_SQLite\»);
КонецЕсли;
ИмяБД = КаталогИБ()+«ExtForms\DB_SQLite\baza.db3»;
глМД = СоздатьОбъект(«MetaDataWork»);
база.Открыть(ИмяБД);
запросSQLLite = база.НовыйЗапрос();
//запросSQLLite.ВыполнитьЗапрос(«PRAGMA journal_mode=WAL»); //это прописать, ежели база в терминале
запросSQLLite.ВыполнитьЗапрос(«PRAGMA journal_mode=OFF»);
ТекстЗапроса =«
|Create table if not EXISTS
|БазаБлокировок (
| ИДОбъекта varchar(13) primary key not null,
| Пользователь TEXT
|)»;
фл = 0;
Пока фл=0 Цикл
Попытка
запросSQLLite.ВыполнитьЗапрос(ТекстЗапроса);
фл=1;
Исключение
КонецПопытки;
КонецЦикла;
Если МонопольныйРежим()=1 Тогда
запросSQLLite.ВыполнитьЗапрос(«delete from БазаБлокировок»);
КонецЕсли;
КонецПроцедуры
Версия для SQL-варианта:
// Глобальные переменные необходимые работы
Перем запросSQL;
Перем глМД;
//======================================================================
Процедура ПриНачалеБлокировкиОбъекта(Объект)
Тип = ТипЗначенияСтр(Объект);
Если (Тип = "Документ")или(Тип="Справочник") Тогда
ИДОбъекта = глМД.ЗначениеВДлиннуюСтрокуБД(Объект);
// для типовой торговли можно пользовать Юзверь = глПользователь.Наименование:
Юзверь = ПолноеИмяПользователя();
ТекстЗапроса = "
|IF Exists (SELECT * FROM Blocks WHERE ИДОбъекта = '"+ИДОбъекта+"')
| BEGIN
| UPDATE Blocks
| SET
| ИДОбъекта = '"+ИДОбъекта+"', Пользователь = '"+Юзверь+"'
| WHERE ИДОбъекта = '"+ИДОбъекта+"'
| END
|ELSE
| BEGIN
| INSERT INTO Blocks (ИДОбъекта, Пользователь)
| VALUES ('"+ИДОбъекта+"','"+Юзверь+"')
| END
|";
запросSQL.ВыполнитьСкалярный(ТекстЗапроса);
КонецЕсли;
КонецПроцедуры
//======================================================================
Процедура ОбработкаБлокировкиОбъекта(Объект, Повторить, ДопТекст)
Тип = ТипЗначенияСтр(Объект);
Если (Тип = "Документ")или(Тип="Справочник")Тогда
ИДОбъекта = глМД.ЗначениеВДлиннуюСтрокуБД(Объект);
ИмяВредителя = запросSQL.ВыполнитьСкалярный("Select Пользователь From Blocks (nolock) Where ИДОбъекта = '"+ИДОбъекта+"'");
Сообщить("Объект:" + Объект + " открыт пользователем " + ИмяВредителя,"!");//сообщать не обязательно, если что
Повторить =1;
ДопТекст = "Объект:" + Объект + " открыт пользователем " + ИмяВредителя;
КонецЕсли;
КонецПроцедуры
//======================================================================
Процедура ПриНачалеРаботыСистемы()
ЗагрузитьВнешнююКомпоненту("1cpp.dll");
ЗагрузитьВнешнююКомпоненту("formex.dll");
глМД = СоздатьОбъект("MetaDataWork");
запросSQL = СоздатьОбъект("ODBCRecordSet");
ТекстЗапроса ="
|if object_id('dbo.Blocks','U') is null
| create table dbo.Blocks
| (ИДОбъекта varchar(13) primary key not null,
| Пользователь TEXT)
|;";
запросSQL.ВыполнитьСкалярный(ТекстЗапроса);
Если МонопольныйРежим()=1 Тогда
запросSQL.ВыполнитьСкалярный("delete from dbo.Blocks");
КонецЕсли;
КонецПроцедуры

