При многопользовательском режиме, пользователи часто видят перед собой картинку
При этом, выяснить, какой же пользователь держит объект открытым, довольно проблематично. Приходится открывать журнал регистрации, долго и нудно искать нужный объект и по событиям журнала пытаться определить, кто же все же открыл данный объект.
Данная метода позволяет автоматом получить имя пользователя в окошке сообщений:
Для её реализации требуется загрузка внешних компонент:
для 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"); КонецЕсли; КонецПроцедуры