Простой способ регистрации изменений реквизитов объектов в 1С Предприятии 8.X (делюсь опытом)




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

75 Comments

  1. mdzen

    Интересно.

    Как в просмотре журнала это смотрится…

    Reply ↓
  2. Armando

    Да, точно. Автор, покажи картинку.

    ps. мне еще вот это понравилось:

    //This code is ported from http://www.kb.mista.ru/article.php?id=115

    «Кофе энд булочка. Ниче, что я по-английски?» — From a joke

    Reply ↓
  3. Поручик

    Как-то так. http://forum.aeroion.ru/download434.png

    Имя пользователя и машины я потёр, что бы не попалить

    Reply ↓
  4. Поручик

    (2) 🙂 То, что тебе понравилось, это привычка с модописательства для phpbb

    Reply ↓
  5. Armando

    (3) Если реквизит был изменен, то хочется видеть на что именно. А то заблудиться можно. Картинку лучше в статью прилепи.

    (4) Я так и понял, что привычка. У меня имха, что это как-то нелепо смотрится.

    Разукрашенный код намного удобней и приятней смотреть)

    Reply ↓
  6. Armando

    И еще. Если это делается для пользователей, то лучше использовать не идентификаторы объектов, а синонимы.

    Reply ↓
  7. Поручик

    >> Если реквизит был изменен, то хочется видеть на что именно.

    Ну так кликни по строке в журнале и увидишь полную раскладку по данному событию.

    Reply ↓
  8. Armando

    (7) Уже понял. Я просто картинку изучаю))

    Reply ↓
  9. Поручик

    (6) ну тут на каждый чих не наздравствуешься.

    Reply ↓
  10. registr

    Полезная вещь.. 🙂 Но я лично, дополнительно решил пойти несколько другим путем — пусть каждый объект еще и сам хранит историю своих изменений, и более подробную…

    Reply ↓
  11. Поручик

    Если нужна история изменений, да ещё и подробная, да ещё и с восстановлением, вам сюда http://infostart.ru/projects/4040/ или в аналогичные.

    Reply ↓
  12. Поручик

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

    Reply ↓
  13. glek

    Ну не знаю, насчет журнала регистрации.

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

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

    Reply ↓
  14. glek

    сорри, не увиждел про подписку.

    Reply ↓
  15. CheBurator

    блин, на семерке этих разработок — вагон и тележка.. и все на 8-ке тех же клоунов лепим.. хоть бы чего нового…

    .

    1. отслежтвается программное изменение реквизитов? если нет — в сад!

    2. способна прога понять, что изменение порядка строк не является изменением? если нет — в сад!

    .. пока хватит..

    Reply ↓
  16. Поручик

    CheBurator, взад

    1. Отслеживается. Подписка на событие срабатывает в любом случае. Учи матчасть. В сад.

    2. не способна, так как и не требовалось по условиям матча. Остальное пох. опять же ва сад.

    Reply ↓
  17. ValentinV

    Любопытно.

    А пику. Есть ли какие законченные продукты для управления проектами?

    Я знаю только: http://v8.1c.ru/solutions/product.jsp?prod_id=32

    Уж по деньгам кусаеться.

    Надо бы заценить вашу идею.

    Reply ↓
  18. Поручик

    >>>> 2. Кто нить пробовал наложить фильтр на журнал регистрации в случае активной работы? И вы еще хотите туда что-то еще добавлять? и как это потом анализировать?

    Кстати для этих целей я внедрил в конфу быстрый журнал регистрации.

    http://infostart.ru/projects/3904/

    С сабжем добавление не связано.

    Reply ↓
  19. Magister

    Завтра в работу пустим, посмотрим как покажет себя ))

    Из найденного — не регистрирует изменения для ПВХ и планов счетов, ошибка на строчках:

    Если МетаданныеОбъекта.Иерархический ….

    И

    Если (МетаданныеОбъекта.Владельцы.Количество() …..

    Нет для них таких свойств метаданных

    Reply ↓
  20. Поручик

    В этиx cтрoкax дoбaвить уcлoвиe ЭтоСправочник. Будет нopмaльнaя cвязь c ceтью, иcпpaвлю.

    Reply ↓
  21. Magister

    (20)

    та это понятно, я для себя исправил уже.

    да, ещё — не регистрирует изменение констант. мне в принципе не особо надо было, поэтому не дорабатывал — но теоретически было бы неплохо.

    Reply ↓
  22. Поручик

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

    Reply ↓
  23. V1V

    Чем не устроил типовой механизм версионирования? Позволяет не только видеть какие реквизиты менялись, что менялось, но также проводит сравнения и откатываться на любую версию. Да и кода многова-то…

    Reply ↓
  24. Поручик

    (23) Версионирование где? В УПП? Есть такое, начиная с релиза 1.2.23

    А в других конфах?

    Или он, по-твоему, зашит на уровне платформы или появляется по щучьему велению?

    Reply ↓
  25. V1V

    (24) А в других «конфах» можно эту идею реализовать с минимальными изменениями. Либо дождаться очередного релиза, благо не долго ждать.

    Reply ↓
  26. Поручик

    Желающие, конечно, могут подождать. Учитывая расторопность 1С

    Reply ↓
  27. artbear

    (25) Совершенно не уверен, что 1С будет подобные «идеи» реализовывать во всех типовых конфах.

    Например, ИМХО в БП им это нафиг не нужно, до сих пор механизм полезнейший механизм свойств не добавили 🙁

    В ЗиК-е вполне могут добавить, хотя также очень сомневаюсь.

    (23) Кода многовато? ты в УПП-то код версионирования видел? 🙂

    Reply ↓
  28. Поручик

    Изменений в коде нет.

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

    Reply ↓
  29. Поручик

    Изменения в коде после одной массовой обработки справочника.

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

    Reply ↓
  30. SunnyCat

    А как бы еще добавить отслеживание изменений в Регистрах сведений? Ладно те, которые регистраторам подчиняются — в большинстве случаев все изменения можно в документах увидеть, а у нас еще есть такие, куда пользователи ручками изменения вносят — изменения налоговых ставок, вычетов НДФЛ, периодических констант и много чего еще, так вот хотелось бы видеть кто, что и когда внес, изменил. По аналогии сделать не удалось — в событиях ПриЗаписи и Запись есть только Отказ и Замещения, сами данные-то не передаются. Киньте идею как реализовать, чтобы данные так же заносились в журнал регистрации? (конфа зарплатная, не типовая, написана на заказ)

    Reply ↓
  31. artbear

    При использовании этой схемы в 8.1.15/14 мои пользователи стали жаловаться на постоянные блокировки

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

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

    А прежний объект — это ведь ссылка, и идет получение инфы из базы.

    Перевел код на использование запросов, блокировки исчезли.

    Reply ↓
  32. Поручик

    (31) Значит, мне ещё везёт, сам таких жалоб не слышал. Будет время, займусь переписыванием.

    Reply ↓
  33. artbear

    (32) Могу выложить готовый код.

    В мыло или в личку или в аську.

    Reply ↓
  34. Поручик

    (33) Кинь в личку, завтра может помозгую.

    Как раз собираюсь конфу обновлять.

    Reply ↓
  35. Поручик

    Не знаю, кому это ещё нужно, но выложил обновлённый вариант с чтением реквизитов запросом.

    Reply ↓
  36. Yasen

    Идея хороша, но изнутри транзакции проведения документа писать лишнее в журнал регистрации — не айс. Это далеко не самый быстрый объект.

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

    Reply ↓
  37. Поручик

    Не спорю, но заморачиваться уже нет особого желания и времени.

    Reply ↓
  38. sound

    (35) Мне надо. То есть тут не последняя версия?

    Reply ↓
  39. Поручик

    (38) Это и есть последняя версия. Та, которую протестил в прежней конторе, перед выпиливанием оттуда.

    Reply ↓
  40. sound

    (39) А все .. понял, сорри, не увидел что текст запроса кусками формируется

    PS блин так неудобно стало когда обработку от обсуждения отделили…

    Reply ↓
  41. Vovanich

    Тема актуальная.Кстати в какой модуль это прикручивать?

    Reply ↓
  42. Поручик

    (41) Расскажу за деньги, если читать не умеешь.

    Reply ↓
  43. Vovanich

    Спасиба почитал повнимательнее в том числе код.)))

    Reply ↓
  44. seandr

    Очень простое и гибкое решение… нечто подобное для 7-ки делал в свое время, правда без подписок на событие естетственно ))). По поводу блокировок — ни я ни пользователи не заметили проблем.

    Reply ↓
  45. Поручик

    (44) Как эту статью вижу, так сразу вспоминаю контору, в которой тогда работал. Не от хорошей жизни пришлось выдумывать и прикручивать.

    Reply ↓
  46. wwizard

    Пожалуйста подскажите тому кто не понимает, а очень надо: в каком документе/модуле это все надо дописать?

    Reply ↓
  47. Поручик

    (46) Обратитесь лучше к специалисту, не то донаписываете.

    Reply ↓
  48. Kaniman

    Спасибо! особенно, что просто приведен код для вставки в конфигурацию. То, что надо!

    Reply ↓
  49. Люпин

    Статья супер! Очень пригодилось! Спасибо огромное автору!

    Reply ↓
  50. Поручик

    Кстати говоря, на 8.2 в режиме управляемого приложения, приведенный код будет исполняться на клиенте. В 8.1. с этим в порядке, исполнение идёт на сервере.

    Reply ↓
  51. StepByStep

    В 8.2 в управляемом приложении в ряде конфигураций появилась сущность «блокируемые реквизиты», т.е. реквизиты, которые нельзя/не рекомендуется изменять после того, как «элементы» (типа Справочника, ПВХ) используются в документах.

    Reply ↓
  52. FlyLink

    Прикрутил. Все супер!

    Reply ↓
  53. Поручик

    Что-то волна пошла. Это поделие ещё кому-то интересно?

    Reply ↓
  54. logarifm

    Из этого всего страдает самое важное — ПРОИЗВОДИТЕЛЬНОСТЬ!!!

    ИМХО — надо использоввать ПОДСИСТЕМУ «Версионирование» предложенною самой 1С.

    Reply ↓
  55. echo77

    (54) Надо, только её нет в БП, УТ, и куче других не топовых типовых 🙂

    Reply ↓
  56. the1

    Я, пожалуй, попробую запилить в свою конфу, посмотрим, как дело пойдет =)

    Reply ↓
  57. the1

    Запилил, все работает! Спасибо большое, а то админы давно просили. Единственное, что я добавил, так это возможность вкл/выкл возможность записи в журнал регистрации по значению константы «Вести дополнительный журнал регистрации», мало ли тормоза нарисуются в будущем. А так респект!

    Reply ↓
  58. the1

    И да, реально не хватает контроля записи в РС, например Контактная информация или Ответственные лица. Как бы реализовать, нет мыслей?

    Reply ↓
  59. webester

    Получилось неплохо. Я тоже сделал но мой код все таки немного хуже оказался, может даже заберу твой, зафигачу к себе после обработки напильником. Кароч, жирный «+», жаль нельзя два поставить.

    Reply ↓
  60. xzorkiix

    (58) the1, Подпись на события перед записью не предлагать? (в рамках обсуждаемого решения)

    см. справку по РегистрСведенийНаборЗаписей

    метод Метаданные() у объекта есть, см. Имя Регистра, определяем нужно ли по нему вести историю

    Отбор — доступен, через него можно же получить текущее состояние ИБ

    Сравнить Источник и Текущее состояние в ИБ.

    Reply ↓
  61. MartyNSK

    Буду пробовать у себя в конфе, спасибо за инфу!

    Reply ↓
  62. timm00

    Сделано «для себя») подправить?

    Reply ↓
  63. Al-X

    Спасибо. Внедряю у себя…

    Reply ↓
  64. Поручик

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

    Reply ↓
  65. Aleksey.z

    (64) Да вот все ждем когда 1С займется средой разработки. Давно пора журнал регистрации вести в СУБД и серьезно его доработать.

    Reply ↓
  66. Silenser

    Решение интересное, но с оговоркой, для больших баз лучше использовать подсистему версионирования из БСП.

    В типовом варианте сериализация в XML и сохранение в регистр работать будет значительно быстрее, а значит вероятность получить дедлок существенно меньше, т.к. в обоих случаях работаем в рамках транзакции записи.

    Reply ↓
  67. the1

    Вываливается в ошибку в серверном варианте работы базы «Попытка передачи мутабельного значения с клиента на сервер», т.к. подписка на события находится в общем модуле Клиент (обычное приложение) и Сервер, а регистрация изменений происходит в ОМ Сервер. Что бы такого лучше сделать?

    Reply ↓
  68. Поручик

    (67) Внимательно прочитать тему и снять флажок сервер с модуля.

    Reply ↓
  69. the1

    (68) внимательно прочитал еще раз

    Добавить в какой-либо общий модуль функцию и процедуру

    добавил

    флажок сервер с модуля

    а вот это не катит, иначе как у меня будет работать модуль, если его вообще нЕоткуда вызвать?!

    Может, подписки и регистрацию изменений разместить в одном модуле?

    Reply ↓
  70. Поручик

    (69) 300 рублей и займусь вашей проблемой.

    Reply ↓
  71. the1

    (69) Таки добавил в один модуль, вроде все работает. Буду тестить…

    (70) Думаю, сам разберусь 😉

    Reply ↓
  72. ab471vi

    Спасибо, мне очень пригодилось на управляемых формах!!!

    Reply ↓
  73. adream77

    Понравилось, попробую по возможности.

    Reply ↓
  74. MaximKor

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

    Reply ↓
  75. user730384

    Спасибо)

    Reply ↓

Leave a Comment

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