Удалить пустые ссылки из регистров




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2026-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='\

36 Comments

  1. overdriver

    Спасибо. Работает. Как раз появилась одна ничейная запись по взаиморасчетам. Успешно была удалена этой обработкой.

    Reply
  2. Alav

    А ТиИ уже не подходит?

    Reply
  3. ApocalypseNTC

    Работает быстрее, чем ТиИ. Да и ТиИ не всегда помогает.

    Reply
  4. sergeypv

    Не плохо бы на форму «положить» строку с именем текущего регистра и индикатор по этому регистру. Так же хотелось бы иметь возможность выбрать один из регистров для проверки, а не все. У кого база за 200 ГБ, тот поймет. Ну и в конце не плохо бы отчет с количеством пустых ссылок в каждом регистре.

    Reply
  5. ApocalypseNTC

    Хорошее предложение. Сделаю.

    Reply
  6. KukA.5

    Хорошая полезная вещь, аккуратно изготовленная.

    Автору огромный плюс и за идею и за ее очень толковую реализацию.

    Как полезный совет:

    для любых ссылочных типов если в запросе напишем «Где …СсылочныйТипПоля.Ссылка ЕСТЬ NULL…», то получим неявное соединение Ссылки «с самой собой», то есть с несуществующим в БД объектом, то есть получим NULL. А это и есть битые ссылки.

    Не всегда же можно оперется на регистратор в регистре, правда ведь? 😀

    Reply
  7. Ish_2

    В обработке в процедуре ПочиститьРегистр() в тексте запроса есть строка

    «ГДЕ НаименованиеРегистра.Регистратор.Дата ЕСТЬ NULL»

    — что понятно и прозрачно. Значит в соответствующей таблице регистраторов объект с такой ссылкой отсутствует и обращение к любому из реквизитов такого регистратора даст NULL , значит эта ссылка битая.

    А вот твой пост (6) загадочен и непонятен.

    Причем тут фильтр на значение самой ссылки

    «Где …СсылочныйТипПоля.Ссылка ЕСТЬ NULL…» ?

    Reply
  8. bulpi

    Все хорошо, только нужно больше информации для пользователя : индикация как идет процесс и т.д.

    Reply
  9. RailMen

    Даешь обработку «Расшифровка, откуда взялись пустые ссылки» 😀

    Reply
  10. KukA.5

    (7) если у нас есть регистр сведений, например, независимый (без регистратора), то «битые ссылки» в нем …могут быть.

    «битые ссылки» могут оказаться по любым измерения, ресурсам, реквизитам, которые ссылочного типа.

    В этом случае их можно «отловить» конструкцией в запросе «Где ИмяПоляСсылочногоТипа.Ссылка Есть NULL»….

    Кстати, Регистратор является ссылочным типом и можно (хотя это безусловно будет чуть 🙂 более затратно в этом конкретном случае) сделать проверку не на Регистратор.Дата, а на Регистратор.Ссылка.

    Поэтому если делать Ссылка.Ссылка, то мы точно получим битые ссылки для любого типа данных, ссылочного типа — и автор может этим воспользоваться для развития своей работы.

    Надеюсь, теперь мой комментарий стал менее туманный (но более скучным).

    Reply
  11. ApocalypseNTC

    Прислушался к советам sergeypv. И сделал обработку более функциональной.

    Reply
  12. bagr

    Смотрел 2-ую версию. Для себя сделал:

    1) Убрал Сообщить(«Чтобы прервать выполнение обработки нажмите Ctrl-Break», СтатусСообщения.Информация); — реально раздражает, заменил его Надписью.

    2) Добавил в начале, конце и перед Возврат — Сообщить(«Начало «+ТекущаяДата()); Сообщить(«Конец «+ТекущаяДата());

    3) Добавил в цикле процедуры КнопкаВыполнитьНажатие(Кнопка) Состояние(ВидРегистра.Имя+»: «+Регистр.Имя); (если регистр большой — обрабатывается долго, видно хоть какой) — а в процедуре «почистить» почему-то «состояние» не обрабатывает

    Reply
  13. bagr

    А ну конечно понятно почему в процедуре Почистить не отрабатавает Состояние, там же собственно запрос по битым ссылкам…

    Reply
  14. wiranata

    При работе обработки не обнаружил заявленных:

    ———————————————————————————————————————

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

    Добавлен индикатор (не точный) процесса. В строке состояния отображаются производимые операции.

    После выполнения обработки выводится отчет в виде табличного документа с группировками.

    ———————————————————————————————————————

    Возможно не там смотрел…

    Reply
  15. ApocalypseNTC

    Два файла для скачивания. Вот на вторую версию ссылка http://infostart.ru/public/download.php?file=72450

    Reply
  16. ms_andrey

    Выдается ошибка при опции Удалить

    {Форма.Форма(134)}: Ошибка при вызове метода контекста (Записать): Ошибка записи! Не установлен отбор по регистратору (Регистр накопления: Взаиморасчеты с контрагентами)

    НаборЗаписей.Записать();

    по причине:

    Ошибка записи! Не установлен отбор по регистратору (Регистр накопления: Взаиморасчеты с контрагентами)

    В чем может быть проблема?

    Reply
  17. ApocalypseNTC

    А какая конфигурация? Лучше отладчиком посмотреть.

    Reply
  18. alex_4x

    Прикол в том, что при попытке чистить этой обработкой записи в PostgreSQL ной базе — 1С Вылетает в момент попытки записать в регистр с отбором по пустому документу.

    Reply
  19. Jogeedae

    а у меня такая называется : ПоискИУдалениеБитыхСсылокВРегистрах.epf :D.

    Reply
  20. Вакулиса

    Не работает когда есть запись с пустой ссылкой. То есть Документ.ПустаяСсылка()

    Reply
  21. Coollerok

    А у меня все работает! Спасибо!

    Reply
  22. gurovvv

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

    Reply
  23. von_de

    По умолчанию с инфостарта качается старая версия обработки — конечно не фонтан. Вторая версия понравилась, помогла справится с пустыми записями.Спасибо.

    Reply
  24. art-ame

    Кто испробовал, подскажите , помогает избавиться от такого глюка как «с качеством Новый на складе …. недостаточно» при наличии этого товара?

    На любых конфигурациях работает?

    Reply
  25. art-ame

    Ну,вот, испробовала… Что сказать, не работает она в УТ 8.1!!!

    Выводит окошко с надписями «Сообщить» , «Удалить», «Выполнить», «Закрыть». Окошки, как показано выше на скриншотах, отсутствуют.

    Reply
  26. gala2009

    спасибо за обработку, очень пригодилась

    Reply
  27. Tur_gad

    Замечательная вещь скачал давно но воспользовался только недавно, работает как часы и очень полезна). Особенно с моей перековерканной базой. Удалось отловить много битого движения когда сумма есть а документа как такового нет). Огромное спасибо за эту разработку респект вам и удачи в дальнейшей работе!!!!

    Reply
  28. Tur_gad

    Вопросик по чему после конвертации обработки под 8,2 у меня удаляет все движение в базах. короче коверкает жуть. подскажите в чем может быть проблема?

    Reply
  29. masiok

    Удаляет только битые ссылки? Или как в описании сказано пустые?

    Reply
  30. vis_tmp

    (29)Пустые не удаляет…

    Reply
  31. dka80

    Спасибо. Думал сам написать, а все уже изобретено до нас )) Отработала без проблем.

    Reply
  32. Den_D

    Вот что значит профессионал! Уже платформа 8.3.8, УПП 1.3, а обработка работает четко! Спасибо

    Reply
  33. ivdic

    почему то не работает открывает пустую форму

    Reply
  34. LosevI

    (33) скорее всего потому что форма неуправляемая, а открываете в управляемом интерфейсе…

    Самому очень нужна сейчас эта обработка. Да простит меня Инфостарт — нужно последнее сообщение ло 1 стартмани, чтобы ее скачать.

    Скачаю, даже если не запустится — будет полезно посмотреть код, как реализован поиск и удаление записей.

    Reply
  35. Laser

    УТ 10.3 Хотел почистить регистр соответствие информационных баз… При запуске показывает далеко не все регистры и нужного мне в списке нет

    Reply
  36. bimy22

    (3) Соглашусь, насчёт скорости работы.

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

    Reply

Leave a Comment

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