gifts2017

Кто заблокировал объект ? 7.7 (SQL/DBF)

Опубликовал Епрст (Ёпрст) в раздел Администрирование - Системное

Обработка блокировки объекта в базе для SQL/DBF варианта.

 

 

 

 

 

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

 

 

 

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

Данная метода позволяет автоматом получить имя пользователя в окошке сообщений:

 

 

Для её реализации требуется загрузка внешних компонент:

Formex.dll

1cpp.dll

для DBF версии еще и

1sqlite.dll

Идея очень простая - при начале работы системы проверяется наличие таблички в базе (в 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");
    КонецЕсли;
КонецПроцедуры

 

 

 

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Евгений Мартыненков (JohnyDeath) 13.08.10 11:35
Хорошо!
Я по аналогии давно хочу сделать "журналирование изменений", но меня терзает один вопрос. Что будет происходить, если один пользователь записывает данные в базу Sqlite и одновременно второй пользователь также начнет писать свои данные.
Не попадал на такое? Как бы красиво и без потерь разрулить подобные ситуации?
2. Евгений Мартыненков (JohnyDeath) 13.08.10 11:37
Извиняюсь, толком не посмотрел твой код.
Оказывается, у тебя идет бесконечный цикл попыток записи. Да, это решение проблемы, но какое-то тяжелое (для процессора).
3. Епрст (Ёпрст) 13.08.10 11:40
(1) попадал, поэтому и все выполнения запросов обёрнуты в цикл + попытка

А так ошибка будет "database is locked"
И т.к таких ошибок по ЖР было за день не так много (штук 10 всего) при 50 пользователях, то такое решение оправдано..

Щас вроде проблем нет.
+ новая версия ВК и режим "PRAGMA journal_mode=WAL" ускорили процессс записи в базу.


4. Епрст (Ёпрст) 13.08.10 11:42
(2) не.. норм.
Я ж проверил на живых пользователях методу сперва ... и без цикла с попыткой
:)
5. Евгений Мартыненков (JohnyDeath) 13.08.10 11:51
(3)
новая версия ВК и режим "PRAGMA journal_mode=WAL" ускорили процессс записи в базу.

Этот режим вряд ли ускорил запись в базу, просто теперь читатели и писатели не мешают друг другу.
Вот кусок с офф. сайта:
WAL might be very slightly slower (perhaps 1% or 2% slower) than the traditional rollback-journal approach in applications that do mostly reads and seldom write.

Хотя это очень маленькая погрешность и ей можно пренебречь.
6. Епрст (Ёпрст) 13.08.10 12:06
(5) да один хрен.. тут в табличке 2 поля всего.. быстро обновляет табличку.
я забил на блокировку - ошибок блокировок мало цикл вполне оправдан.
7. Александр Рытов (Арчибальд) 13.08.10 12:54
Вот если бы система еще сама стучала по голове блокировальщику...
9. Епрст (Ёпрст) 13.08.10 13:18
Добавлю, аналогично можно проверить, кто блокировал объект и при програмной записи..
сделав тот же самый запрос , что и в ОбработкаБлокировкиОбъекта
10. Александр Венгер (venger) 13.08.10 13:29
Можно подумать, но это так, - фантазии, чтобы тому, кто заблокировал объект, выскакивало предупреждение о том, что надо бы объект освободить, так как уже очередь...;-)
11. Александр (prolancer) 13.08.10 15:10
(10) когда известен автор проблемы, можно и по телефону ему позвонить, или докладную шефу на стол...
12. Епрст (Ёпрст) 13.08.10 15:30
(11) да и, если терминалка (или радмин какой-нить), самому закрыть объект..
или сессию срубить..
13. Андрей (Свой) 13.08.10 16:21
класс... твои юзеры наверное катаются в масле, окруженные такой заботой программиста :)
14. Епрст (Ёпрст) 13.08.10 16:57
(13) по крайней мере, перестали мне звонить по этой ерунде - рулят сами
15. Александр Венгер (venger) 13.08.10 17:02
(13),(14) Я еще хотел сказать, что он просто о себе заботится, чтоб не дергали по ерунде, а не о пользователях, но опередил в 14-м посте;-)
16. Аркадий Кучер (Abadonna) 13.08.10 18:31
А ежели просто ограничить время, которое юзер может держать объект открытым?
Одним формексом можно обойтись
17. Александр Венгер (venger) 13.08.10 19:00
(16) Как-бы это через чур жестко;-) Еще таймер обратного отсчета большими красными буквами: "До взрыва осталось: 00:00:03";-) Да и с программной блокировкой тогда как быть?
18. Владимир (hogik) 13.08.10 21:12
(16)
"Одним формексом можно обойтись"
- Эту задачу можно решить, вообще, без ВК. ;-)
(0)
Хорошее решение проблемы.
Но, думаю, еще имеет смысл устранять не следствие, а причину. Т.е. запретить пользователю открывать объекты БД в режиме редактирования по двойному щелчку в списках, журналах. Т.е. открывать в режиме просмотра объекта. И случайных проблем с "задним числом" будет меньше... Ведь чаще всего пользователи хотят только посмотреть объект БД, а не изменить его одновременно. Первичный документ, чаще всего, существует в одном экземпляре, на одном рабочем месте... Или не так? ;-)
Dolly_EV; kozorez; +2 Ответить 1
19. Аркадий Кучер (Abadonna) 14.08.10 03:54
(18)
- Эту задачу можно решить, вообще, без ВК. ;-)

