Конструктор запроса для 7.7




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

55 Comments

  1. Noy

    Замечательная обработка!

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

    Reply
  2. andrewbc

    идея понятна. проблемка в том, что телефон клиента хранится в одном из трех справочников «ЮрЛица», «СвоиЮрЛица» и «ФизЛица». а в справочнике «Контрагенты» «ЮрЛицо» — это реквизит «Справочник» неопределенного вида. но подумать можно…

    Reply
  3. Noy

    (2) у кого как….;)

    Reply
  4. Ёпрст

    Если Запрос.Выполнить(тз) = 0 Тогда

    {VISUAL QUEST.ERT(1050)}: <<?>>

    Запрос[1] : Пустой запрос

    Reply
  5. Ёпрст

    Добавь возможность корректировки текста запроса.

    Reply
  6. Altair777

    (0) Интересно 🙂

    Мне кажется, что будет удобнее «Текст запроса» и «Результат» разместить на отдельных закладках. И заодно избавиться от слоя «Дополнительный».

    Кстати, вот обнаружил — при двойном клике на переменной запроса и последующем нажатии на «ОК» к имени переменной добавляется «1», хотя ничего не поменялось

    Reply
  7. Арчибальд

    Думаю, что это хорошо. А баги отловятся со временем. 🙂

    Reply
  8. Altair777

    (7) Главное, что бы они не просто отлавливались, а и исправлялись 🙂

    Reply
  9. Свой

    спасибо, красиво, еще бы прямые запросы прикрутить

    как то можно сохранять сконструированные запросы ? а возвращаться в панель настройки после выполнения запроса ?

    Reply
  10. Свой

    «а возвращаться в панель настройки после выполнения запроса ?»

    — снят, это есть в обработке

    Reply
  11. andrewbc

    Ёпрст 03.11.2009 16:10:59

    Если Запрос.Выполнить(тз) = 0 Тогда

    {VISUAL QUEST.ERT(1050)}: <<?>>

    Запрос[1] : Пустой запрос

    это откуда?

    Reply
  12. andrewbc

    Ёпрст 03.11.2009 16:15:35

    Добавь возможность корректировки текста запроса.

    а это правильно

    Reply
  13. andrewbc

    Кстати, вот обнаружил — при двойном клике на переменной запроса и последующем нажатии на «ОК» к имени переменной добавляется «1», хотя ничего не поменялось

    Это отловил. спасибо за баги.

    Reply
  14. andrewbc

    для (6. Altair777) FormEx надо ограничивать. Слишком сильная вещь.

    Reply
  15. andrewbc

    для 6. Altair777

    если что-то изменил, то не гони на разработчика. У МЕНЯ ЗАКЛАДОК НЕ БЫЛО. (учти написно для 1С, а не для С или Delphi)

    Reply
  16. andrewbc

    лучше бы посоветовали где можно структуру запросов 1с-скую найти (чтобы в обратку разобрать)

    Reply
  17. shard

    Не сочтите за рекламу, но более простая (хотя бы в плане оформления и функционала) обработка: http://infostart.ru/public/16692/

    Если же будет желание прикрутить прямые запросы, то могу подкинуть примеров и помочь с идеями по реализации (стучаться в личку).

    Reply
  18. andrewbc

    для «упрощения» выложил еще одну обработку. хотелось покрасивее и поудобнее.

    Reply
  19. boev

    Понравилось,

    при созраннении в ехель дало ошибку,хочет так 🙂

    ПолноеИмяФайла = КаталогИБ()+»select.xls»;

    Reply
  20. Altair777

    (15)

    > если что-то изменил, то не гони на разработчика. У МЕНЯ ЗАКЛАДОК НЕ БЫЛО. (учти написно для 1С, а не для С или Delphi)

    Да, я изменил для себя, добавил закладки, потому что так удобнее

    А я разве где-то гнал? Глюки Вы написали сами, без меня 🙂

    Кстати, может Вы не в курсе… 1С умеет рабоатть с закладками. Хотя она и не С и не Delphi.

    P.S. снял плюс

    P.P.S. А версию Формекса можно было и по-свежее выложить. (в архиве 93, у меня 95)

    Reply
  21. vasilykushnir

    (1) Для этого есть Новейший Отчет 🙂

    Делает практически ВСЕ.

    Reply
  22. Altair777

    (17) > Не сочтите за рекламу, но более простая (хотя бы в плане оформления и функционала) обработка: http://infostart.ru/public/16692/

    вот! Это лучше 🙂

    И редактор текста запроса есть, и закладки.

    Reply
  23. Noy

    (17),(22) Че-то я не разобрался, а как в http://infostart.ru/public/16692/ сделать группировку по Регистр.ОстаткиТоваров.Товар.ТорваяМарка?

    А в (0) можно. Именно это считаю главным достоинством данной обработки.

    Автору респект!

    Reply
  24. Altair777

    (23) хм… в этом ты прав

    Но автору не респект за отношение к критике 🙂

    например, за 15 коммент

    Reply
  25. fAngel

    Можно еще добавить журнал расчетов для более полной картины

    Reply
  26. maloi_a

    Все хорошо, только параметров не хватает.

    Reply
  27. andrewbc

    извинения для Altair777. но я придерживаюсь мнения, что комментировать надо оригинальную разработку, а не измененную. у меня был вариант с закладками, но я их не очень люблю за то, что они убивают свободное место на форме. если монитор у разработчика 22», а у пользователя 15», то нужно это учитывать. хотя это не предмет для спора. кому что нравится.

    Reply
  28. andrewbc

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

    вопрос для (26) Все хорошо, только параметров не хватает. — о каких параметрах идет речь?

    Reply
  29. andrewbc

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

    Reply
  30. Altair777

    (27) Я комментировал оригинальную разработку.

    Или Вы не нашли в ней глюк, описанный в (6)? 😀

    И насколько же процентов закладка уменьшает место? 🙂

    Неплохо бы сделать сохраняемые запросы. Что бы не конструировать их каждый раз, а вызывать из уже ранее сохраненных

    Извинения приняты.

    Reply
  31. andrewbc

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

    Reply
  32. Altair777

    (30) Вот еще глюк:

    В Текст и Результаты попадают только те переменные запроса, у которых выставлен флажок «Группировка». Мне кажется, это не есть хорошо 🙂

    Reply
  33. andrewbc

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

    Reply
  34. andrewbc

    кстати,

    (17) > Не сочтите за рекламу, но более простая (хотя бы в плане оформления и функционала) обработка: http://infostart.ru/public/16692/

    с нее все и началось (спасибо автору за идею), но для меня были нужны 2 вещи:

    — (23) как в http://infostart.ru/public/16692/ сделать группировку по Регистр.ОстаткиТоваров.Товар.ТорваяМарка?

    — для одной переменной назначить несколько объектов конфигурации (номенклатура = регистр.остатки.номенклатура, регистр.партииналичие.номенклатура).

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

    Reply
  35. Altair777

    (33) А если запрос по справочнику делается или по реквизитам документов? Тогда переменные еще ой как несут в себе информацию 😉

    И, как я понимаю цель подобных разработок — это с минимальными потерями времени и не создавая внешних отчетов, получить результат.

    Иначе проще в стандартном конструкторе сделать.

    Вот и хотелось бы иметь действительно универсальный инструмент, не требующий дополнительных усилий для программирования 🙂

    Reply
  36. Altair777

    (34) А это можно и в Описании указать… Выразить благодарность автору за идею 🙂

    Reply
  37. andrewbc

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

    Reply
  38. shard

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

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

    Reply
  39. andrewbc

    с использованием FormEx’а согласен, сам не раз попадал с правами в терминальном клиенте. есть задумка реализовать дерево без ВК. но пока это тестируется как отдельная разработка.

    Reply
  40. andrewbc

    (38) кстати, 1с даже на server 2008 x64 требует полные права на папку с ИБ. поэтому записать туда FormEx.dll не проблема. но с идеей на проверку наличия ВК в папке обработки согласен. будет учтено.

    Reply
  41. andrewbc

    больно удобно и красиво с FormEx’ом… 🙂

    Reply
  42. maloi_a

    (28) Речь идет о параметрах в запросе. В 7.7 это переменная, в 8.0 это &параметр, получающие значение при выполнении запроса.

    Reply
  43. andrewbc

    (42) согласен. работаем.

    Reply
  44. АЛьФ

    2(38) Чушь какая! FormEx (в отличие от других внешних компонент) как раз не требует регистрации в реестре. Уж года два как не требует.

    Reply
  45. Buxxter

    Какой из двух файлов для чего нужен? Какой качать? (Лучше в шапку добавить инфу)

    Reply
  46. andrewbc

    качать первый. второй сейчас убью. это старая версия.

    Reply
  47. brr

    Неплохо бы проверять, что Formex уже загружен.

    Reply
  48. brr

    Пе,Гр,БГ,НО,Пр,Рс,КО,См — расшифруйте. Гр — это группировка, БГ — без групп. А остальное? Пе — надо думать, переменная. А сортировка будет?

    Reply
  49. andrewbc

    (47) а есть смысл? надо проконсультароваться у АЛьФ’а.

    (48) НО — НачОст, Пр — Приход, Рс — Расход, КО — КонОст, См — Сумма.

    с сортировкой — вопрос времени. в перспективе — полный синтаксис 1с-запроса (по возможности).

    Reply
  50. raider-rec@ya.ru

    +1 Мне понравилось! Пригодицца когда нибудь. Спасибо!

    Reply
  51. sanches

    Неплохо было бы при открытии делать проверку на то, что FormEx уже загружен. А то получается, что он у меня при запуске базы подгружается, а когда запускаю отчет, то выдает что нельзя загрузить Formex и закрывается, при этом в окне сообщений пишет что он уже загружен

    Reply
  52. Abadonna

    (51)>делать проверку на то, что FormEx уже загружен. А то получается, что он у меня при запуске базы подгружается.

    Вот как раз и не надо! 😉 Ежели уж есть FormEx, то и надо его использовать на всю катушку, т.е. как раз и грузить вначале.

    А из обработки ЗагрузитьВнешнююКомпоненту убрать вообще.

    Reply
  53. andrewbc

    (51) это сделано в новой версии. но она пока в отладке и не выложена. пока можно внести исправления вручную:

    Процедура ПриОткрытии()

    Попытка

    Тест = СоздатьОбъект(«Сервис»);

    Тест = «»;

    Исключение

    Если ЗагрузитьВнешнююКомпоненту(«FormEx.dll») = 0 Тогда

    Предупреждение(«Невозможно загрузить внешнюю компоненту FormEx.dll.

    |Выполнение обработки прервано.»);

    СтатусВозврата(0);

    Возврат;

    КонецЕсли;

    КонецПопытки;

    ……….

    КонецПроцедуры

    Reply
  54. Alex_Smolensky

    супер! (+)

    Reply
  55. GSoft

    единственно я бы добавил проверку загрузки Formex

    у многих файл библиотеки не лежит в корне ИБ

     Попытка
    Сервис = СоздатьОбъект(«Сервис»)
    Исключение
    //Formex не загружен
    Если ЗагрузитьВнешнююКомпоненту(«FormEx.dll») = 0 Тогда
    Предупреждение(«Невозможно загрузить внешнюю компоненту FormEx.dll.
    |Выполнение обработки прервано.»);
    СтатусВозврата(0);
    Возврат;
    КонецЕсли;
    КонецПопытки;

    Показать

    Reply

Leave a Comment

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