Реанимация битых ссылок




Принцип обмена данными из 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='\

42 Comments

  1. Re:аниматор

    Реально данная обработка помогла, спасибо!

    Reply ↓
  2. tormozit

    А тестирование и исправление разве не делает тоже самое?

    Reply ↓
  3. Спасибо. Сам такую писал но где-то с UID был трабл. А ту все фунциклирен.

    Reply ↓
  4. PowerBoy

    Добавил версию обработки «РеанимацияБитыхСсылокСУчетомВладельца»,

    позволяет создаваемому объекту назначить владельца.

    Автор:kirill buckov

    Reply ↓
  5. andrey995

    а для семерки такое есть ?

    Reply ↓
  6. ivanoa

    У меня не получилось(. В регистре бухгалтерии(УПП) есть в регистраторе ьитая ссылка. Документ платежное поручение создается с данным UUID, но при записи ссылка остается битой, в записи регистра регистратор не становится ссылкой на вновь созданный документ… Пробую пересоздать, говорит, что есть Подскажите, в чем дело.

    Reply ↓
  7. PowerBoy

    (6) Обработку запускаете с полными правами?

    Reply ↓
  8. Finn

    1С:Предприятие 8.1. Удалил несколько контрагентов. Теперь пытаюсь восстановить. Последовательность — сначала запись справочника о контрагенте, потом ДоговорВзаиморасчетов и ЮрЛицо с привязкой к Контрагенту. ДоговорВзаиморасчетов и ЮрЛицо действительно создаются с нужными ссылками и привязками. А вот ссылка на контрагента, скажем, в расходной накладной, остается битой. 🙁 Не пойму в чем дело. Пользоваться пытался обеими версиями, но версия с подчинением не дает создавать запись справочника без указания подчиненния. 🙁

    Reply ↓
  9. Abadonna

    >В результате все битые ссылки будут теперь ссылаться на новый объект.(т.е. будут теперь не битыми).

    За одну битую ссылку две небитых дают! :))))))))))))))

    Reply ↓
  10. Finn

    Разобрался. Восстановил. Спасибо!

    Reply ↓
  11. frolov.dns

    Может кто подскажет, в чем полезность данной обработки?

    Reply ↓
  12. avea

    Под 8.1 можно переделать?

    Reply ↓
  13. PowerBoy

    (12) Добавил версию под 8.1

    Reply ↓
  14. looxxx

    Пишет длина GUID ссылки должна быть равна 32 знакам

    Reply ↓
  15. looxxx

    (14) разобрался. надо вставлять номер после двоеточия. 🙂

    Reply ↓
  16. ost.a

    В 8.1 пытался восстановить удаленную характеристику(в документах осталась сыылка на объект не найден) — СОЗДАЕТ НОВУЮ(с новым GUID), а ссылки так и остаются на объект не найден…??? в чем трабл?

    Reply ↓
  17. FausTT1

    Ситуация такая же как и у ost.a

    Может кто объяснить в чем причина?

    Reply ↓
  18. марокко

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

    Reply ↓
  19. Катя84

    Спасибо, пригодилось!

    Reply ↓
  20. iones

    Посмотрел в коде, система понятна… НО!

    При записи создается новый GUID (тестировалась на 8.1 УПП).

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

    Reply ↓
  21. iones3

    Короче.

    У меня возникла такая проблема:

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

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

    Почитав и поисках, перерыв учебники, интернет и кучу форумов, вот что нашел:

    http://www.poleznayainfo1c.narod.ru/

    Это реально работает!

    В SQL подменил UIN. и Все сработало. Главное найти нужную таблицу.

    Для Определения таблицы в SQL пример:

    МассивИменМетаданных = Новый Массив();

    МассивИменМетаданных.Добавить(«Справочник.ФизическиеЛица»);

    СтруктБД=ПолучитьСтруктуруХраненияБазыДанных(МассивИменМетаданных);

    Узнаем таблицу, а в SQL создаем Query такого плана:

    UPDATE [название_базы].[dbo].[_название_таблицы]

    SET [_IDRRef] = удаленный_идентификатор

    WHERE [_IDRRef] = на_какой_идентификатор_подменяем

    Не благодарите =)

    Дерзайте.

    Reply ↓
  22. pegas80

    При записи создается новый GUID (тестировалась на 8.1 УПП).

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

    Reply ↓
  23. PowerBoy

    (22) вероятно указываете неверный тип ссылки.

    Reply ↓
  24. pri_hod

    не работает для 8.2 sql 2008

    Reply ↓
  25. zhumanova

    спасибо. у меня все срабатывает. и понятная в использовании

    Reply ↓
  26. arjunasoft

    Спасибо, помогла реанимировать номенклатуру.

    Reply ↓
  27. Scorpion1_77

    Спасибо. Отличная обработка. Несколько раз выручала.

    Reply ↓
  28. opolyakova

    как то, никак.

    Reply ↓
  29. Nika-cat

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

    Reply ↓
  30. nasya

    Спасибо! Обработка очень пригодилась — и для восстановления удаленного и для того, чтобы разобраться как работать с UID-)

    Reply ↓
  31. jONES1979

    Спасибо конечно, но как из формата «46:b7b0001cc460bde211df026a8dd7cb3a» получить GUID в том виде, в каком требует обработка?

    EDIT: Спасибо, разобрался. Автору плюсик.

    Reply ↓
  32. petrovaUL

    1С:Предприятие 8.1. Удалил несколько контрагентов. Теперь пытаюсь восстановить. Спасибо! Обработка очень пригодилась — и для восстановления удаленного

    Reply ↓
  33. nasya

    Большое спасибо!

    Reply ↓
  34. emptyteam
    А тестирование и исправление разве не делает тоже самое?

    Действительно, в чем отличие от тестирования и исправления ?

    Reply ↓
  35. PowerBoy

    «Действительно, в чем отличие от тестирования и исправления ?»

    Чтоб сделать тестирование и исправление мне нужно выгнать из базы около 100 работающих пользователей, запретить обмены РИБ и подождать часиков 5-6 и еще неизвестно что она там попутно направит.

    Reply ↓
  36. Istur

    (0) Поставил минус. Во-первых — это не GUID, а UUID. Отсутствует какое-либо описание и когда я вбивал GUID в поле, то поле мне ошибку выдавало про 32 символа, я только в комментариях увидел, что автор подразумевает UUID. ну и просто v8.x: Битая ссылка, <Объект не найден>, Уникальный Идентификатор, GUID лучше и понятнее, юзабельнее, и описание есть. Данную обработку скачивал, потому что здесь можно создавать элементы с владельцем, потом плюнул, и в обработку по ссылке сам добавил присвоение владельца, что заняло минут 3-5.

    Reply ↓
  37. нинас

    Работает в монопольном режиме или нет?

    Reply ↓
  38. PowerBoy

    (38) НЕТ

    Reply ↓
  39. a1ex4ndr

    что то гляжу под 7.7 никто такой обработки не знает… может тогда кто то подскажет, разницу ЗначениеВСтрокуВнутр(Объект) для текущей базы и для объекта полученного через ОЛЕ? насколько я понял в текущей базе первый символ — идентификатор типа — (T=счет/O=документ/B=справочник/E=перечисление/U=неопределенн­ный) и последний реквизит 23 знака — 10 знаков идентификатор вида(спр номенклатура например) 10 знаков — идентификатор объекта, и последние 3 — идентификатор базы (юзается для УРИБ)

    а в ссылке (36):

    Объект = БазаОле.ЗначениеВстрокуВнутр(Док_Источник.ТекущийДокумент());

    // Для примера Объект возвращает {«O»,»0″,»0″,»3114″,»0″,»0″,» 258156CB «}

    что значит этот 258156CB? каким то образом объединеные идентификаторы?

    Reply ↓
  40. mr.Kot

    Посмотрел, почитал коменты и воспользовался обработкой из комента (36).

    Reply ↓
  41. AlexO

    (35)

    Чтоб сделать тестирование и исправление мне нужно выгнать из базы около 100 работающих пользователей

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

    Reply ↓
  42. AlexO

    (36) Istur,

    то поле мне ошибку выдавало про 32 символа, я только в комментариях увидел, что автор подразумевает UUID

    У автора каша какая-то, на самом деле формат ID выглядит так:

    UUID — 84:bf5600145e3710ab11dda4c605dbe824

    GUID — 05dbe824-a4c6-11dd-bf56-00145e3710ab

    Reply ↓

Leave a Comment

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