<?php // Полная загрузка сервисных книжек, создан 2024-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='\
Странно, что не работает SleepVbs. Я обычно таким методом пользуюсь, на компах с Виндовс работает.
Все работает…
Показать
Почему-то забыли для УФ асинхронный диалог вопроса? Он принимает параметр Таймаут (который нам и нужен), и заодно выводит юзеру сообщение — а обратная связь не помешает, ведь так? Я обычно вызываю что-то вроде
Показать
Кроме очевидного — задержки, не нагружая системные ресурсы — этот метод даёт пользователю возможность прервать длительный процесс, а нам — корректно отработать это прерывание и сделать всё красиво.
Ах, да, и самое, наверное, важное: этот метод работает с любым клиентом в любой операционной системе. В отличие от.
(4) +1, какой-то набор вредных советов в статье 🙂 Если только нужно именно на сервере пауза, в очень редких случаях.
Есть ещё
работает и в обычных и в управляемых формах.
(0)
Не соглашусь с автором — вариант SleepJs прекрасно работает.
(6)
Вы считаете, что обработкам, выполняющимся на сервере, совсем никогда не нужна задержка выполнения?
Реальный пример кода, где обработка ждет, когда все задания отправятся на принтер. Кстати, применен один из методов паузы, описанный автором статьи:
(6) пример из жизни. нужна была пауза при отправке смс, т.к. оператор устанавливал лимит на количество сообщений в очереди в секунду.
P.S. Сделал через ПодключитьОбработчикОжидания()
все варианты работают в windows. укажите чисто 1с метод через HTTPСоединение или ожидания блокировки
Если очень хочется ждать на сервере, то на мой взгляд наименее костыльный способ — это ожидание фоновым заданием самого себя.
Показать
Можно еще так фоновое задание+блокировки:
Показать
Показать
(1) Сравнил с (7). Работает, у меня пауза была не в секундах, а в миллисекундах, поэтому я решил, что не работает.
(7) Работает, у меня пауза была не в секундах, а в миллисекундах, поэтому я решил, что не работает.
(2) Добавил в статью
(4)
То, что Вы предлагаете, принципиально не годится, именно из-за асинхронности. Нужна ПАУЗА! А у Вас не будет никакой паузы. Висящий вопрос в асинхронном режиме — это не пауза, т.к. программа уже пошла вовсю дальше работать.
(16)
То есть, как делать формы для работы в асинхронном режиме, Вы не умеете. Но это — недостаток Вас как специалиста, а не моего ответа как алгоритма.
Подскажу для тех, кто в танке: код в методе ПриОткрытииЗавершение() выполнится только после завершения ожидания.
Переносите в него всё, что должно было отработать после паузы, и всё!
А вообще, сайт its.1c.ru, и RTFM
Ожидание на фоновом задании — самое интересное решение (сам только что хотел предложить такое же) — но, надо бы проверить как будет вести себя в файловой базе. Предложу ещё фичу — один раз запустить «бесконечное» регл. задание (аналогично ждущее завершения самого себя) — и всем остальным сеансам обращаться на ожидание завершения ФЗ этого регл. задания. Но будет одна пользовательская лицензия расходоваться на регл. задание. Но ФЗ доступны только на сервере или в толстом клиенте — но для длительного ожидания можно и в серверный контекст переходить — это не проблема.
Остальные все советы платформенозависимые (хотя некоторые подходы можно переработать так, чтобы они имели реализацию для разных платформ).
Использовать WshShell
WshShell = Новый COMОбъект(«Wscript.Shell»);
WshShell.Run(«Wscript.exe…»)
Всё же не рекомендую — 10-я версия платформы на это может ругаться, да ещё и в безопасном режиме работать не будет.
Но если надо так — то лучше «ЗапуститьПриложение(КомандаWindows,,Истина);» — по крайней мере будет работать в Windows, Linux и MacOS (c WEB-клиентом могут быть проблемы), где теперь тоже есть клиенты 1С.
Если нужно чисто на клиенте — то придётся извращаться с «ПодключитьОбработчикОжидания» — если нужно платформеннонезависимое решение, работающее в безопасном режиме, без модальности.
Но прямо среди кода остановиться так не получится — но, на мой взгляд, если такой код разбить на части через «ПодключитьОбработчикОжидания» не получится — значит там явно очень плохой дизайн.
Либо, нужно просто написать классический бесконечный цикл (думаю, что сюда попадут лишь короткие паузы — не более пары секунд- можно и покрутить проц клиента — коли уж очень нужно).
Или писать платформеннозависимый не безопасный код через вызов «ЗапуститьПриложение» или, ожидать на фоновом задании (регламентном или специально запускаемом), ждущим самого себя; с заходом в серверный контекст выполнения (если это не толстый клиент).
В общем всё ещё ждём, когда 1С встроит в платформу системную функцию паузы… давно ждём….
(10) Через HTTPСоединение
Показать
Будет платформенонезависимо, будет работать на клиенте. Но опять-таки, не работает в безопасном режиме (хотя на сервере профиль безопасности можно настроить, чтобы работало — для КОРП лицензии сервера).
И, главное, чтобы строка соединения в «HTTPСоединение» была указана корректная — чтобы доступ к HTTP ресурсу в принципе был!
Я думаю, что это хороший пример того как писать не надо.
(17)
То есть, смысл моего замечания Вы не поняли. Но это — недостаток Вас как специалиста, а не моего замечания :).
Уж конечно, я понимаю, что «код в методе ПриОткрытииЗавершение() выполнится только после завершения ожидания». Но вот то, что ПОСЛЕ ПоказатьВопрос — выполнится сразу. И вот этот «гениальный» подход : «Переносите в него всё, что должно было отработать после паузы, и всё» — применим не всегда. Или для этого нужно извратиться так, как рвать гланды через Ж. Статья вообще не об этом, а о паузе. А это не ПАУЗА ( впрочем, что-то я повторяюсь, а зачем ? )
Думаю, что многие уже сами догадались, но все-таки нужно поотделять мух от котлет хотя бы для новичков, которые могут это читать:
Вариант с пингами:
Трансформируется в:
Аналогично Timeout, который я выложил в комментариях
Трансформируется в:
Показать
Соответственно все эти варианты обращаются к командам, которые можно вводить через консольку операционной системы, использовать в CMD-файлах, но следует различать:
Во-первых обратиться можно к разным командам ОС (Ping, Timeout)
Во-вторых способ, которым можно обратиться — (Оператор платформы «ЗапуститьПриложение» и COMОбъект(«WScript.Shell»); )
Соответственно — на клиенте «ЗапуститьПриложение» выкидывает черное окно с консолью, на сервере его никто не видит
COMОбъект(«WScript.Shell») — обходится без визуальных эффектов.
А что из этого использовать — дело другое Timeout команда для задержки собственно и предназначенная, но в старых операционных системах (Windows 2000 точно, Windows XP не помню точно) отсутствовала. Проблема с CMD в те времена решалась похишением Timiout.exe с серверной операционной системы аналогичной давности и помещением в System32 на целевой машине.
А вот найти машину не поддерживающую Ping и лишенную TCP/IP напрочь уже тогда было сложно. (Хотя мне это удалось)
Спасибо, очень полезная статья.
(20)Павел, здравствуйте! Пишу не по теме, но хотелось бы проконсультироваться с Вами по поводу Вашего плагина для вордпресс opcity. Как с Вами можно связаться?
Кусок функционала из БСП:
Функция ПроверитьДоступностьСервера(АдресСервера)
СистемнаяИнформация = Новый СистемнаяИнформация();
ЭтоWindows = (СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86)
Или (СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64);
Если ЭтоWindows Тогда
ШаблонКоманды = «ping %1 -n 2 -w 500»;
Иначе
ШаблонКоманды = «ping -c 2 -w 500 %1»;
КонецЕсли;
СтрокаКоманды = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонКоманды, АдресСервера);
Результат = ЗапуститьПрограмму(СтрокаКоманды, ПараметрыЗапускаПрограммы);
Ссылка на эту статью есть в публикации, которую использовали. Взяли на заметку
Найдено в недрах БСП:
Показать
Платформо-независимо, работает на сервере, не нагружает процессор.
Вызов из БСП:
Найдено в недрах БСП:
Показать
Платформо-независимо, работает на сервере, не загружает процессор.
Вызов из БСП (пример):
+ в копилку
типовой из подсистемы Меркурий (первая версия подсистемы опубликована в июле 2018)
(29)Сами же мучаются, но написать встроенную в язык паузу — все никак … Автору спасибо и за статью, и за то, что статья получилась собиратель полезных комментариев. Конструктивным комментаторам тоже ++. Мой пример серверной потребности в паузе: в регламентном задании отправляю на сторонний php скрипт картинки порциями, скрипт их закачивает и параллельно создает миниатюры, иногда не успевает к моей следующей отправке порции картинок — нужна пауза несколько секунд.
Спасибо автору и комьюнити, не пришлось изобретать велосипед.
Еще из БСП (обработка УправлениеДоступом):
Показать
отлично
работает
САМЫЙ КОШЕРНЫЙ SLEEP — платформонезависимый, не требует прав пользователярасширения на запуск внешних процессов
Показать