<?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='\
Чемтиповые механизмы БСП не угодили? Там еще и контроль доступа для фонового задания задействовать можно будет.
(1) читал я про эти методы, к сожалению нет идентификатора задания, а хотелось бы получать прогресс и выводить сообщения из фонового задания. а то от обычного кружка или котика радости мало))
(2)вот здесь-то смотрели?)
(3) о да, она даже у меня в закладках есть) там есть привязка к «ИмяМодуля.ИмяЭкспортнойПроцедуры», ещё и замена общей формы, а задача — реализовать без изменения конфигурации.
(4) Привет, не пробовал такой хак пройдет аудит на Fresh ? С учетом того что обработка во внешних, из файла понятно что не возьмет.
(5) Нет, не пробовал, попробуй — нам расскажешь.
Разобрался =)
Необходимо понимать, что объект внешней обработки, вызов метода которого выполняется в фоне — не тот же самый объект, форма которого открыта на клиенте.
(8) Да, контекст в этом случае конечно отвалится. Я вообще вызываю процедуру из модуля объекта этой внешней обработки и туда передаю все что нужно. Рабочий пример если интересно здесь —https://infostart.ru/public/585055/ это по сути мой рабочий инструмент.
Спасибо! Утащил к себе.
(11)Да, ПрогрессОбработки и ИдентификаторЗадания надо добавлять на форму, это стоило указать хотя мне и казалось чем-то само собой разумеющимся. Имя файла проще всего получить через функцию
Ошибка при сохранении связана с безопасным режимом, если у Вас полные права, то такой проблемы не возникает.
Чтобы не выводить прогресс через состояние для ПрогрессОбработки сделайте Элемент с видом Поле индикатора. СтруктураПараметров — понятное дело ваша, там параметры для процедуры, которую будем запускать. Для простоты можно сделать просто процедуру типа
и на самой форме
но это совсем упрощенно
(12) выход вывод прогресса это не типовой функционал БСП, а нарисованная форма / элемент в обработке. Плюс как я понял нужно делать в логике длительной операции вызов процедуры:
В которую и передавать процент выполнения, а далее обработчик ожидания, его прочитает и вставит в наш реквизит.
Если на форме обработки идёт прогресс, у тебя остаются кликабельными кнопки и остаётся возможность менять реквизиты у пользователя в процессе выполнения длительной операции, или ты это запрещаешь?
До конца не понятно какие процедуры используются, т.к. указаны части кода из процедур, можешь привести код всех процедур полностью?
(11) для чего проверяется сообщение на фигурную скобку?
(16) когда длительная операция возвращает результат, то он в хмл, вот автор это и проверяет!
(14) менять реквизиты на ходу не получится, только перезапускать сеанс или мутить хранилище со значениями реквизитов и получать их в цикле. Тут надо понимать, что выполнение кода — это уже отдельный сеанс, основной сеанс о нем знает по идентификатору, а второй сеанс о первом не знает впринципе. Как я уже говорил пример где это работает здесь:https://infostart.ru/public/585055/ кода много в итоге, не уверен что Вам все нужно.
(18) речь не об этом, я не понимаю почему выбраеа такая технология : размещать прогресс на той же форме, а не открывать отдельную как в бсп.
В этом случае же есть недостатки:
1. Нужно постоянно во все свои доработки вносить намыорму прогресс и код для фонового задания
2. Когда пользователь запустил длительный процесс, он может в форме продолжать что-то творить , т.к. она осталась не заблокированной.
Мне кажется удобнее когда форма прогресса открывактся отдельно с блокированием прогоесса.
P.s. Обработку посмотреть не могу, нет см.
(20) нет особых проблем с тем чтобы заблокировать форму, это уже по желанию Доступность = ложь; для всех элементов кроме кнопок управления внешним процессом. Вообще идея в том чтобы код можно было вписывать в текстовое поле или например хранить в файлах, то есть обработка одна, а вариантов запускаемого кода много.
(22) У Вас дополнительная внешняя обработка ?
(23) да, в этом и смысл. В одну все поместить так понимаю нельзя. Ну хоть в 2
Почему нельзя ? Все можно . Вам просто надо все сделать правильно.
1) добавить 2 ключевых параметра Идентификатор команды — тип строка и ДополнительнаяОбработкаСсылка с типом Справочник ссылка Дополительные внешние отчеты и обработки
2) в модуле формы создать команду которая будет запускать длительную операцию ( но это не сама длительная операция ) см мой 19 ответ в этой теме процедура ЗагрузитьИЗаписать только надо будет заменит ВыполнитьКомандуВФоне на ДлительныеОперацииКлиент.ВыполнитьКомандуВФоне
3) В модуле объекта пишешь функцию регистрации внешней обработки (сведения о внешней обработке )
И добавляешь процедуру ВыполнитьКоманду ( ИдентификаторКоманды,Параметрывыполнения) — тут могу ошибиться как звучит второй параметр , в которой реализуешь свою длительную операцию
Вот и все
(25) Зачем регистрировать? то есть можно и регистрировать, но идея в том что БСП-шная процедура ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки открывает обработку просто как внешний файл и выполняет экспортную процедуру из её модуля. Команда здесь тоже не нужна, хотя наверное и через неё можно.
(26) я описал типовой механизм вызова длительной операции из внешней обработки как это рекомендует 1с.
Просто не понимаю зачем такие сложности получить обработку — передать на сервер и т.д. и т.п. Если есть внешняя обработка код которой нужно выполнить в фоне то это делается просто
Плюс вам писали про стандартные методы БСП и Вы сказали что Вам не нравится что нет идентификатора задания и котик вам не нравится и хотелось бы получать прогресс , но как я Вам уже отвечал это все решаемо , как раз Ваша статья на ряду с другими на эту тему натолкнула меня на мысль написатьсвою хотя она повторят то чт оо чем я писал тут выше
Спасибо! Разобрался, использую
Я то то не так понял или фоновое задание которое будет выполняться должно располагаться в конфигурации, а не в обработке?
(29)в обратотке, в модуле объекта. В конфигурации должна быть БСП с методом ДлительныеОперации.ЗапуститьВыполнениеВФоне.
(19) На БСП 3 также пытался сделать, не передаются некоторые параметры, пишет «Параметры не могут быть сериализованы».
Строки и числа передаются в ПараметрыКоманды, а что посложнее можно запихать в эти параметры, но выскакивает ошибка.
Кроме того, без БСП процедуры и функции в модуле объекта видят реквизиты объекта, а если запускать через длительную операцию, то ничего не видят — все значения пустые.
Непонятно как этим пользоватся, как сложные типы данных передавать для выполнения в длительную операцию на БСП 3?
(30)
…
ПараметрыКоманды.Вставить(«Каталог», Объект.Каталог);
//ПараметрыКоманды.Вставить(«Объект»,Объект);
ПараметрыКоманды.Вставить(«ТипЗагрузкиДокументов»,Объект.ТипЗагрузкиДокументов);
ПараметрыКоманды.Вставить(«НачПериода»,Объект.НачПериода);
ПараметрыКоманды.вставить(«КонПериода»,Объект.КонПериода);
…
Можно ли в этих параметрах передавать что то сложнее чем число или сторку? Хотел бы передать ТЗ и КомпановщикНастроек.
(32) что мешает поместить тз во временное хранилище , и через параметры передать адрес
(33)Насколько понял, создается другой сеанс для длительной операции. Поэтому переменная во временном хранилище, созданном в другом сеансе наверно видна не будет. А передать ее стандартным способом не получается, потому что она не сериализируется.
(34) не очень вас понял — посмотрите в стандартных конфигурациях — там сплошь и всюду так делается.
(35) До передачи в ПараметрыКоманды попробывал поместить:
Отборы — реквизит объекта внешней обработки, тип «КомпоновщикНастроекКомпоновкиДанных»
«Ошибка при выполнении запроса POST к ресурсу /e1cib/files/9ead0971-78e9-4061-8983-34f3c58b5395:
Переданное значение не может быть помещено во временное хранилище».
(35)Попробывал даже вот так —https://forum.infostart.ru/forum9/topic118827/
В процедуре формы оборачивал нужную переменную в структуру, а потом помещал в хранилище.
При попытке получить переменные в «Процедура ВыполнитьКоманду» из временного хранилища по переданным адресам ничего нет.
(37) Смотрите — основная проблема у вас в том что вы хотите передать то , что не может быть передано с клиента на сервер, ТЗ например таким способом передать можно
(38) ТЗ через временное хранилище тоже пустая.
Получается варианта два — либо я неправильно передаю, либо это вообще передавать не нужно.
Для чего все это. В модуле объекта внешней обработки я в цикле формирую отчеты (по времени долго), для которых и пытаюсь передать отборы любым способом, и все это пытаюсь передать на сервер для организации длительной обработки. Внешнюю обработку естественно помещаю в «Дополнительные отчеты и обработки».
Как можно обойтись без этого?
nikita0832, ты можешь сбросить сам файл обработки? Уже два дня мучаюсь не могу толком разобраться… везде только обрывки кода или разные способы, которые не получается довести до ума… Очень хочу с этим разобраться.
(40)ответил в личку
nikita0832, а можно мне тоже пример файла обработки, пжт