<?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) т.к. 1С использует «ленивое» сравнение, можно поставить
на первое место, это должно избавить от лишних проверок. Можно добавить индикацию необходимости только на клиенте в обработчик «ПриОкончанииРедактирования» и «ПослеУдаления». Просто в моём случае это пока работает достаточно быстро, проблем нет.
(1)http://prntscr.com/g5ftg8 — весь код на клиенте, без вызова сервера. Вызов происходит только на строке
(3) Во-первых это ничего не изменит обработчик ожидания подключен например на 30 сек.
Во-вторых, сейчас работает быстро, а если у вас в сети предприятия например 1000 пользователей. И у всех вот такие вещи опрашивают базу и делают избыточные записи.
Также хочется подчеркнуть тот момент, что автосохранение и не всегда пользователю необходимо. Зашол в документ и изменил товар, чтобы посмотреть какая цена получится или общая сумма, но клиент отказался от такой суммы и просит оставить так как было и т.д. и тому подобное.
(4) Во-первых, чем не нравится обработчик ожидания? Тут он срабатывает каждый раз при простое. Если ставить больше, то очень часто просто не срабатывает, т.к. система генерирует события и вполне вероятно, что он вообще не будет срабатывать.
Во-вторых, базу они не опрашивают, и так же по тексту читайте — «Если нужно не всем пользователям…», «Реализовывать этот механизм для всех документов конфигурации определённо не стоит…», «Также этот метод без модификации кода не подойдёт…».
В-третьих см. «Во-вторых» 🙂
Объект.Проведен = Опрос базы
Объект.Товары.Количество() = Опрос базы
Объект.ВозвратнаяТара.Количество() = Опрос базы
Из мат.части в Вашем случае вообще произойдет полная отчитка объекта в кэш.
Минус поставил!
(6) показал же, что не происходит. Или замеру от 1С не доверяете?
Вот это интересно, что бы это могло значить. Ничего в объект не пишу.
Критикуешь, предлагай.
(7)
сохраняйте в табличный документ или xml локально во временой папке на компьютере пользователя
Заодно будет история версий.
Никаких нагрузок на сервер
Ну и загрузку придется реализовать
Я бы такую штуку скачал
(8) нагрузок нет на сервер. А вот предложенный вариант будет, как раз, очень медленный. Да и для нормальной реализации потребуется писать ПВД, чтобы контролировать что там пользователь вводил, а что теперь в базе (значения ссылочных типов изменяются). Вообще этот вариант лучше делать (я так думаю) с помощью встроенной подсистемы версионирования, но это точно ещё «хуже».
(10) В самом простом случае — это три цикла (реквизиты, строки т/ч, колонки т/ч), даже если хранить только примитивные типы и ссылки (без реквизитов по ссылкам), это гораздо медленнее (даже если не использовать метаданные, а кэшировать в форме на клиенте имена реквизитов). А запись файла на диск — это ещё куча операций. Если бы это работало, как в Excel на уровне платформы, тогда да, это можно было бы рассматривать как вариант на случай потери соединения.
Нда …. Почитайте временные файлы и для чего они нужны.
(12) Хорошая шутка. Всегда думал, что временные файлы на то и временные, что после того как приложение закрывает дескриптор файла, нет никаких гарантий что файл не будет удалён или изменён.
Что будет если данные объекта будут изменены извне? в ходе обмена при включенной авторегистрации например? Интерактивно при попытки записи будет выдаваться сообщение что данные изменены другим пользователем. А как будет вести себя обработчик ожидания? Может вызов Записать лучше поместить в попытку?
(14) могу сказать по собственному опыту, что это хорошо, если пользователь узнает, что объект, который он сейчас редактирует, изменился. т.к. часто приходилось слышать такое: «я тут набираю документ, нажимаю ‘Провести’, а мне ошибка. что делать?». и пытался я сделать автоматическое сохранение, но получил однозначное «фе» от руководителя. это была платформа 8.2. а как это могло бы облегчить жизнь тем бух-ам?
П.С. в попытку думал, разница будет в том, что тогда для пользователя это будет просто сообщение, нужно будет меры принимать какие-то, а так — это исключение, нажми «Ок» и что-нибудь предпринимай. Хотя предложение правильное, но можно и просто исключительную блокировку накладывать при открытии документа. Так, кажется, приходилось делать для каких-то документов.
Блокировка накладывается на форму:
Показать
а вот обмен или регламентированное задание может перезаписать документ Не Интерактивно. Поэтому через Попытку и будет корректней пытаться записать документ, и в случае ошибки сразу отключить обработчик ожидания
(16) добавил попытку, а вот при попытке начать редактирование уже открытого в другом сеансе документа и так появляется сообщение об ошибке в автоматическом режиме управления блокировками.