Поиск непроведенных документов с движениями (8.2, обычное приложение, управляемое приложение)




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?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='\

32 Comments

  1. V_V_V

    Порадовала универсальность. В своей же самописной конфе пользовался собственным вариантом — оказывается не учел пару моментов, нашлись еще документы! 😀

    Reply
  2. krv2k

    (2)на здоровье )

    Reply
  3. 1C82

    Быстро написать простенький отчетик по вылавливанию таких багов по одному регистру конечно же можно. Но зачем изобретать велосипед. Проверено на боевой базе — работает! Во всяком случае по регистру партий косяк отловила. Большое спасибо! Пригодится всем.

    Reply
  4. krv2k

    (4) Это хорошо, значит, не зря сделал обработку универсальной.

    Reply
  5. dyh

    +1 к универсальности на кривых самописных конфах. пасиб 😉

    Reply
  6. Alexey55

    Спасибо! очень пригодилась!

    Reply
  7. sherbv

    Спасибо за обработку!

    Теперь проблема решается намного быстрее)

    Reply
  8. krv2k

    (8)

    Теперь проблема решается намного быстрее)

    А с какой проблемой Вы столкнулись, если не секрет?

    Reply
  9. krv2k

    (8) Хотелось бы узнать, из-за чего именно возникает проблема, что её приходится периодически решать.

    Reply
  10. ninch

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

    Reply
  11. lidia3004

    Спасибо, сегодня очень пригодилась, хотя скачала давно.

    Reply
  12. Гость

    а каким образом у не проведенного, а уж тем более помеченного на удаление документа могут быть движения по регистрам?

    Reply
  13. krv2k

    (13) Например, такая ошибка часто возникает при обмене между распределенными ИБ.

    Reply
  14. lidia3004

    Спасибо, просто запустила и оказалось, что есть такие доки — буду разбираться.

    Reply
  15. oberon355

    У меня такая ситуация возникла, когда загружал документы через xml. Если новый документ записывается поверх старого, то движения по документу сохраняются от старого. Чертовски неприятно. Такое произошло на стандартной бухгалтерии из за кривизны xml файлов. Так что обработки проведения документа здесь не причём.

    Reply
  16. krv2k

    (16) oberon355

    Да, это еще один из способов запороть базу.

    Reply
  17. oberon355

    (17) Что значит запороть базу? Загружать кривые документы? Так достаточно просто убрать движения и перепровести их. Появятся новые движения и все будет зашибись

    Reply
  18. krv2k

    (18) Я имел в виду не конкретно движения, но саму процедуру. При загрузке через xml нужно быть осторожным, так как последствия могут проявиться через некоторое время, когда будет уже поздно.

    Reply
  19. materiy_boec

    А если документ вообще без движений, а галка что он проведён стоит, ваша обработка будет показывать такие документы?

    ПОсле обмена РИБ или Свертки базы бывают и такие ситуации, надеюсь выручит ваша обработка

    Спасибо

    Reply
  20. materiy_boec

    Но я все равно жду ответа на вопрос

    Reply
  21. krv2k

    (20) Нет, такие документы обработка не покажет, так как в общем случае это не является ошибкой. Но если такая возможность нужна, могу её добавить.

    Reply
  22. JammShoot

    есть вышеописанная проблема, при обмене через универсальный обмен данными в формате xml из УТ 10 в БП 3, у документов помеченных на удаление остались движения.

    не могу запустить обработку

    платформа: 1С:Предприятие 8.3 (8.3.4.496)

    конфа: Бухгалтерия предприятия, редакция 3.0 (3.0.32.6)

    при открытии выдает ошибку:

    {Форма.ФормаУправляемая.Форма(8)}: Поле объекта недоступно для записи (ЭтотОбъект)

    ЭтотОбъект = РеквизитФормыВЗначение(«Объект»);

    Reply
  23. krv2k

    (23) JammShoot, ошибку исправил.

    Reply
  24. Pavean

    Прямо противоположная проблема для меня сейчас насущнее, но эта обработка тоже наверняка будет полезной.

    Reply
  25. krv2k

    (25) Pavean, что за противоположная проблема?

    Reply
  26. Pavean

    (26) Найти и перепровести проведенные документы без движений.

    Reply
  27. chmv

    А откуда они беруттся?

    Reply
  28. Den_D

    Еще полезный функционал, найти движения с удаленными объектами.

    Например по какой то причине «Объект не обнаружен» в РИБ из центральной базы поднялись движения, но не поднялся сам объект, а только идентификатор.

    Reply
  29. Den_D

    — не сюда —

    Reply
  30. корум

    (22) фантазия вопрошающих «большую кнопку сделать всё» безгранична.

    Спасибо за обработку, постараюсь на её основе сделать по требованию:

    реестр документов по юр.лицам из списка,у которых признак «Проведен» = ЛОЖЬ и «ПометкаУдаления» = ЛОЖЬ за выбранный период;

    реестр документов по юр.лицам из списка за указанный период, у которых признак «Проведен» = ЛОЖЬ, но есть движения по регистрам (с указанием имен регистров).

    реестр документов по юр.лицам из списка за указанный период, у которых стоит признак проведения, но нет движений.

    Reply
  31. корум

    кстати, какой из 3 методов самый быстрый?

    Reply
  32. sempaii

    Спасибо за обработку, помогла найти непроведенные документы.

    Внёс небольшое изменение.

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

    Поправил процедуру:

    &НаКлиенте
    Процедура ДокументыТаблицаВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    //ОткрытьЗначение(Элемент.ТекущиеДанные.Регистратор);
    ПоказатьЗначение(,Элемент.ТекущиеДанные.Регистратор);
    
    КонецПроцедуры

    Показать

    Reply

Leave a Comment

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