Книга знаний

1С:Предприятие / Администрирование / Производительность

Перепроведение документов в 1С:Предприятие без блокировки других пользователей

Статья описывает способ "безопасного" проведения документов при работающих сетевых или SQL-пользователях. Дело в том, что если проводить документы без пауз, то работа остальных пользователей в 1С будет заблокирована. Статья содержит ссылку на внешнюю компоненту с исходным кодом, а также содержит другие рецепты, как сделать паузу без использования внешних компонент.Автор статьи: romix | Редакторы: Лёвыч, Fragster, coding, mikecool,
Последняя редакция №8 от 28.03.11 | История
URL: http://kb.mista.ru/article.php?id=98

Ключевые слова: sleep, транзакция, блокировка, пауза, проведение, документов, компонентофобия


Для того, чтобы транзакции пользователей не «висели» в бесконечном (или, скорее, конечном) цикле, а могли все-таки выполниться, алгоритм перепроведения документов должен включать паузы (т.е. необходимо проводить документы не все время, а с промежутками). Тогда пользователи смогут «вставить» свои собственные транзакции, и продолжить, без значительных помех, свою работу.  

К сожалению, в 1С нет аналога системной функции sleep, которая в системе Windows (и, кстати, изначально - в Unix) делает паузу в миллисекундах, не нагружая при этом процессор (точнее, процессор все равно работает, но при этом выполняются другие задачи в многозадачной операционной среде). Для этого, если вы не ищете легких путей, используйте внешнюю компоненту, которая реализует системный вызов sleep().

Пример внешней компоненты (с исходным кодом) можно скачать по адресу:
http://x-romix.narod.ru/Sleep.rar

Если у вас лекарственная идиосинкразия к внешним компонентам и COM-объектам, есть и другие способы сделать паузу. Один из самых простых - Предупреждение() с таймаутом в секундах (второй параметр метода Предупреждение):

Процедура Проведение()
  док=СоздатьОбъект(«Документ»);
  док.ВыбратьДокументы(НачДата, КонДата);
  Пока док.ПолучитьДокумент()=1 Цикл
    док.Провести();
    Предупреждение(«Ждем 3 секунды…», 3);
  КонецЦикла;
КонецПроцедуры


Звезочет: предупреждение не срабатывает, если окно теряет фокус ввода. То же самое, для диалога ВводЧисла. А вот для ВводСтроки - таймаут работает! ;))
v8: Аналог Sleep()



//делает паузу с округлением до целого числа секунд - 1000, 2000 и т.д.
//Использует ВводСтроки с таймаутом, который работает даже если окно теряет фокус ввода.
Процедура sleep(ms)
    стр="Ожидание "+ТекущееВремя();
    Состояние(стр);
    сек=цел(ms/1000);
    ВвестиСтроку(стр, стр, 100, 0, сек);
КонецПроцедуры    




Для организации цикла ожидания можно также воспользоваться (недокументированной) функцией _GetPerformanceCounter() – это счетчик времени в миллисекундах, или документированной – ТекущееВремя() – с точностью до секунды. Но при этом потребуется «крутить» цикл без пауз, который, как известно, потребляет 100% ресурсов одного процессора (что может сказаться на производительности работы пользователей, например, в терминальном режиме).

Лёвыч:
для тех, у кого идиосинкразия только к ВК, но не к ActiveX-объектам в целом, могу предложить такой велосипед:
Процедура глВремя_Задержка(чСекунд) Экспорт

    ИмяПутьСкрипта = КаталогПользователя()+"sleep.js";
    
    Скрипт = СоздатьОбъект("Текст");
    
    Скрипт.ДобавитьСтроку("WScript.Sleep("+Строка(1000*чСекунд)+");");
    
    Скрипт.Записать(ИмяПутьСкрипта);
    
    cmdLine="wscript.exe "+ИмяПутьСкрипта;
    
    WshShell = СоздатьОбъект("WScript.Shell");
    
    WshShell.Run(cmdLine, 0, -1);

КонецПроцедуры



Fragster: Для паузы можно использовать более короткий вариант:
Процедура глПауза(Сек)
    scr = СоздатьОбъект("WScript.Shell");
    scr.Run("sleep "+СокрЛП(Число(Сек)),0,1);
КонецПроцедуры;

Ну а если у кого-то нету sleep.exe, то
Процедура глПауза(Сек)
    scr = СоздатьОбъект("WScript.Shell");
    scr.Run("ping 127.0.0.1 -n "+СокрЛП(Число(Сек)+1),0,1);
КонецПроцедуры;

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика