Замена идентификаторов справочников




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

48 Comments

  1. tormozit

    Ну вот уже и ГУИДы менять начали. Куда катится мир?)))

    Reply
  2. luns

    (0) А зачем их менять?

    Reply
  3. Широкий

    Когда открывали новые филиалы — ставили нашу рабочую базу без документов..

    Позже занялись проектом «консолидация данных».. ну и напоролись что ГУИДы у номенклатуры совпадают во всех филиалах процентов на 80.

    Reply
  4. luns

    (3) Понятно… а мы консолидируем при помощи свойств. Так можно «объединять» элементы с разными значениями реквизитов.

    Reply
  5. Широкий

    Исправил ошибку.

    Reply
  6. Широкий

    Добавил отображения состояния обработки.

    Исправил ошибку: если заменямый справочник являлся графой отбора журнала — то замена проходила некорректно

    Reply
  7. alexdum12

    Нужная вещь, особенно когда нужно добиться синхронизации нескольких баз со «своей историей» и конфигурацией до запятой в части справочников

    Reply
  8. adminagro

    Ребята выдает «неудачная попытка соединения с SQL-сервером». … Помогите может быть кто сталкивался .

    Reply
  9. Широкий

    Параметры вводишь неправильные..

    Попробуй написать логи/пароль с учетом регистра

    Reply
  10. adminagro

    😥 Что то не получается. Я ввожу сервер 1C или нужно указывать конкретно SQL сервер где лежит база . И имя и пароль указывать для доступа к базе или к SQL серверу?

    Reply
  11. Широкий

    К скулю конечно

    Reply
  12. adminagro

    ?? я вроде не … но что то не получается.

    вот что указываю : SQL сервер server-msa

    логин : sa

    пароль : ****** 🙂

    база данных как в SQL 1cv81 и ни… сразу без задержек дает отбой

    Reply
  13. Широкий

    Скуль случаем не экспресс?

    Открой Managment Studio и попробуй там законнектиться.

    Reply
  14. adminagro

    Да вроде пошло 🙂 . Спасибо буду пробывать

    Reply
  15. adminagro

    Подскажите а можно ли заменить GUID только у выбранного элмента и на тот GUID что я укажу. У меня просто не согласование GUID между синхронизирующимися базами. нужно менять не все и только на то что укажу ?

    Reply
  16. Широкий

    (15) Можно … только надо убедится что твой новый ГУИД в базе не существует

    Reply
  17. adminagro

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

    Reply
  18. Широкий

    Вообще то обработка должна менять ГУИД во всех объектах, где твой справочник может участвовать.

    Иначе полезут битые ссылки

    Reply
  19. adminagro

    Еще один уточняющий вопрос. Почему для любого значения справочника Контрагенты, число «Обработанно реквизитов» равно 424 ?

    Reply
  20. Широкий

    Я же уже объяснил. Справочник типа «Контрагент» в участвует в различных документах,справочниках и т.д. Во всех этих таблицах нужно заменить гуид

    Reply
  21. adminagro

    Спасибо .

    Reply
  22. Трактор

    А как обработка поступает с регистрами свойств если после изменения ГУИДа запись становится неуникальной?

    Например: Регистр сведений КонтактнаяИнформация измерения Объект, Тип, Вид. Мы изменилили в нём ГУИД одного контрагента на ГУИД другого. Но у этого другого есть записи с теми же значениями Тип и Вид. Что мы увидим в регистре сведений?

    Reply
  23. Широкий

    (22) Мы увидим ошибку..

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

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

    Reply
  24. Umka18

    Пригодилось когда в 2-х базах с обменами постоянно что-то задваивалось. Пришлось делать синхронизацию по гуид, но сначала их корректировать пришлось

    Reply
  25. IgorXml

    Без SQL фокус не получится? С другими СУБД может получиться?

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

    Reply
  26. xoxland

    Некорректно, точнее вообще, не обрабатываются ссылочные ресурсы РегистровСведений. исправляется легко:

    в модуль формы после строки 117 добавить:

    ПеребратьПоляОбъектаМетаданных(ОбъектМетаданных,Представление,»Ресурсы»);

    Также, не обрабатываются константы, анализировать как исправить не было времени

    За идею — зачОт, оч спасло

    Reply
  27. Abadonna

    (3)

    Когда открывали новые филиалы — ставили нашу рабочую базу без документов..

    Позже занялись проектом «консолидация данных».. ну и напоролись что ГУИДы у номенклатуры совпадают во всех филиалах процентов на 80.

    Через конфигуратор что ли грузили? Не через скуль выгрузку-загрузку?

    Reply
  28. stzk

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

    Reply
  29. БольшойЧайник

    (28) проще поменять правила обмена. сделать синхронизацию по коду вместо внутреннего идентификатора

    Reply
  30. Широкий

    (28) Левые колонки что надо поменять, правые — на что надо поменять

    Reply
  31. Xatori111

    (18)Не обрабатывает документы ОперацияБух (т.е. не заменяет Гуиды в этих документах) (Управление производственным предприятием, редакция 1.3 (1.3.38.3) ), Можно сделать?

    Точнее Регистры Бухгалтерии не обрабатываются, а именно не находится ссылка в Субконто

    Reply
  32. Широкий

    Там не сам документ, а его движения.

    Reply
  33. Xatori111

    (32)Это и имел ввиду, по субконто не хочет менять Гуиды, починить можно?

    Reply
  34. Широкий

    Попробуй так

    Reply
  35. Xatori111

    (34)Работает, сейчас заметил, что как выше писали так же не отрабатывают регистры сведений, попробовал исправить вставить кусочек кода после строки 117 вот что получилось, но что то всё равно ГУиды в РС не меняются

    Для каждого ОбъектМетаданных Из Метаданные.РегистрыСведений Цикл

    Представление=»РегистрСведений.»+ОбъектМетаданных.Имя;

    ПеребратьПоляОбъектаМетаданных(ОбъектМетаданных,Представление,»Измерения»);

    ПеребратьПоляОбъектаМетаданных(ОбъектМетаданных,Представление,»Реквизиты»);

    ПеребратьПоляОбъектаМетаданных(ОбъектМетаданных,Представление,»Ресурсы»);

    КонецЦикла;

    Reply
  36. Широкий

    По регистрам сведений код уже был.

    Предположу что получается нарушается уникальность значений, если элемент (на что заменяем) уже существовал в РС.

    Reply
  37. Xatori111

    (36) А такой ещё вопросик, зачем создаётся колонка в таблицах (там вроде получается сначала Гуид записывается в эту колонку, а потом заменяется), почему нельзя сразу заменить?

    Reply
  38. Широкий

    Я не помню 🙂

    Reply
  39. Широкий

    По хорошему — надо бы эту обработку вообще удалить.

    Слишком много дыр и условностей

    Reply
  40. Xatori111

    (39)Ну а что делать если надо:)

    Reply
  41. kser87

    Под 8.2 никак не хочет работать. Поправьте пожалуйста

    Reply
  42. Широкий

    В описании же написано 8.1

    Вы можете конвертировать ее под 8.2 (открыть обработку в конфигураторе) — но тут на свой риск.

    Reply
  43. AlexO

    (3)

    ну и напоролись что ГУИДы у номенклатуры совпадают во всех филиалах процентов на 80.

    Так это и есть одна и та же Номенклатура. Вся ваша проблема была совсем в другом — обмены нужно было делать не по UUID (раз распределенка — однозначно убрать), а по коду. И все.

    А это — велосипед. С квадратными колесами получился. Да еще и с кузовом вместо багажника (выгрузка в SQL).

    Вот как пример записи в таблицы SQL — вексьма. И все.

    (24) Umka18,

    Пригодилось когда в 2-х базах с обменами постоянно что-то задваивалось.

    Опишите проблему точнее. Тоже — обмены РИБ по UUID?

    (22) Трактор,

    Но у этого другого есть записи с теми же значениями Тип и Вид.

    Да ничего не увидим, мы должны однозначно знать, что таких UUID больше в базе нет. Нигде и ни у кого.

    Reply
  44. AlexO

    (0)

    Далее она скидывает элементы справочника (у которых надо поменять ГУИД) в служебную таблицу на sql_сервере и дополнительно создает служебные колонки у таблиц, где будет проходить замена.

    На какие UUID меняются старые? Откуда их берут?

    Измененные UUID — попадают обратно в базу? Или так и остаются в таблице SQL?

    (27) Abadonna,

    Через конфигуратор что ли грузили? Не через скуль выгрузку-загрузку?

    Разницы, в данном случае, нет никакой — в контексте ответа. Что SQL, что в конфигуратор — выгрузка в базу-приемник будет именно тех UUID, которые с исходной базе, никаких проверок с «вон той базой РИБ» по ключам не было и не будет.

    Отличие — если внутри самой базы в файловой версии (к рпримеру) были задвоенные UUID (так как 1С не озаботилась проверкой их уникальности), то SQL не позволит развернуть у себя такую базу — у него поле Ключа уникально и не подлежит «обсуждению». Проще говоря, ругнется «Ошибка. Create Unique index. Неуникальное значение в уникальный индекс».

    И чини как хочешь.

    Reply
  45. Широкий

    (43)

    Так это и есть одна и та же Номенклатура. Вся ваша проблема была совсем в другом — обмены нужно было делать не по UUID (раз распределенка — однозначно убрать), а по коду. И все.

    А это — велосипед. С квадратными колесами получился. Да еще и с кузовом вместо багажника (выгрузка в SQL).

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

    Reply
  46. AlexO

    (39)

    По хорошему — надо бы эту обработку вообще удалить.

    Возможно, достаточно сменить название — «Практически пример создания таблицы в SQL из 1С».

    (40) Xatori111,

    Ну а что делать если надо:)

    Что надо-то на самом деле?

    Reply
  47. AlexO

    (45)

    Слушай, ты.. не-мальчик… ты давай повежливей.

    Reply
  48. AlexO

    (0) Ты проблему даже не описал. А выкатил обработку, делающую финт ради развлечения.

    Развлекаться — развлекайся, но пиши об этом прямо, и не груби.

    Мальчик не-мальчик.

    Reply

Leave a Comment

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