Что-то сомневаюсь, если только прописывать код в каждый объект, а это не комильфо
20. Владимир (hogik) 14.08.10 15:22
(19)
Прописывать надо. Но не в каждый объект. Т.к. до появления "формекса", уже давно, прописано во все объекты вызов глобальной функции решающей схожие алгоритмы в схожих местах. Типа:
Процедура ПриОткрытии() хПриОткрытии(Контекст); КонецПроцедуры
Процедура ПриЗакрытии() хПриЗакрытии(Контекст); КонецПроцедуры
Нас самом деле, еще проще - используется общая функция, типа:
хУсё(КодДействия,Контекст).
Ну, а в конкретном случае данной темы, выполняются по смыслу следующий код, но расширенный на всё типы объектов 1С-а. Еще есть обработка показа списка всех заблокированных объектов.
Процедура ПриОткрытии()
	Если (Форма.ТолькоПросмотр()=0) И (Выбран()=1) Тогда 
		ЗначениеВФайл(КаталогИБ()+СтрЗаменить(ЗначениеВСтрокуВнутр(ТекущийДокумент()),"""","_")+".xxx",ИмяПользователя(),0);
	КонецЕсли;
КонецПроцедуры
Процедура ПриЗакрытии()
	Если (Форма.ТолькоПросмотр()=0) И (Выбран()=1) Тогда 
		ФС.УдалитьФайл(КаталогИБ()+СтрЗаменить(ЗначениеВСтрокуВнутр(ТекущийДокумент()),"""","_")+".xxx");
	КонецЕсли;
КонецПроцедуры        
Процедура Кнопка()
	Если ТекущийДокумент.Выбран()=1 Тогда 
		Предупреждение(ЗначениеИзФайла(КаталогИБ()+СтрЗаменить(ЗначениеВСтрокуВнутр(ТекущийДокумент.ТекущийДокумент()),"""","_")+".xxx",,0));  
	КонецЕсли;
КонецПроцедуры
...Показать Скрыть
21. Аркадий Кучер (Abadonna) 14.08.10 16:08
(20)
Т.к. до появления "формекса", уже давно, прописано во все объекты вызов глобальной функции решающей схожие алгоритмы в схожих местах. Типа:
Процедура ПриОткрытии() хПриОткрытии(Контекст); КонецПроцедуры

Вот и я про то же. У меня тоже было прописано глПриОткрытии() глПризаписи.
Но ты, по ходу, лет 10 на одной базе сидишь, а у меня их сейчас чуть не по паре новых в день (не считая еще 8х). А прописать формекс у меня сейчас всего две строчки в ГМ, которые не фиг восстановить после обновления. Все остальное работает в ДопГМ, который правь на лету - не хочу
22. Аркадий Кучер (Abadonna) 14.08.10 16:15
+(21)Вот считай:
Перем Сервис Экспорт; // раз строчка
Процедура ПриНачалеРаботыСистемы()
//....................................
ОткрытьФорму("Отчет",Контекст,КаталогИБ()+"СтартСистемы.ert"); // два строчка
КонецПроцедуры // ПриНачалеРаботыСистемы()
Все остальное делается "на лету"
23. Владимир (hogik) 15.08.10 00:51
(21)(22)
Аркадий.
Я же не против "формекса". Естественно, когда много разных конфигураций. Требуется делать обновления. Хочется не заниматься тупой работой. Надо использовать средства, типа, "формекса". А у меня, действительно 10 лет, всего, две конфигурации. Одна в бухгалтерии, в которую я не лезу. И одна, полностью самописная, для основной сферы деятельности конторы. Но эта конфигурация одна на все задачи конторы. От автосервиса до проходной. И база одна на всех. Мне легче, чем тебе, но ооо-чень скучно... :-(
24. Епрст (Ёпрст) 15.08.10 21:19
Ну да.. можно было бы обойтись одним формексом:
ид-объекта получать через ЗначениеВСтрокуУнутрь, а блокировки писать в файло (коть в текстовик, хоть в дбф) и поиск там же..

Вот только без ВК совсем не отловить интерактивное возникновение блокировки объекта. В лучшем случае, во всех формах списка /журналах документа прописать рукописное открытие формы через ОткрытьФорму() + смотреть, что возвращает метод.
ежели нуль - искать в файле блокировок юзверя, открывшего объект.
Но это как-то не очень.

25. Владимир (hogik) 15.08.10 23:20
(24)
"Но это как-то не очень."(с)
Да, "без ВК совсем не отловить интерактивное возникновение блокировки"(с). Надо либо "прописывать"(с) в списках/журналах, либо делать кнопку в списках/журналах, либо делать отдельную обработку с кнопкой в панели инструментов. Но пользователю не важно как это сделано если блокировки, такого рода возникают, один раз в неделю. Т.е., скажу еще раз, надо устранять причину. Открывать, по умолчанию, объекты в режиме "только просмотр". А если пользователям необходимо работать одновременно с одним объектом, то в схеме базы данных этот объект уже не один объект. Простой пример. Шапку документа забивает "бухгалтер", а строки документа "кладовщик". Сделать форму документа с закладками - это самое примитивное решение задачи. На самом деле (в нашем примере) шапка документа и строки - это разные объекты. Это в теории... ;-) И не в 1С... :-(
P.S. Повторю еще раз. Вы предложили очень хорошее решение проблемы. И использование этих ВК оправдано на 100%. Т.к., думаю, эти ВК используются в вашей системе не только для решения данной задачи. А, тогда, почему бы их не использовать и в этой задаче... ;-)
26. Епрст (Ёпрст) 16.08.10 08:05
(25) Да, так и есть - вк не только для этой задачи используются.
По-поводу правки, документ может иметь несколько состояний (распечатан/собран/и т.д и т.п) + разные схемы отгрузки.. Все эти доп флаги-реквизиты документа проставляются как правило, обработками. Но документ может быть открыт аналитиком в это время, для правки самого документа. Вот и возникают коллизии.
Не часто, но есть.
27. Victor Nespyatin (victuan) 16.08.10 08:27
Аж три ВК! Для такой рутинной задачи
28. Епрст (Ёпрст) 16.08.10 08:53
(27) см. (24)... достаточно одной.. - формекс.
29. Victor Nespyatin (victuan) 16.08.10 09:31
(28) "можно было бы обойтись одним формексом"
Так ведь не обошелся же :D
30. Епрст (Ёпрст) 16.08.10 09:35
(29) мне важна скорость работы и максимальное удобство, тем более, что 1cpp и 1sqlite используются в других местах кода, зачем лишать себя этого - не ясно.

А так, можно и вообще всё без ВК сделать, только оно надо ?
31. Владимир (hogik) 16.08.10 18:22
(26)
"доп флаги-реквизиты документа проставляются ... обработками"
"документ может быть открыт ... в это время ... для правки самого документа"
Об этом и говорю. Это и означает, что "доп флаги-реквизиты" не должны являются реквизитами документа. Т.е. наблюдается ошибка в проектировании схемы БД.
32. Епрст (Ёпрст) 17.08.10 10:40
(31)Намекаешь, что состояния документов нужно хранить в подчиненном документе ? Или еще где ?
Изменяются не только флаги, но и ключевые реквизиты типа Контрагент/договор/Фирма..
Долго объяснять почему, связано с разными схемами учета.





33. Владимир (hogik) 17.08.10 22:07
(32)
Намекаю на, немного, другое. ;-)
Проблемы блокировки документов, последовательности, проведение задним числом, закрытие периодов, само понятие "провести", свертка БД, регистры и т.д. возникает при попытки "автоматизировать" предметную область документами и бух.проводками. Но эта предметная область называется - бухгалтерский учет (и все его разновидности). Судя по Вашим текстам из (26)(32) сообщений, делается попытка автоматизировать не бух.учет, а реальную жизнь конторы. И использовать, для этого, структуры схемы БД типа документ - не совсем логично. Думаю, документ должен появляться на конечном этапе всей "хоз.операции" исключительно для взаимодействия с внешним контрагентом, в виде распечатки, а не в БД как единое целое. Но, это, опять не про 1С... :-(
34. Епрст (Ёпрст) 18.08.10 13:40
(33) почитал ваши посты в других обсуждениях, примерно понял, об чем речь..
К сожалению, в данный момент переделывать всё и уходить от логики, заложенной еще самой 1с не представляется возможным..
Да и на снеговик пытаются упорно толкнуть.
35. Gen Tay (GenTay) 19.08.10 09:47
Скачал, поставил +. Внедрил - база стала неустойчивой, подвержена вылетам и медленной.
36. Епрст (Ёпрст) 19.08.10 12:35
(35) ВК каких версий поставил ?

И на счет медленной.. есть сомнения.
У вас терминал, или чисто файловая ?
37. Епрст (Ёпрст) 19.08.10 12:38
+36 скажем так, терминалка, пользователей от 40 до 70 в одной базе, проблем с падением производительности и нагрузкой на проц не наблюдается.
Ну и вылетов, тем более нет.
38. Епрст (Ёпрст) 19.08.10 12:39
+37 на счет, чисто файловой не скажу, не тестил под нагрузкой, ибо таких баз не имею.
39. Евгений Мартыненков (JohnyDeath) 19.08.10 21:33
Да и для "чисто файловой" (вне терминала) базы директива sqlite
PRAGMA journal_mode=WAL

бесполезна
40. Gen Tay (GenTay) 20.08.10 13:47
(36) Релиз 7.70.266. Прога основательно доработана. Есть центральная и 2 периферийки. Периферийки на терминалах. Вылеты случались на разных периферийных базах. Причем по времени обновил вечером, утром следующего дня начало вылетать. День непоняток, на сл.день глушу в конфе текст доработки и два дня тьфу-тьфу. В принципе нет и нет, не парюсь по этому поводу.
41. Александр Орефков (orefkov) 20.08.10 14:26
+(39)
Я бы даже добавил, что
запросSQLLite.ВыполнитьЗапрос("PRAGMA journal_mode=WAL");

можно делать ТОЛЬКО если все юзеры этой базы сидят в ней на одном терминальном сервере. Если хотя бы один заходит в базу с другого компа - чревато неизвестным поведением, и лучше этого не делать.
42. Епрст (Ёпрст) 20.08.10 17:17
(40) заремь 2 процы ОбработкаБлокировкиОбъекта и ПриНачалеБлокировки, проблема осталась ?

попробуй заремить запросSQLLite.ВыполнитьЗапрос("PRAGMA journal_mode=WAL");
если юзвери работают не на 1 сервере терминалов.

(41) у меня так и есть...
43. Епрст (Ёпрст) 20.08.10 17:19
+42 .. По-поводу частых блокировок Sqllite базы во время записи, их и не так много за целый день.
Смотрел за 2 дня, тупо выкинув цикл с попыткой в ЖР.. При 50 пользователях, таких записей было ~15 за два дня.
Так что.. загон в цикл с попыткой оправдан.

44. Евгений Михайлов (Борода) 21.10.10 16:48
ОбработкаБлокировкиОбъекта не цепляет константы хотя ПриНачалеБлокировкиОбъекта отрабатывает. Это нормально ?
45. Епрст (Ёпрст) 21.10.10 16:57
(44) нормально, я не ставил целью обработку констант, если нужно - дописать недолго.
46. Евгений Михайлов (Борода) 21.10.10 17:04
плюс однозначный.
модифицировал малость:
Если МонопольныйРежим()=1 Тогда
запросSQLLite.ВыполнитьЗапрос("delete from БазаБлокировок");
Иначе
запросSQLLite.ВыполнитьЗапрос("delete from БазаБлокировок Where Пользователь = '"+Пользователь.Наименование+"'");
КонецЕсли;

(45) в чем нормальность, просветите.
47. Епрст (Ёпрст) 21.10.10 17:13
"Нормальность"
в том, что лень было константы анализировать еще :)

48. Епрст (Ёпрст) 21.10.10 17:16
(46) я бы не удалял сведения о пользователе - лишнее это.
Там всегда при начале блокировки - INSERT or REPLACE - всегда эта запись "перезапишется", если была.

49. Евгений Михайлов (Борода) 21.10.10 17:17
(47) нет, "ненормальность" в том, что при попытке вторым юзером зайти в константу процедура ОбработкаБлокировкиОбъекта не отрабатывает вообще и 1С сразу выдаёт ошибку.
Может это только у меня так ?
50. Епрст (Ёпрст) 21.10.10 17:37
(49)Я не помню уже, ловит или нет, надо у АЛьФа спросить.
51. Епрст (Ёпрст) 21.10.10 17:43
+50, для красоты, можно еще так сделать:

//Сообщить("" + Объект + " открыт пользователем " + ИмяВредителя,"!");
ДопТекст ="" + Объект + " открыт пользователем " + ИмяВредителя;
52. Евгений Михайлов (Борода) 21.10.10 18:04
(51) Это я уже сделал. Таки супер! :D
53. Максим Макаренко (dranzerf) 04.03.11 19:35
Вещь классная, тока, у меня почему-то наоборот не получается. Когда один пользователь заходит в справочник к примеру, то у другого выдает сообщение, а если этот другой откроет элемент справочника, а первый зайдет в него, то пишет только "объект открыт пользователем", а имя пользователя не пишет.
В чем причина и как ликвидировать?
54. Епрст (Ёпрст) 09.03.11 13:43
(53) Кто куда и откуда ?
Нипонятна..
55. Максим Макаренко (dranzerf) 10.03.11 07:12
Тут оказывается дело только в одном пользователе. Система блокировки не хочет определять его,тока не понятно почему. А с остальными все впорядке.
56. Епрст (Ёпрст) 10.03.11 09:19
(55) как "определяешь" пользователя ?
Через ИмяПользователя() или через глПользователь ?
57. Епрст (Ёпрст) 10.03.11 13:10
+56 да еще, у этого пользователя, ВК загружены ?
58. Максим Макаренко (dranzerf) 10.03.11 20:02
(56) глПользователь.
(57) Мы работаем через терминал, база на серваке, т.ч. да.
59. Епрст (Ёпрст) 11.03.11 08:57
(58) И ? наименование есть у него ?
Мот он без рабочего каталога входит, как "не авторизован" ?
Тогда и не пишется ему ничего..
60. Епрст (Ёпрст) 11.03.11 08:58
+59 у этого пользователя открой табло и напиши глПользователь.Наименование, что возвращает ?
61. Максим Макаренко (dranzerf) 11.03.11 18:49
Пишет - Ошибка в вырожении.
62. Максим Макаренко (dranzerf) 11.03.11 18:50
Может стоит использовать ИмяПользователя а не глПользователь?
63. Епрст (Ёпрст) 14.03.11 09:15
(61) ну вот и ответ.
(62) проще пользователю создать нормальный рабочий каталог и проверить его наименование/код в справочнике Пользователи.
64. Максим Макаренко (dranzerf) 14.03.11 19:43
Да нет. Все нормально. Просто тот, кто изначально заводил пользователей, не прописал им полное наименование. Т.ч. все работает, но все равно спасибо.
65. Максим Макаренко (dranzerf) 16.03.11 19:48
Не. Все равно проблемы. Что-то со строкой: ИДОбъекта = глМД.ЗначениеВДлиннуюСтрокуБД(Объект);
Вопрос такой - есть ли ограничения по версиям dll и конфигурации?
66. Епрст (Ёпрст) 17.03.11 08:15
(65) есть.
1cpp желательно иметь 3-ей версии
67. Vitaly Pishchanok (vitapi) 21.04.11 17:17
А почему это решение не подходит для 1С SQL? Мне для SQL надо...
68. Епрст (Ёпрст) 21.04.11 18:10
(67) потому, что на 1sqlite написано, а так, в SQL сделать намного проще - создал табличку для хранения заблокированных объектов в самом скуле + всё тоже самое + синтаксис запроса подправить.
69. Vitaly Pishchanok (vitapi) 21.04.11 18:15
(68) То есть, как я понимаю, это вопрос целесообразности? Я было подумал, что это несовместимо с SQL.
70. Епрст (Ёпрст) 21.04.11 18:41
(69) для скуля это просто можно сделать разными способами, (на софтпоинте есть одно из решений, например)
а вот для дбф никто не удосужился, вот я и выложил.

А так, для скуля всё сделать по-аналогии, только заместо базы в sqlite использовать свою табличку в скуле.
проверяешь есть ли она, если нет , то create table и всё собственно, так же в ПриНачалеБлокировки пишешь в неё того кто заблокировал, потом так же обрабатываешь блокировку.
Короче, тот же код, только синтаксис запроса чуть другой.
71. Епрст (Ёпрст) 22.04.11 15:57
+70 добавил для скуля.. пробуйте.
72. Язва Жопы (Sergafan10) 25.04.11 11:49
На скуле не показывает пользователя, но мне кажется это у тех, у кого права в системе "овощные" или же библиотека не зарегана. Заходил под админом на двух разных тачках - всё путем.
73. Епрст (Ёпрст) 25.04.11 11:54
(72) Это, использовал ПолноеИмяПользователя() или глПользователь.Наименование ?
74. Епрст (Ёпрст) 25.04.11 11:56
+(73) ну и 1cpp и formex желательно грузить в ПриНачалеРаботыСистемы ( и регистрить их спецом не надо, они уже сто лет в обед в этом не нуждаются)
ЗЫ: ставмит только последних версий желательно 3 и выше для 1cpp и ..101 и выше для формекса.
Sergafan10; +1 Ответить
75. Язва Жопы (Sergafan10) 25.04.11 12:38
Судя по всему ПолноеИмяПользователя(), т.к. у того, кем блокировал, как раз его и не было(причём только у одного). ;)))
Рад, что регать не надо, у меня версии свежие, а то я уж способы регания библиотек в домене наскоблил)))
Спасибо!!! Плюсанул.
76. Станислав Шепталов (sCHTASS) 25.04.11 14:04
Могет кому будет полезно и мое творение http://infostart.ru/public/19782/.
Отличие от этой разбработки:
1) использует 2 компоненты: 1с++ и formex
2) работает _ТОЛЬКО_ на sql-базах
3) чтобы все заработало, нужно прописать в глобальнике только одну строку.
4) в любой момент можно отключить/включить приблудку.
77. Епрст (Ёпрст) 25.04.11 17:44
(76) публикация не активна, а так, моя поделка использует 2 ВК для скуля и 3 для ДБФ, хотя можно и 1-ой обойтись - формексом, но не удобно.
78. Станислав Шепталов (sCHTASS) 25.04.11 21:20
(77) Странно. Когда-то была активной...
79. Епрст (Ёпрст) 26.04.11 09:42
(78) посмотрел, всё тоже самое, отличие - все действия в доп глобальнике, минус - не проверяется, был ли он(доп глобальник) уже загружен ранее.

:)

Методе то сто лет в обед
80. Епрст (Ёпрст) 26.04.11 09:45
81. Наталья Кондрашова (natalika1601) 17.05.11 11:19
После подключения данной обработки при закрытии базы стала выскакивать ошибка отложенной записи Windows. И база стала тормозить. Что с этим делать? База dbf.
82. Епрст (Ёпрст) 17.05.11 15:08
(81)
база по сети ?
в терминале ?
ВК каких версий поставили ?
83. Константин (cabat) 19.05.11 13:28
Использую данную схему некоторое время (база DBF, база блокировок в SQLite-файле), все гуд.
Но тут наткнулся на такой момент - при массовой обработке объектов получаем большой поток блокировок объектов
и соответствующее кол-во запросов вставок в базу блокировок.
И что то как то подтормаживает все это некисло..
Пока обошел так - добавил методы начала и фиксации транзакции при записи в SQLite, перед массированной обработкой объектов начинаю транзакцию, после фиксирую..
Ускорение на порядок, но как то некузяво это..
Может какое более красивое решение есть?
84. Епрст (Ёпрст) 19.05.11 18:42
(83) база в терминале или по сети ?
У меня, даже при массовых операций тормозов не замечено.
85. Епрст (Ёпрст) 19.05.11 18:42
база в терминале, правда.
86. Константин (cabat) 20.05.11 09:16
боевая база в терминале, для разработки локальная - результат одинаковый
по профайлеру получается, что 80% времени выполнения массовой обработки объектов занимает запись в таблицу заблокированных объектов..
если обернуть процедуру в транзакцию SQLite, то время выполнения сокращается на порядок..
87. Константин (cabat) 20.05.11 10:32
попробовал на всякий случай сначала один раз подготовить запрос, а потом вызывать с параметрами - результат тот же..
причем ведь файлик базы SQLite весит то всего 10-20Кб, а скорость вставки записей очень низкая получается..
наверное я просто не умею ее готовить :(
88. Епрст (Ёпрст) 20.05.11 14:30
(86) странно, у меня в худшем случае, если кто-то ужо пишет туда.. но по логам в ЖР, когда цикла с попыткой выполнения запроса не было, таких случаев в день при 70 юзверей, не так и много..
А с попыткой в цикле и так влёт влетает.
1sqlite какой версии хоть ?
Покажи, как свою транзакцию ставишь.
89. Константин (cabat) 20.05.11 14:54
1sqlite версия: 1.0.2.3

транзакция ставится выполнением запроса "BEGIN TRANSACTION", фиксируется "COMMIT TRANSACTION"
в остальном код по работе с таблицей блокировок почти один в один взят из твоего примера..
только у меня используется класс-обертка над объектом 1sqlite для выполнения запросов
90. Епрст (Ёпрст) 20.05.11 16:30
(89) странно..
Ладно, попобую поиграться на досуге..
Ты кстати, отключение журналирования делал ?
91. Константин (cabat) 20.05.11 17:05
(90) а то..
даже спецом добавил в класс метод, который возвращает текущий режим - думал, может не срабатывает..
пробовал даже режим MEMORY ставить..
может конечно, имеет смысл с Сашей Орефковым посоветоваться, может я что то не так делаю при работе с 1sqlite..
92. yurok kozorez (kozorez) 06.05.12 12:26
Хорошее решение проблемы.
Но, думаю, еще имеет смысл устранять не следствие, а причину. Т.е. запретить пользователю открывать объекты БД в режиме редактирования по двойному щелчку в списках, журналах. Т.е. открывать в режиме просмотра объекта. И случайных проблем с "задним числом" будет меньше... Ведь чаще всего пользователи хотят только посмотреть объект БД, а не изменить его одновременно. Первичный документ, чаще всего, существует в одном экземпляре, на одном рабочем месте... Или не так? ;-)

тоже считаю что очень правильное решение, плюс настроенные права пользователей, не открывать что не нужно или не редактировать.
93. Алексей (Rockman) 17.05.12 12:42
97. QWE Qwerty (qwe_QWE) 06.07.12 14:03
Не могу понять - Процедура ОбработкаБлокировкиОбъекта() вызывается уже из объекта конфигурации?
98. Анна Денисова (aimerlive) 13.07.12 11:52
Интересная идея спасибо!
99. Епрст (Ёпрст) 13.07.12 12:07
(97) ?
что значит "из объекта" ?
100. Епрст (Ёпрст) 13.07.12 12:07
это всего лишь предопределенная проца глобальника из формекс
101. Евгений Долиновский (Dolly_EV) 01.11.12 07:14
Прикрутил... при групповом проведении на писание в SQLite тратится 1% времени. А как бы сделать так, что при групповых операциях в таблички не писалось?. Т.е. как узнать в ПриНачалеБлокировкиОбъекта(), что это групповой проведение?
102. andrewks 01.11.12 07:34
(101) Dolly_EV, если я правильно помню подноготную 7.7, то можно в модуле проведения дока в разделе осн. программы установить переменную ЭтоГрупПров=0, а в самой процедуре проведения в самом конец ЭтоГрупПров=1.

тогда по тексту процедуры проведения можно будет опираться на эту переменную, за исключением самого первого дока данного вида, но, думаю, 1 док - это не показатель.

только проверьте сначала эту фишку
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа