Вытаскиваем метаданные из буфера обмена 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='\

29 Comments

  1. Oleg_nsk

    Познавательно. Но зачем это может понадобиться? Не могли бы в начале обозначить спектр задач где ваши научные исследования структуры буфера обмена 1с могут пригодится простому разработчику.

    Reply
  2. ilov_boris

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

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

    Я не предлагаю конкретное решение, а только лишь показываю как это работает и как это можно использовать.

    Reply
  3. sytkosa

    В снегопате можно использовать такую схему. там как раз не хватает такого плана скриптов.

    Reply
  4. tango

    (3) 8SiriuS8, тут фишка как раз в том, что снегопат может покурить

    Reply
  5. sstar90

    Плюс. Надо попробовать для общего развития

    Reply
  6. orefkov

    (3)

    В снегопате это делается так:

    Код
    var file = metadata.current.rootObject.childObject("Документы", "АвансовыйОтчет").saveToFile()
    file.seek(0, fsBegin)
    Message(file.getString(dsUtf8))
    

    Показать полностью

    и все.

    Reply
  7. orefkov

    (4)

    А курить я больше года как бросил 🙂

    Reply
  8. vec435

    а если на основе Clcl сделать ВК то и использовать можно как снегопат

    Reply
  9. ilov_boris

    (8) vec435, ВК — это уже режим предприятия (да и зависимость от оного). А Снегопат и скрипты на Lua позволяют получить профит находясь в конфигураторе.

    ВК и обработку несущую такой функционал конечно можно сделать, но это будет дико неудобно.

    Reply
  10. ilov_boris

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

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

    зы И еще… могу описать более подробно как установить и использовать Lua в связке с Sublime Text 2.

    Reply
  11. orefkov

    (10)

    Из идей — прикрутить это к autoit (где-то тут был на нем мини опенконф для восьмерки)

    Reply
  12. orefkov

    И кстати да, в (6) описано было, как получить то, что в первой части статьи — внутреннее представление.

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

    Reply
  13. ilov_boris

    (11) orefkov, возможно я ошибаюсь, но в autoit вроде только текст из буфера обмена можно вытащить…

    Reply
  14. ilov_boris

    (11) «где-то тут был на нем мини опенконф для восьмерки»

    Покажите где оно лежит плиз. Интересно однако 🙂

    Reply
  15. orefkov

    (13)

    Ну так потом можно текст как-то обработать, поместить в буфер и послать контрол v

    (14)

    http://infostart.ru/public/65526/ здесь упоминается

    Reply
  16. vec435

    при копирование объектов из конфы в конфу по Cntr+C копируется целиком объект.значит из буфера можно по-идее все вытащить.что-то вроде UnPack может получится прямо из конфигуратора. а обработать удобнее в предприятии.

    Reply
  17. orefkov

    Кстати, посмотрел, что лежит в «1C:MD8 External Data»

    Если преобразовать из base64, получим текст модуля документа, в формате, понимаемом v8unpuck.

    Но мне вот что интересно.

    Если я в одной конфе нажал Ctrl+C допустим на документе, а в другой Ctrl+V, то док вставляется весь — все формы, модули и т.п. Но в клипборде я что-то не вижу этой инфы, а только структуру метаданных, да модуль дока. Откуда это передается?

    А если я скопировал док, а в другой конфе встал на узел «Последовательности» и нажал Ctrl+V, то добавляется новая последовательность, с именем как у дока, а реквизиты дока стают измерениями последовательности.

    Reply
  18. orefkov

    +(17)

    Хотя нет, погорячился насчет того, что в «1C:MD8 External Data» только модуль документа. Невнимательно я декодировал. Там для всех вложенных объектов метаданных все лежит в таком же 1Сном фигурном списке. Все формы, модули и т.д. и т.п. Над

    Reply
  19. ilov_boris

    (18) Хотел уже было ответить вам, но вы меня опередили 🙂

    Да, там все есть. И про модуль в External Data я знаю.

    Кстати можно сделать скрипт, который выведет отчет по назначенным обработчикам в модулях объектов. (ПриЗаписи, ПередУдалением и т.д. и т.п.) На Lua с ее строковой либой должно быть элементарно. 🙂

    Reply
  20. ilov_boris

    Посмотрите еще как «Роли» закодированы. Забавно там 🙂

    Использовать парсер писанный на 1С для такого объема уже не айс.

    Reply
  21. orefkov

    (19)

    Обработчики умеешь получать и для толстых и для упр форм?

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

    Reply
  22. ilov_boris

    (21) orefkov, не знаю 🙂 нужно пробовать

    Reply
  23. oberon355

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

    Reply
  24. alexandr1972_1

    Очень интересно, особенно в плане использования Lua. Поставим в закладки, потом разберёмся.

    Reply
  25. CaSH_2004

    Занятно, из областей применения возможно подойдет такая задача: тут встречалась задача что нужно новую обработку конвертировать из 8.2 в 8.1 или даже 8.0, предложено было решение копировать из конфигуратора 8.2 в конфигуратор 8.1/8.0, однако иногда были проблемы при переносе копированием, по всей видимости из-за разной структуры. Этот механизм мог бы помочь решить данную проблему, но по сути проще самому все нарисовать чем все изучить и запрограммировать.

    Интересно, а обратного конвертера так никто и не придумал? Может UnPack справиться?

    Reply
  26. AnryMc

    ??? ЗначениеВСтрокуВнутр ???

    Reply
  27. ilov_boris

    (26) AnryMc, что? O_o

    Reply
  28. AnryMc

    (27) ilov_boris,

    Половина описаной работы решается этим

    Reply
  29. ilov_boris

    (28) AnryMc, какая половина и каким образом?

    ps … или вы просто потроллить заглянули? 😉

    Reply

Leave a Comment

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