<?php // Полная загрузка сервисных книжек, создан 2025-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='\
А чем не устраивает комментарий у отчета?
По моему скромному мнению, лишние поля в схеме — не есть гут. Все равно все отчеты, которые есть — не подпишешь. Обязательно найдутся пользователи, которым ваш заголовок будет мешать. Самый лучший способ — самодокументируемое название отчета в дереве метаданных. См. Рекомендации по именованию метаданных на ИТС
(1) yurii_host,
Про дерево метаданных наши заказчики даже не слышали )) и конечно, название там не может быть подробным, не может включать значения параметров в удобочитаемой форме.
А как обстоят дела с производительностью такого подхода? Замечал, что если включать такие поля (без данных из набора данных, просто с служебной информацией), то время выполнения увеличивается, возможно запрос набора данных выполняется 2 раза.
Производительность не пострадает, а вот эстетика — да ))
Я бы формировал заголовок программно (ПриКомпоновкеРезультата).
(4) papche,
Тоже хороший вариант. Но чуть сложнее.
(4) papche, если сбросить СтандартнуюОбработку, то фоновое выполнение отчета придется реализовывать руками.
(4)
Увы, такое не прокатит для подключаемых к БСП отчетов, не имеющих собственной формы отчета
(7) Cyberhawk, кто сказал? На сколько я знаю, метод модуля отчета «ПриКомпоновкеРезультата» выполняется всегда.
С другой стороны, всегда можно вывести заголовок с помощью макета. Я обычно так и делаю: заголовок из макета, остальное из схемы.
(6) Evil Beaver, а и не надо сбрасывать флаг стандартной обработки без необходимости
(7) Cyberhawk, а Вы попробуйте, удивитесь, но работает и без собственной формы ))
Вот рабочий код, выводит заголовок с использованием параметра «Период» типа стандартный период
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
ЗначениеПериода = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(«Период»)).Значение;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Настройки.ПараметрыВывода.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(«Заголовок»)).Значение =
«Дата начала: «+Строка(ЗначениеПериода.ДатаНачала) + «. Дата окончания: «+Строка(ЗначениеПериода.ДатаОкончания);
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных,);
КонецПроцедуры
(8) starik-2005, а это как, можно поподробнее?
(0)
Пара вопросов:
1. А что будет если параметр является необязательным и он не установлен?
2. Необходимо добавить вычисляемое поле в группировку? Думаю, будет не лишним указать, что в этой группировке надо отключить автополе, и выбрать только вычисляемое поле. Подобным образом надо сделать в разделе сортировка
Добавьте еще скриншот как будет выглядеть отчет с этим заголовком
(11) papche, если исходить из того, что некоторые вместо «Отчет.Сформировать()» используют процессор, то у них не работает. А вот если отчет формируется (можно и в фоне), то метод «ПриКомпоновке…» отрабатывает. В типовой через «Сформировать» все работает.
Но если вопрос касался макета для заголовка, то тут нужно показывать.
ЗЫ: вапсче, господа, если о чем-то спрашивайте, то детали иногда важны, Особенно если в сообщении два ответа.
Использовал данный подход. Имеет смысл, когда нужно программно формировать заголовок с учетом параметров и т.д.. Кстати, можно в настройках СКД шапку и рамку заголовка убрать, а также шрифт настроить.
(15) zqzq,
я рад, что кому-то пригодилось.
(13) echo77, Добавил.
(12) SITR-utyos,
1. В вычисляемое поле можно добавлять любые условия, проверки заполнения.
2. Да. Спасибо за дополнение.
(0) Так же советую, рассказать про то, что группировку можно оформить макет оформления — Без оформления, а в самой схеме прописать, что данное поле оформляется минимальной шириной = х, максимальной шириной = х, чтобы не было переносов, так же можно поиграть со шрифтами
Как бы проблема поиска нужного отчета не решилась — все равно надо все отчеты перебирать пока подходящий не найдется
(19) echo77, спасибо.
(20) Alien_job, Такой заголовок сделает отчет понятнее пользователю. Количество вопросов уменьшится.
Вообще, в заголовке отчетов как минимум нужно указать название отчета, период, дату и время формирования, имя пользователя, который формировал отчет, отборы и параметры, которые использовались при его формировании. :Все это помогает решать массу вопросов даже по скриншоту.
Лучше период указывать отдельными полями, чтобы можно было его скопировать, например, в другой отчет (открыли отчет из письма, например, в Excel или ООо). Также и с некоторыми другими полями отбора — контрагент, склад, подразделение. Если каждый раз придется выдирать дату, контрагента или иной полезный параметр данных из центра строки, то это увеличит количество кликов, а количество кликов надо сокращать.
(23) starik-2005, Это все можно запихнуть в стандартный «Заголовок отчета» — который находится на последней закладке в отчете
делается это все в процедуре «При компановке результата» — кода одна строка.
зачем изобретать велосипед ?
(24) Agapov_Stas,
Использовать вычисляемое поле проще, чем кодировать процедуру «При компоновке результата».
Кроме этого, можно управлять размером шрифта и прочим оформлением, положением заголовка относительно отчета или его частей.
(24) в стандартный заголовок можно, но муторно. Если дети-программисты пилят отчет и тащат туда две даты (для начала периода и его окончания, а потом пилят КОНЕЦПЕРИОДА(ДатаКонца, День) ) — это одно, тут две даты в двух полях. А если это уже подростки, то они вполне способны вместо двух дат стандартный период юзать — и тут уже одна строка с двумя датами и до кучи временем, что совсем не гут при копировании — приходится выдирать. Ну и отборы в одну строку все падают, а хотелось бы в разные ячейки, чтобы проще выбрать и найти что-либо при анализе отчета. Это уже предполагает, что заголовок будет нарисован.
(25) по поводу «проще», то я бы лично так не сказал. Процедура в модуле создается одним кликом. Но изменить макет можно только после выполнения компоновки. Т.е. «стандартнаяОбработка = ложь; сформировать(); …работать с макетом…» Этот момент уже не даст пользователю возможности помимо отчета делать что-то еще, ибо тут асинхронности формирования отчета не получается.
(27) Vlad_2008,
Макеты — это стандартно, красиво.
Это лучший выбор, когда есть время.
(28) если нет времени на макет, но есть время на инфорстарт, то кто-то что-то делает не так.
Комментарии впечатлили больше, чем статья, сработавшая катализатором.