Парсировщик (НОВЫЙ инструмент для изучения метаданных + загрузка предопределенных значений из табличного документа)




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

29 Comments

  1. artbear

    Молодец! Уже за идею плюсую

    Reply
  2. German

    а может вот так ?

    1. Загрузить элементы

    2. Изменить им свойство предопределенности?

    http://main.1c-ei.ru/Articles/ismeta

    так что преимущество под сомнением 🙂

    Reply
  3. bambr1975

    (2) Пальму первенства отбирать не собираюсь. Копаем одно и то же, в разное время и в разном месте. Спасибо за проявленный интерес. Большая честь! 🙂

    Reply
  4. detec

    На 64-битной ОС пишет, что не может найти библиотеку zlibeng.dll. Я её регистрировал и в c:WindowsSystem32, и в c:WindowsSysWOW64\r

    А вообще просьба всем тем, кто использует разного рода внешние компоненты в разработках. Тестируйте свои творения под 64-битными ОС. Мир не ограничен узкими окошками 32-битной XP SP2-3. Куча разработок с Инфостарта у меня полетела в мусорку, т.к. не была реализована корректная работа на 64 битах.

    Reply
  5. mozz

    Автору респект и уважуха!

    Reply
  6. bambr1975

    (4) Выложил новую версию. Ошибка повторяться не должна.

    Reply
  7. andrewbc

    Извиняюсь, но вообще не работает в режиме управляемого приложения под 8.2. Пора бы уже это учитывать. (Это в добавку к (4)).

    Reply
  8. bambr1975

    (7) Возможно, позже сделаю.

    Reply
  9. mevgenym

    оч хорошо сделано, правда хотел поломатую конфу восстановить, не получилось, но эт неважно

    Reply
  10. karbofos

    Нужная вещь. Беру на вооружение. Автору респект.

    Reply
  11. CaSH_2004

    Подскажите страждущему О ИСКУШЕННЫЕ КОВЫРЯЛЩИКИ ВНУТРЕННОСТЕЙ, есть ли какой способ (желательно без танцев с бубном в полнолуние в 13-ю пятницу 13-го числа, если такое бывает) чтобы можно было в обычную обработку (epf) засунуть двоичные данные не заходя в конфигуратор, как например все делают с макетом в конфигураторе — засовывают разные компоненты и другие файлы. Есть потребность но не вижу инструмента, на 7-ке вроде встречал но сейчас (во всяком случае хранение и распаковка как в 1С8) но уже не хочется бедную лохматить.

    Отзовитесь О МОГУЩЕСТВЕННЫЕ!!!

    Reply
  12. svvinks

    (11) CaSH_2004, Без бубна — это обработку записать в дополнительные обработки и прилепить к ней макет в виде параметра

    Reply
  13. CaSH_2004

    (12)Это ты про что? Я хочу в одной обработке все хранить в виде макетов или еще чего, а ты про конфу что-ли?

    Reply
  14. bissov

    Это очень круто, спасибо!!!

    Reply
  15. Rustig

    (0) попробовал распаковать базовую версию, добавить предопределенный элемент, далее запаковать файлы в конфу: получилось. Только не понимаю, остается ли базовая версия от таких манипуляций «базовой»? И почему, считается, что «базовые» конфигурации нельзя редактировать, если можно «включить возможность изменения» через настройку поддержки? вопрос скорее организационно-юридический, чем технический. и все же не понимаю — можете прокомментировать? заранее спасибо.

    Reply
  16. bambr1975

    Разработка «Парсировщика» носила экспериментационный характер. Всерьез я ничего редактировать таким образом не рекомендую.

    Касательно отличий «базовых» версий КОНФИГУРАЦИЙ от «ПРОФ» есть отличный материал — http://infostart.ru/public/98417/

    В любом случае — главное отличие этих версий от версий «ПРОФ» в другом строении форм — наверное, именно этим и обеспечивается их монопользовательский режим.

    А «включить возможность изменения» в случае наличия у Вас «базовой» ПЛАТФОРМЫ все равно не получится — этот пункт меню будет заблокирован.

    Reply
  17. Rustig

    (16) Спасибо большое за ответ! Нашел ответы на свои вопросы. 🙂

    Reply
  18. Kaperang

    А как закачать предопределенные значения? Копался полчаса, так и не нашел.

    Reply
  19. Kaperang

    Вроде нашел. Если у объекта уже есть предопределенные значения, в дереве метаданных у этого объекта уже отображается раздел «Предопределенные». Можно запустить форму просмотра и загрузки предопределенных значений выбрав этот пункт. А как быть, если у объекта нет предопределенных значений и соответствующего раздела в модуле?

    Reply
  20. bambr1975

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

    Reply
  21. Kaperang

    Коллега, я снова к Вам с поклоном… 😳

    В прошлый раз Вы мне сформулировали паттерн имени объекта следующего вида «{d,[d]+,w{8}-w{4}-w{4}-w{4}-w{12}},»»(S+?)»»,


    Теперьмне нужно сформулировать паттерн синонима объекта. Пример текста для изменения:

    «{1,

    {47,314e75be-9c96-4a70-a5fb-f73d37e7306f,5e66eea4-01d2-497a-9769-07c9207a4dde,de2fb776-fa0b-4bb3-a39f-f77b7cba2605,f12f2c3d-cb90-439f-8a2c-cb4556571835,2e22d328-007d-41e2-a237-73afc542b898,93f7a53d-21bc-40a9-9026-f5d3dee901ce,4c2e70c5-c785-47b6-bf54-d6f8e2263b15,bcae4342-d29a-4958-8d80-463ca084a4b3,

    {0,

    {0,

    {0,0,961f1aa0-9c85-4fd3-b49a-c081a737f64a},»ааАвтомобили»,

    {1,»ru»,»Автомобили»},»Автомобили»}

    },2,1,

    »

    Не поможете по старой памяти?

    Reply
  22. bambr1975

    (21) Kaperang — с церемониями Вы явно переборщили

    {d,[d]+,w{8}-w{4}-w{4}-w{4}-w{12}},»»S+?»»,
    ?{d+(,[#k8SjZc9Dxk,]*,»»([#k8SjZc9Dxk»»]*((«»»»)?[#k8SjZc9Dxk»»]*(«»»»)?)*[#k8SjZc9Dxk»»]*)»»)*}

    Срабатывает на сложные многоязычные синонимы с множественными кавычками

    Искать Match.SubMatches(1) (если синоним многоязычный — нужен доп. цикл для разбора Match.SubMaches(0) — иначе в результат попадет последний найденный — но обычно язык один — этого достаточно для нахождения)

    Reply
  23. Kaperang

    Спасибо, помогло!

    Правда выскочил забавный баг: параллельно изменились тексты интерфейсов — везде проставился префикс.

    Причем, файлик, где хранится сама структура интерфейса, вроде как не затрагивается. Правится только «файл заголовка».

    Теоретически названия пунктов меню должны были взяться из этого файлика, т.е. без префиксов. Ан нет, в меню «ааНоменклатура», «ааКонтрагенты» и т.д.

    В итоге, подправил через «Групповой поиск и замену».

    Reply
  24. p_kuzmichev

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

    Reply
  25. p_kuzmichev

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

    Reply
  26. bambr1975

    (25) p_kuzmichev, если вы загрузите полученную конфигурацию в пустую базу — изменения там будут. У Вас изменения не отобразились, потому что Вы просто накатили полученную конфигурацию на такую же, с теми же идентификаторами версий объектов. А таблица versions у меня не меняется… Поэтому при сравнении (а сравниваются версии объектов, а не их внутреннее представление) ничего не показывает. Парсировщик — не хирургический инструмент. Это скорее, просто инструкция к внутреннему представлению файлов 1С.

    Reply
  27. Madj

    (26) можно ли каким-то образом изменять таблицу versions, чтобы видеть внесенные изменения?

    (25) p_kuzmichev, можно загрузить конфигурацию после упаковки в пустую базу, затем воспользоваться «Выгрузить конфигурацию в файлы». И опять же в пустую «Загрузить конфигурацию из файлов» — это покажет изменения, но загрузка таким образом может добавлять свои изменения, например, в ролях. Изменения модей объектов и модулей формы показывает корректно.

    Reply
  28. bambr1975

    >можно ли каким-то образом изменять таблицу versions, чтобы видеть внесенные изменения?

    (27) Madj, поправочка — не таблицу versions, а внутренний файл versions (ну, с кем не бывает).

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

    Reply
  29. Bac3

    Большое спасибо!

    Нашел ошибку в своей конфигурации. Исправил

    Была ошибка «нарушена целостность структуры конфигурации».

    Оказалось что не хватало файла для объекта метаданных перечисления.

    Распаковал рабочую базу и взял оттуда скопировал в эту.

    Упаковал обратно и все норм стало!

    🙂

    Reply

Leave a Comment

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