Полезные процедуры по работе с СКД и табличными документами (часть 2)




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

    Выровнять заголовки по центру можно вообще без кода при помощи условного оформления.

    Reply
  2. json

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

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

    Reply
  3. soulsteps

    В этой процедуре

    Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)

    СтандартнаяОбработка = Ложь;

    ОчиститьСообщения();

    // 1

    ТекущееПодразделение = ПолучитьЗначениеПоИмениГруппировкиВРасшифровке(

    «Подразделение»,

    ДанныеРасшифровки,

    Расшифровка);

    Сообщить(«Подразделение : » + ТекущееПодразделение);

    // 2

    ПоляРасшифровкиВВидеТаблицы = ПолучитьПоляРасшифровкиВВидеТаблицы(

    Расшифровка,

    ДанныеРасшифровки);

    Для Каждого Строка Из ПоляРасшифровкиВВидеТаблицы Цикл

    ТекстСообщения =

    «Уровень: » + Строка.Уровень + «; » +

    «Поле: » + Строка.Поле + «; » +

    «Значение: » + Строка.Значение + «; «;

    Сообщить(ТекстСообщения);

    КонецЦикла;

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

    не обнаружил передачу (локальное определение) переменной ДанныеРасшифровки? Хотя идет обращение по коду:

    ТекущееПодразделение = ПолучитьЗначениеПоИмениГруппировкиВРасшифровке(

    «Подразделение»,

    ДанныеРасшифровки,

    Расшифровка);

    Обработку не скачивал, смотрю только код. Если это какая-то глобальная переменная или параметр формы, просьба уточнить, возможно ДанныеРасшифровки = Расшифровка?

    Reply
  4. json

    (3) soulsteps,

    Расширение формы отчета (Report form extension)

    ДанныеРасшифровки (DetailsData)

    Использование:

    Чтение и запись.

    Описание:

    Тип: ДанныеРасшифровкиКомпоновкиДанных.

    Содержит данные расшифровки последнего выполненного отчета.

    Доступность:

    Толстый клиент.

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

    Reply
  5. soulsteps

    (4) я это и хотел услышать (уточнение))

    Reply
  6. Поручик

    (0) Не обращай внимания на критиканов.

    Reply
  7. PrinzOfMunchen

    Недавно писал нечто подобное, описанному в первом примере. Только мне надо было получить ВСЕ значения полей группировки и детальных записей (без ресурсов) в виде плоской таблицы, где колонки — это выбранные поля. Знатные извращения…))

    Reply
  8. Nuuq

    А есть пример по образу сделать получение области итогов СКД по вертикали и общие по горизонтали — программно добавить туда новое поле и заполнить его?

    Reply
  9. Yashazz

    Забавно. Тоже буквально вчера понадобилось выгрести значения текущей расшифровки, всех полей уровня и, естесссно, родительских группировок. Тоже сделал через таблицу значений. Подумывал сериализовать «ДанныеРасшифровки» и поиграться с её xdto, но там не оказалось ничего интересного. Остальное — тоже, в общем, очевидные вещи.

    Автор прав, пост-обработка это зло. Но иногда зла не хватает)) Могу от себя добавить, что ввиду непредсказуемости внешнего вида результатного табличного документа делаю такие пост-обработки, привязываясь к специально заданным расшифровкам, перегоняя моксель в его сериализованный вид xml и орудуя уже в нём. Так хоть меньше шансов обломаться, если юзверь перенастроит СКД. Так что рекомендую отказаться от дикости вроде «ВысотаТаблицы» и работать через xpath или объекты DOM. Ей-ей, надёжнее)

    Reply
  10. rasswet

    спасибо, интересные вещи.

    Reply
  11. German_Tagil

    спасибо

    Reply
  12. Makushimo

    Спасибо, так держать

    Reply
  13. AzagTot

    Спасибо! Очень полезный цикл статей.

    А кто знает как можно сдвинуть таблицу на несколько колонок? Чтобы вывод начинался не с первой колонки, а, например, с 3-й. При этом другие таблицы в отчете должны остаться без изменения.

    Reply
  14. ol_xak

    (3)А ведь вопрос был правильный

    Reply
  15. json

    (14) ответил же на вопрос. Или ответ не понятен?

    В управляемых формах есть реквизит формы ДанныеРасшифровки, в котором хранится адрес во временном хранилище, а в обычных формах в этом реквизите хранятся сами данные

    Для обычных форм:

    // 1
    ТекущееПодразделение = ПолучитьЗначениеПоИмениГруппировкиВРасшифровке(
    «Подразделение»,
    ДанныеРасшифровки,
    Расшифровка);
    

    Для управляемых:

    // 1
    ТекущееПодразделение = ПолучитьЗначениеПоИмениГруппировкиВРасшифровке(
    «Подразделение»,
    ПолучитьИзВременногоХранилища(ДанныеРасшифровки),
    Расшифровка);
    
    Reply
  16. ol_xak

    (15) Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)

    откуда в данной процедуре появляется переменная ДанныеРасшифровки

    Reply
  17. json

    (16) читайте внимательно предыдущее сообщение. Там все разжевано.

    В управляемых формах есть реквизит формы ДанныеРасшифровки
    Reply
  18. ol_xak

    (17)А в обычной форме? Я не критикую, просто пытаюсь использовать предложенный метод, но не получается. Где взять ДанныеРасшифровки в процедуре РезультатОбработкаРасшифровки? Использую неуправляемую форму обработки.

    Reply
  19. json

    (18) по обычной форме цитата из справки


    Расширение формы отчета (Report form extension)

    ДанныеРасшифровки (DetailsData)

    Использование:

    Чтение и запись.

    Описание:

    Тип: ДанныеРасшифровкиКомпоновкиДанных.

    Содержит данные расшифровки последнего выполненного отчета.

    Доступность:

    Толстый клиент.

    Показать

    То есть расширение формы отчета имеет такой реквизит ДанныеРасшифровки. В форме отчета он есть по умолчанию (если основной реквизит формы — внешний или внутренний отчет).

    Разница между параметрами Расшифровка и ДанныеРасшифровки следующая:

    в ДанныеРасшифровки — хранятся данные по всему сформированному отчету

    в Расшифровка — хранится ключ, по которому можно искать в ДанныеРасшифровки. Этот ключ хранится в значении ячейки, по которой кликает пользователь

    Reply

Leave a Comment

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