<?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. Зачем СОКРЛП()? У текстовых реквизитов установлена фиксированная длина?
2. При большом объеме базы список будет жутко тормозить, т.к. обновление отображения будет происходить каждый раз при изменении размеров формы или перемещения по строкам.
Мое мнение, использовать такой подход для расчета имеет смысл только для документов с выбранным интервалом, т.е. нет необходимости вешать его на обновление отображения.
Правда, что то я сумневаюсь, что если у документа есть реквизит «Сумма», что по нему в подвале нельзя получить итоговое значение.
Опять же, почему нельзя посчитать итог в запросе?
Вообщем много почему!!!
Вот именно что, почему в событии ОбновлениеОтображения(), а не в ПриПолученииДанных?
2(3): +1
Каждый раз в цикле юзать ДокументСписок.Отбор[Индекс] совсем не гуд 🙁
похоже человек только учиться… видать бывший семерочник 🙂
Советую изучить ИсточникДанных и ОписаниеИсточникаДанных, при использовании которых данная задача превращается в тривиальную.
(7)+
(2) 1 — Метод СокрЛП() используеться для перестрахования, Ресурсов много он не ест, зато дает стопроцентный результат (возвращает ТЕКСТ без ПРОБЕЛОВ) что для запроса и нужно. 2 — при большом объеме базы рекомендую вешать не в предопределенную процедуру ОбновлениеОтображения(), а на кнопку, чтоб пользователь рассчитывал сам эту сумму. Или если есть вариант получше, я с радостью выслушаю.
(3) Потому что предопределенной процедуры ПриПолученииДанных() нет в форме списка документа. А я повторяюсь что это код для получения итоговой суммы в динамических списках (список документов, список справочников).
(5) есть другие варианты с радостью выслушаю 🙂
К сожалению, я других вариантов не вижу, при условию что мне нужно передать текущий отбор.
(6) Век живи, век учись. «Семерочником» всегда лучше быть чем двоечником 😀
А если серьезно, то не вижу логики в ваших словах. Из бывших «семерочников» часто получаются настоящие «восмерочники».
(7) Спасибо! Пригодился ИсточникДанных, с помощью которого удалось избежать лишнего цикла. +1
(13) Уже намного лучше.
1. Для оптимизации (все-таки код будет очень часто вызываться) лучше весь блок до ПостроительЗапроса.Выполнить() вынести в отдельный метод, вызываемый в ПриОткрытии.
2. Совсем нелогично использование запроса и выгрузки в ТЗ и подсчет суммы 🙁
считай итоговую сумму сразу в запрос 🙂 — будет совсем шустро.
Кстати, автор прав, а (3) нет 🙂
(15), (10) Извините-с, х..ню-с сморозил. 🙁
(0) Автор, прочтиhttp://www.kb.mista.ru/article.php?id=471
думаю, станет более понятна схема с построителем и динамическим списком.
(17) Нормальная статейка, подтвердил свои знания )))
На (14) обрати внимание
(19) Да, согласен, что часть кода можно вынести в процедуру ПриОткрытии(), только до строки «ОписаниеИсточникаДанных= Новый ОписаниеИсточникаДанных(ДокументСписок);» иначе не будет обновляться итоговая сумма. И итог можно в запросе рассчитать. 🙂
Для динамического списка с произвольным запросом работает (управляемые формы)??? У меня почему-то не взлетело.
ОписаниеИсточникаДанных= Новый ОписаниеИсточникаДанных(ДокументСписок);
ДокументСписок — Это элемент формы???
(21) tka4enk0, для управляемых форм этот код не пойдет.
ДокументСписок — это тип «ДокументСписок[ИмяДокумента]».