<?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='\
Это то же, что и 2 среза последних на 2ве даты что ли?
Не очень понятно, что это даёт.. дайте пожалуйста пару примеров где это может пригодится..
ту 1:
В конкретно этом примере, действительно можно было бы использовать 2 среза последних, однако мне попадались ситуации, когда в запросе необходимо было получить значения периодического регистра сведений или остатков из регистра накопления на различные, заранее не известные наборы дат. Ранее приходилось решать динамическим построением текста запроса.
Пример по другим таблицам, но с использованием того же механизма.
Например используя этот механизм можно построить отчет «Динамика дебиторской задолженности по месяцам» для БП8 в различных валютах. Причем сумма задолженности вычисляется по курсу, действовавшему на конец каждого месяца попавшего в период отчета.
Вот здесьhttp://infostart.ru/public/21181/ моя статья с примером-базой, посвященная данному вопросу. Твое решение сильно запутано. Там надо всего 2 запроса: либо один вложенный в другой, либо через одну временную таблицу. У тебя же в примере запросов 4.
При желании можно сделать текст этого запроса и с 2мя конструкциями выбор и с 3мя.
Некоторая запутанность обусловлена тем, что я использую 2 периодических регистра сведений.
Как не странно, но с 4мя запросами этот пример отрабатывает приблизительно в 10 раз быстрее, чем с 2мя.))))
(5) В данном примере я увидел только РегистрСведений.КурсыВалют. Где второй? На самом деле скорость выполнения так же обусловлена построением запроса и его оптимизацией внутри MSSQL. Как сервер оптимизирует запрос — одному Майкрософту известно, но не факт, что он это делает всегда правильно. Конструкции с вложенным запросом и с временной таблицей могут различаться по времени выполнения в разные стороны из-за многих факторов, которые включают в себя так же и то, насколько правильно настроен MSSQL и количество данных, передаваемых между таблицами. Так что быстрее в 10 раз может быть исключительно на твоей системе, а у других может быть так же или медленнее.
(1). Посмотрите мою статью, указанную в 4-м посте, возможно так Вам станет понятнее. На самом деле нужный и полезный прием.
(7). указанную статью я видел уже давно.
На мой взгляд — и эта и Ваша статья — одно и тоже, да вот только когда надо я не смог найти уже предложенное Вами решение моего вопроса. Потому сначала сделал сам, а потом выложил на этом сайте.
Предлагаю не начинать обсуждение, чем хорошо ваше решение, или чем хорошо мое — смысла я в этом не вижу. Если лучше все таки Ваше — честь Вам и хвала.
Честно говоря, Ваше решение кажется мне не менее запутанным, чем мое))).
(8) Посмотреть статью было адресовано kote.
)))
Уже было. Это называется срез последних на каждую дату в запросе. Например, вот эта публикацияhttp://infostart.ru/public/77568/
В интернете уже достаточно решений данного вопроса.
А соединять два набора данных в СКД с исползованием среза последних — я не рекомендую, т.к. это достаточно медленно работает
(1) Где это можно применить? Например, вы делаете реестр счетов-фактур, часть из которых не рублевые, а валютные. Вам нужен реестр в одной валюте — в рублях. По скольку курсы валют могут быть не на каждую дату, а какие счет-фактуры и на какю дату в валюте сразу и не определишь.
(11) echo77, Указанная Вами публикация датирована позже моей. Собственно, мне все-равно.
Применить можно во многих случаях. Срез последних на каждую дату в запросе может быть полезен когда приходится выводить данные из регистра накопления и регистра сведений одновременно. Причем, из регистра сведений данные необходимо получать актуальные на дату из регистра накопления.
Пример из практики: вывести движения по складу, где суммовая оценка движения товара берется из типов цен. Ест-но значение цены должно получаться на дату движения.
По прошествии времени, понимаю, что привел не всем понятный пример(
(12) Я только что увидел, что я здесь некропостингом занимаюсь. Не понимаю, как ваша публикация 2010 года всплыла на главной странице…
Есть пример применения?
Обработка-пример имеется?
(14), (15) Пример приведен в публикации. Это виртуальный пример. На практике этот кусок кода, обычно, является частью более крупного запроса.
Без примера очень сложно.
Реальный пример хотя бы из УТ