Определение простоя в работе пользователя.




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2025-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

42 Comments

  1. coder1cv8

    Часто встречаю вопросы на форумах типа «Как заблокировать/закрыть сеанс 1С при простое», поэтому появилась такая вот безделица… )

    Reply
  2. tango

    хорошо бы этот функционал полностью внешний

    Reply
  3. coder1cv8

    (2) Можно если, разве что, сделать в виде внешней обработки и её открытой у пользователя держать всё время… Что, согласись, не красиво.

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

    Reply
  4. PeRom

    Отлично за идею, на досуге опробую.

    Reply
  5. zyto

    Это из серии — работаешь, работаешь, и тут бац — заставка!

    Reply
  6. coder1cv8

    (5) В смысле?… )

    Хотя, лично у меня, не возникало необходимости в подобных утилитах… Сам бывает «медитирую» над кодом пока заставка не появится… )

    Но раз люди спрашивают, значит кому-то это необходимо. Вон бывает ключиков на всех не хватает )

    Reply
  7. sergeevn1

    А у меня отчет формируется два часа без нажатий мыши и клавиатуры. Тоже получится простой?

    Reply
  8. coder1cv8

    (7) Надо отчеты оптимальней писать, товарищ! ))

    А если серьезно, то да, если пользователь вообще не будет трогать клавиатуру и мышь эти 2 часа, уйдет например куда-нибудь — то это простой. А если он свернет окошко 1С и будет другими делами заниматься, то простоя не будет.

    Reply
  9. Shaman100M

    (8) Если выполняется отчет, опрос «по бездействию» пользователя не производится до тех пор, пока отчет не выполнится? Тогда, имхо, логично к накапливаемому общему времени простоя добавлять не время выполнения отчета, а просто один период опроса, или, обобщенно, [кол-во опросов за время выполнения чего-л] х [период опроса]

    Reply
  10. coder1cv8

    (9) Да, опрос времени бездействия выполняется через ОбработчикОжидания, поэтому, естественно, в период формирования отчета/выполнения обработки он не делается. Суть в том что считается время простоя системы, а не 1С. Поэтому формирование отчета в общем случае не является простоем, что вполне логично, ИМХО.

    Reply
  11. Трактор

    ИМХО считаю лишним делать три константы ПериодОпросаПростоя, ВремяПростоя, ДействиеПриПростое. Я бы обошёлся одной константой «НатройкаПриПростое» типа строка неограниченной длины. Туда можно запихивать структуру с нужным количеством полей.

    Возможно это тема для форума, но мне лень идти на форум…

    Reply
  12. coder1cv8

    (11) Конечно, можно вообще все константы таким образом «упаковать». Но это, на мой взгляд, не совсем методически грамотно. Да и здесь главное сделать наглядно, что бы был понятен принцип. А дальше каждый может модернизировать как считает нужным…

    Reply
  13. sml

    а как насчет того, чтобы простоем считать неактивность сессии (не елозит мышь в окне 1С, не нажимаются клавиши в активном окне 1С и при этом загрузка процессора процессом 1с = 0?

    дело в том, что многие юзверя понаоткрывают окон 1С на рабочем столе и в это время трут в асе или шарят в нете — а ресурсы заняты в это время.

    Reply
  14. coder1cv8

    (13) Ну а что же вы хотите от БЕСПЛАТНОЙ разработки? ) Можно сделать и это. У софтпоинта, вроде, есть подобное решение, которое считает именно активность процесса 1С, но это и денег стоит не малых я думаю…

    Reply
  15. puh

    (13) 1С всегда загружает проц, либо это обработки ожидания, либо в открытых списках идет обновление информации.

    Reply
  16. alina-aud

    заинтересовала Ваша обработка …

    подскажите, а для терминального сервера можно доработать? Т.е. человек удаленно по rdp заходит в сессию ….. срабатывает блокиратор, но после закрытии 1С через пару секунд и закрывается сеанс пользователя с сервером….

    Reply
  17. coder1cv8

    (16) да, это возможно сделать )

    Reply
  18. alina-aud

    (17) к сожалению, shutdown -l не поддерживает указание времени задержки в 5 секунд … [shutdown -l -t 5]

    на сервере запущена программа, которая «контролирует» закрытие 1с, а потом уже разрешает закрыть сессию …. и вот без этой задержки идея и накрылась =(

    Reply
  19. coder1cv8

    (18) скрипт написать, вызывающий shutdown, куда вставить sleep(5000)

    Reply
  20. alina-aud

    (19) вот, подсказали кусок кода … как бы сюда вставить задержку?

    Set objWMIService = GetObject(«winmgmts:\.
    ootcimv2:Win32_Process»)

    errResult = objWMIService.Create(«B:1cv8.exe», null, int1cID)

    Set objWMIService = GetObject(«winmgmts:\.
    ootcimv2»)

    Set colProcesses = objWMIService.ExecNotificationQuery _ («Select * From __InstanceDeletionEvent Within 1 Where TargetInstance ISA ‘Win32_Process'»)

    Do Until False = True

    Set objProcess = colProcesses.NextEvent

    If objProcess.TargetInstance.ProcessID = int1cID Then

    Exit Do

    End If

    Loop

    Set objShell = CreateObject(«Wscript.Shell»)

    objShell.run «shutdown /l»

    Reply
  21. grum01

    (20) Настрой сеанс терминала (в настройках пользователя), на запуск 1С при входе на сервер. Тогда сеанс RDP будет автоматически закрываться сам при окончании работы в программе.

    😀

    Reply
  22. fillin

    Какая-то польза от новой системы, наверное, есть. Напомнили, что надо воздать должное авторам. (На http://infostart.ru/profile/activity/downloads/ теперь есть значки-напоминалки)

    Скачал эту разработку уже давно. Аж 25.10.08.

    Прикрутил к корпоративной УПП, кое-что допилил: добавил предупреждения юзерам о скором закрытии сеансов, лог в журнал регистрации, и после закрытии сеанса с помощью AutoIt выводится сообщение о том, что сеанс 1С закрыт из-за простоя (Чтоб юзера не паниковали).

    Эффект: У нас 110 ключей было. Их стало не хватать, но на новые в бюджете тек. года средств не было. После того, как прикрутил эту обработку, и мертвые сеансы стали автоматом завершаться через 2 часа, выснилось, что реально работающих пользователей в среднем 80 человек.

    Теперь у нас нет проблем с нехваткой ключей.

    Reply
  23. uropek

    то, что доктор прописал!

    Reply
  24. Sergey_Murzinov

    Используем, сначала юзвери ворчали, потом привыкли. Нормально

    Reply
  25. Ruslan***

    Спасибо. Применил идею завершения работы в 1С.

    Reply
  26. petrovaUL

    Спасибо. Пригодиться — оптимизировать работу пользователей, бывает из 1С-ки не выходят и ПК не отключают.

    Reply
  27. goodman12

    Спасибо, полезно. А то черти эти вечно забывают выходить как положено

    Reply
  28. Klondaik

    Отличная публикация. Сделал с ее помощью выход в режим ожидания программы, а то складские работники вечно оставляют все открытым и по свим делам ходят.

    Reply
  29. piton667

    Столкнулся с похожей проблемой, ключей не хватает, сервак тормозит, а юзеры по 3 часа висят неактивные…..

    Может кто загонялся над таким вопросом , может можно подключаться к диспетчеру служб терминалов как к КОМ-объекту? Чтобы от туда получать простои пользователя, и на основании этого выкидывать их…

    Reply
  30. borrman

    Спасибо!

    Прямо вот сегодня такую задачу поставили.

    Отлично!

    Reply
  31. antgrom

    Взял файл по ссылке на Народ.

    Блокировка не работает ни в оригинальной конфе , ни при объединении с другой базой.

    Проверял только в файловом режиме.

    ОС : Виста.

    Платформа : 8.1.13.41.

    В чем может быть причина отсутствия блокировок ?

    Reply
  32. antgrom

    + 33 Все работает. Вопрос снят.

    Реализовано красиво.

    Reply
  33. Santur

    (22) fillin, а не хотели бы поделиться допиленной версией?

    Reply
  34. mr_best_23rus

    Автору респект! Подсистема помогла!

    Reply
  35. avk2009

    Спасибо за разработку, а главное за то, что скачивание бесплатное! Сконвертировал для 1С 8.2 — все работает без нареканий.

    Reply
  36. Velliar

    А с терминальной сессией дружит обработка?Понимает она что 1С запущенна, но терминал свернут?

    Reply
  37. medvedev8

    Добрый день! Подскажите, пожалуйста, возможно ли в качестве времени простоя считать время простоя 1С, а не всей системы?

    Reply
  38. bashirov.rs

    Возьмем на заметку. Спасибо — ставлю плюс!

    Reply
  39. Namig

    в 8.0.18.2 выдает ошибку: {ОбщийМодуль.ПроверкаПростоя(8)}: Метод объекта не обнаружен (ВремяПростоя)

    ВремяПростоя=Блокиратор.ВремяПростоя()/1000; // в секундах

    Reply
  40. kredko

    Для SQL-ного варианта такая фича будет когда-нибудь?

    Хотя уже не надо. Написал сам для документооборота на уФ.

    Reply
  41. izidakg

    просто и эффективно, наткнулся на эту разработку в БД клиента и только потом уже тут нашел подробное описание и обсуждение.

    у меня только один вопрос — в обработке «Блокиратор» в макете зашит файл EXE и естественно возник вопрос а что он делает?

    Reply
  42. Risoks

    Скачала. Не могу воспользоваться:

    «Структура конфигурации несовместима с текущей версией программы»

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *