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




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2024-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 не будет опубликован. Обязательные поля помечены *