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




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

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 не будет опубликован. Обязательные поля помечены *