При многопользовательском режиме, пользователи часто видят перед собой картинку

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

Для её реализации требуется загрузка внешних компонент:
для 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"); КонецЕсли; КонецПроцедуры
Вступайте в нашу телеграмм-группу Инфостарт
