Регламентное выполнение внешних обработок с параметрами (при помощи СКД) без изменения конфигурации (на примере УТ 11)




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

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

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

<?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='\

19 Comments

  1. Ibrogim

    Жду комментариев и/или конструктивной критики )

    Reply
  2. pumbaE

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

    Reply
  3. Ibrogim

    (2) pumbaE, Скажите как? может действительно есть. Ключевой момент, должна быть возможность настройки параметров

    Reply
  4. pumbaE

    (3) вопрос снимается, т.к. если судить по теме, то вам необходимо было регламентное выполнение внешних обработок — это делается без проблем, если говорить про сохранение настроек, то тоже делается без проблем, т.к. можно сохранить из формы по определенному адресу структура с настройками, потом в фоновой задаче восстановить.

    Если про рассылку отчетов, то используя типовые средства трудно сделать произвольную настройку.

    Reply
  5. Ibrogim

    (4) pumbaE, Задача именно в том, чтобы быстро сделать из существующей обработки фоновую, с возможностью настройки параметров интерактивно. т.е. не обязательно рассылка.

    Reply
  6. pumbaE

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

    Reply
  7. Ibrogim

    (6) pumbaE, Ваше предложение вполне будет работать но

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

    Каким образом пользователь будет настраивать расписание с разными настройками?

    Reply
  8. pumbaE

    (7) для различных настроек — это не подойдет. Можно, конечно сделать для себя соглашение, что команда будет равна названию настройки и тогда можно вручную прописывать, но это больше админ.решение, чем пользовательское.

    Reply
  9. wolfsoft

    Плюсанул за идею.

    Reply
  10. the1

    (0) Все хорошо, но где найти эту рассылку отчетов? В БП 3.0 в органайзере только настройка электронной почты…

    Reply
  11. Ibrogim

    (10) the1, Вероятно в БП3 нет этого функционала. Мне известно что он есть в УТ11 и ERP

    Reply
  12. the1

    (11) вероятно не помешает указать о существенных ограничениях применимости данной методы в публикации? 😉

    Reply
  13. Ibrogim

    (12) the1, Вы правы, хотя я нигде и не писал что это подойдёт для всех конф.

    Дописал

    Суть заключается в использовании стандартного механизма рассылки отчётов. Внимание, этот механизм есть не во всех конфигурациях, например его нет в БП.
    Reply
  14. maxis33

    (10) the1, я внедрил эту подсистему из БСП в БП 3.0 — оказалось очень легко, фактически перенес несколько общих модулей, справочник и регистр сведений и подсистему. Все работает.

    Reply
  15. Ibrogim

    (14) maxis33, Буду знать. Однако в этом случае теряется фишка «без изменения конфигурации»

    Reply
  16. Mitrill

    (1) А как вывести в поле «Настройки отчета» реквизит типа СпискаЗначений, чтобы можно было задавать несколько значений? Спасибо

    Reply
  17. Ibrogim

    (16) Просто в СКД поставить галочку Доступен список значений. В процедуре ПриКомпоновкеРезультата там где Преобразуем параметры скд в реквизиты обработки

    Вставить

    Если ИмяПараметра=»СписокАдресовРассылки» Тогда
    Если ТипЗНЧ(ЭлементПараметров.Значение) = Тип(«СписокЗначений») Тогда
    СписокАдресовРассылки=ЭлементПараметров.Значение.Скопировать();
    Иначе
    СписокАдресовРассылки.Очистить();
    СписокАдресовРассылки.Добавить(ЭлементПараметров.Значение);
    КонецЕсли;
    
    
    
    КонецЕсли;
    

    Показать

    Reply
  18. Mitrill

    А какой здесь имеется ввиду тип в ветке «Иначе»? Если он не «СписокЗначений», то возможно у него нет методов «Очистить» и «Добавить».

    Reply
  19. Ibrogim

    (18)СписокАдресовРассылки это реквизит обработки с типом список значений. Если в СКД соответствующий параметр заполнен списком значений, то я копирую его значения. если нет, то просто очищаю.

    Reply

Leave a Comment

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