Прямые запросы 1спп с наложением фильтров




Принцип обмена данными из 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='\

37 Comments

  1. Ёпрст

    Есть QA

    Есть Консоль и Конструктор от Berezdetsky

    Reply
  2. Ёпрст
  3. dav405

    1,2) Подскажите, как в QA отобрать по конкретной группе номенклатуры?

    А консоль отчетов — вообще супер, вот только там я тоже не разобрался, как втыкать конкретные значения из базы.

    Вообще все началось с этих долбаных акций. Ну чего писать что-то отдельное, когда запрос набросать две минуты? А фильтр держать в мф.

    Reply
  4. CheBurator

    и есть еще отдельный класс МФ, который реализует типовой МФ

    Reply
  5. JohnyDeath

    (4) фигасебе! Че, ты стал классами пользоваться? ;))))

    Reply
  6. dav405

    (4) Спасибо, только фильтр нифига нетипофой. Лучше бы плюс поставил, мне не хватает 3 плюса и никто не дает. Вот, например, вместо того, чтобы воткнуть хорошую и красивую печать ТЗ от Че. которую не могу скачать сегодня, поставил плохую и ужасТную свою.

    А вообще, видимо буду доводить, жуть как удобно получается для ответов на редкие вопросы.

    Reply
  7. CheBurator

    (5) А ты думал!!! у меня уже один класс месяца три вертится! Но как всегда — руки у изготовителей кривые — пришлось допиливать по мелочи… и то одна ошибка выскакивает все время…

    Reply
  8. Donat

    Сделаешь свободный доступ, поставлю плюс 🙂

    Хотя, ладно, авансом…

    Reply
  9. dav405

    (9)Йееес.

    А я сначала в свободный поставил — без энтузазизма восприняли. Тем более надобно доводить все равно до ума. Заторопился. бо сама идея парсить переменные для фильтра (да и типы) прямо из запроса меня утром очаровала, аж невтерпежж.

    (8) http://www.infostart.ru/projects/386/

    Да,были люди в наше время…. Буду посмотреть

    Reply
  10. CheBurator

    (10) по (8) отпишись по факту внедрежа

    Reply
  11. vandalsvq

    (7) один класс… три месяца… хотя уже хорошо ))))))))))

    Автору плюс за разбирательство с прямыми запросами. 😉

    Reply
  12. artbear

    (7) У меня порядка 100 классов в свое время крутилось, и на некоторых зарплатных и бухгалтерских базах до сих пор крутится.

    ЗЫ некоторые классы совсем простые и маленькие, но свое дело делают 🙂

    Reply
  13. rasswet

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

    Reply
  14. rasswet

    РекордСет.УложитьСписокОбъектов(Эл,Пар,Вид);

    {QUERY1CPPANDMFЗАПРОСПП_С_МФ.ERT(143)}: База данных не установлена

    запустил, на множ фильтре очистил, тип указал справочник. хз что она ещё хочет. видимо для продвинутых.

    Reply
  15. dav405

    (15) Значения для фильтра выбери, либо убери # и поставь — в начале строки, тогда будет по всем отбирать.

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

    Reply
  16. rasswet

    (16) да ничего не получается. да не парься. фиг с ним.

    Reply
  17. dav405

    (17) А сейчас?

    Reply
  18. rasswet

    (18) хз где там ставить —. нет так нет. обожаю обработки в которых открываешь и нажимаешь сформировать и видишь хоть какие-то данные. а те где сначала надо заполнить 25 параметров причем хз как и без установки хоть одного не взлетает, такие в топку.

    Reply
  19. dav405

    Забудь про прямые запросы, там многабукф )

    Reply
  20. dav405

    (19) Не мог спать спокойно, добавил работу с ДБФ (! немонопольно)

    Reply
  21. rasswet

    (21)это в который файл? их три. и какой о чем не понятно(

    Reply
  22. dav405

    (22) Главный — первый файл. Второй — просто вывод таблицы результата на печать -необязателен. Третий — таблица примеров запросов. В Твоем случае, она все равно не сработает, потому что под скуль. Т.е. тебе, чтобы посмотреть хоть какой-то результат надо скачать первый файл, проставить на машину фоксовые дрова (vfpoledb), и написать в поле ввода (большое такое) что-то вроде sel ect * from $Справочник.Номенклатура, после чего нажать «Сформировать». А потом могешь более эксперементировать с запросами и результатами. Когда нажимаешь «сохранить» — запрос запоминается под именем, которое в «описании», т.е. можно по-очереди делать и проверять запросы, сохраняя их историю. //Черновики потом удаляешь. Я-то прикололся, но подозреваю, что интерфейс жутко кривой :).

    После того, как запрос нравится — нажимаешь копипаст — и из окна сообщений копируешь текст запроса в код «настоящей» обработки.

    Reply
  23. rasswet

    3, 0, 1, 22

    ОлеДБ.ПрисоединитьИБ(КаталогИБ());

    {F:\_С ИНЕТАЗАПРОСПП_С_МФ2.ERT(180)}: FAILED! IDataInitialize::GetDataSource(): Класс не зарегистрирован

    это из-за дров фоксовых?

    Reply
  24. Ёпрст

    (24) Эту строчку нужно заремить..

    + нет строки подключения для дбф..

    + весьма забавный метод определения , что это файловая версия (при наличии спец. метода в самой компоненте)

    Короче, в дбф не работает.

    Reply
  25. dav405

    (25) Уважаемый будет смеятся, однако работает.

    (24) да, после установки должно заработать.

    (25)+ Канэшно забавный, а вай нот, дело то в том, что версия мне понадобилась попозжее, ну и номер версии — если видишь, определяю странно, потому как в том 1срр, который у меня сейчас метод «версия()» возвращает непойму что. А теперича они(1срр) по умолчанию втыкают строку для подключения к текущей базе. Мало того, насколько я понимаю, (по изменяющейся документациина 1cpp.ru) авторы работают над поддержанием уложитьсписокобъектов() для дбф.

    Reply
  26. Ёпрст

    (26) Работает, но медленно, ибо строка подключения в методе ПрисоединитьИБ устаревшая..

    Reply
  27. Ёпрст

    >>>который у меня сейчас

    Это какой ?

    3.0.1.23 если что пользуй.

    Reply
  28. rasswet

    ругнулось на

    ИмяФайлаТЗ=СписокСохраненныхТаблиц.ПолучитьЗначение(лТекПоз,);

    {N:СИНЕТАЗАПРОСПП_С_МФ2.ERT(318)}: Индекс не входит в границы списка значений.

    Reply
  29. rasswet

    на закладку множ фильт не переходит 29-ошибка.

    но после установки фоксовых дров заработало. теперь можно дальше думать..что с этим делать))

    залил

    http://narod.ru/disk/13204508000/VFPOLEDBSetup.msi.html -фоксовые дрова

    кому надо не ищите по инету. качайте по ссылкам

    3.0.1.23 тут http://narod.ru/disk/13204616000/Icpp-latest-3.0.1.23.rar.html

    Reply
  30. rasswet

    сделал конструктором запрос

    SEL ECT $АвансовыйОтчет.Сотрудник [Сотрудник $Справочник.Сотрудники]

    , $АвансовыйОтчет.ПриложеноДок ПриложеноДок

    , $АвансовыйОтчет.НаименованиеАванса НаименованиеАванса

    FROM $Документ.АвансовыйОтчет AS АвансовыйОтчет

    не сработало. а есть какой-то конструктор, которым можно запросы делать и в эту твою штуку вставлять?

    пробовал http://infostart.ru/projects/1081/ этим делать

    Reply
  31. dav405

    (27) Ну, может медленно, у меня-то и клиентов на дбф не осталось, не гонял.

    (30) Сохрани запрос — должен создавать таблицы,(в т.ч. и мф), но да, поправлю проверку.

    Reply
  32. dav405

    (31) Глянь в той теме http://infostart.ru/projects/1081/ 4-й коммент от JonniDeath

    Reply
  33. dav405

    (31)+ Там, кстати выдернутые запросы из кода можно втыкать, потом кнопка копипаст — делает две версии — в поле ввода убирает «|», в окне сообщений — наоборот добавляет.

    Конечно уродство, но удобно.

    Reply
  34. dav405

    (27) Она еще и casesensitive, блин. Поменяю.

    Reply
  35. rasswet

    (32) сохрани запрос-это не понял. (33) с AS понял. работает!

    копипаст-тоже понял.

    SEL ECT $АвансовыйОтчет.Сотрудник AS [Сотрудник $Справочник.Сотрудники]

    , $АвансовыйОтчет.ПриложеноДок AS ПриложеноДок

    , $АвансовыйОтчет.НаименованиеАванса AS НаименованиеАванса

    FROM $Документ.АвансовыйОтчет AS АвансовыйОтчет

    это работает.

    на закладку всё равно не переходит. буду копипастить из конструктора.

    in (sel ect val from #myTemp) это мне тогда не надо?

    табл с рисунка 6406 не выводит. выводит в виде ТЗ.ВыбратьСтроку()

    Reply
  36. dav405

    (36) Там кнопка Добавить/обновить — она сохранят текст запроса в файл для дальнейшего использования, она же должна создавать МФ.

    #MyTemp в дбф пока не работает

    Табл с рисунка получается, если в каталог обработки положить второй файл (ПечатьТЗ2.ert)

    С датой из общего журнала, смотрю пока неудобненько, переделаю завтра, чтобы для дбф клал дату по-другому.

    Reply

Leave a Comment

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