Конфигурация: Журнал регистрации




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

36 Comments

  1. Очень неплохо!

    Было бы еще круто сделать автоматическое подключение к базе и сохранение логов. + сокращение журнала на дату.

    Чтобы это запускалось регламентно.

    Еще — нет возможности вести в одной базе несколько логов из разных баз! 🙁 а это бывает нужно…

    Reply ↓
  2. echo77

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

    Возможность вести в базе логи нескольких баз изначально была, но от неё я отказался, в пользу получения более быстрых отчетов и более быстрой загрузки данных в БД(изначально журнал за месяц у меня грузился 1 час). Я предполагал хранить базу в файловом варианте — чтобы получить более высокую скорость формирования отчета.

    p.s. Народ, если попробовали, укажите пожалуйста, какого размера(средний размер) у вас выгруженный журнал за месяц, и сколько по времени вы грузили этот журнал в БД с приведенной в публикации конфигурации

    Reply ↓
  3. (2) Автоподключение: Рассмотрим вариант когда несколько баз. Необходимо создать справочник настроек подключения к базе (можно назвать: «Информационные базы») — этот справочник будет делить все данные в регистре и будет являться владельцем остальных справочников с данными.

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

    при создании настройки ИБ и включении галочки «автообмен» — должно создаваться регламентное задание (посмотри как сделано в стандартном обмене в УТ, БП, ЗУП, УПП). Так же можно было бы запускать обмен вручную.

    Несколько баз: думаю если ввести индексы то для больших объемов данных будет довольно быстро работать.

    Reply ↓
  4. echo77

    (3) При текущей организации регистра процесс удаления записей из него за период будет достаточно долгим

    Reply ↓
  5. (5) а зачем удалять данные? например если требуется хранить журнал регистрации…

    но если установить отборы, удаление должно быть очень быстрым…

    Reply ↓
  6. echo77
    а зачем удалять данные?

    Что тогда подразумевается под этим? :

    сокращение журнала на дату.
    Reply ↓
  7. echo77

    (3) Немного приблизил ваше желание к жизни 😀

    Reply ↓
  8. (7) я имел ввиду сокращение журнала регистрации в реальной базе — т.к. он растет и логи растут и это может занимать много гигабайт!

    т.е. такая база нужна для того чтобы слить в нее журнал регистрации, а в реальной базе удалять журнал.

    — было бы все неплохо хранить даные из разных баз (спр.ИнформационныеБазы — в нем хранить все настройки для подключения и этим справочником делить все данные в регистре (и сделать владельцем справочников). ввести индексацию данных в регистре и все должно быстро летать!)))

    (8) спасибо! погляжу!…

    Reply ↓
  9. John83

    В журнале не отображаются изменения в константах. Это так задумано?

    Reply ↓
  10. echo77

    (10) В журнал не грузятся данные об изменениях в регистрах — так задумано, возможно это не корректно.

    Константы теперь грузятся 🙂

    Добавил справку в отчет(5 примеров).

    Reply ↓
  11. kaging

    А не подскажите где взять КонсольЗаданий 🙁

    Reply ↓
  12. John83

    (12) на диске ИТС

    Reply ↓
  13. John83

    по-моему было бы еще неплохо следить за изменениями в регистрах сведений

    Reply ↓
  14. echo77

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

    Но по скольку, в журнал регистрации попадают очень не детальные данные об изменени записи регистра — я решил отказаться от загрузки в базу этой информации

    Reply ↓
  15. Алексей777

    Здорово работает. А вот когда загружаешь данные из 8.2, то уже сконвертированная конфигурация на 8.2 обработкой ЗагрузитьДанныеXML выдает ошибку:

    {Обработка.ЗагрузитьДанныеXML}: Ошибка чтения журанала регистрации: C:Documents and SettingsАдминистраторМои документыФайл.xml

    {Обработка.ЗагрузитьДанныеXML}: Ошибка при вызове метода контекста (ПрочитатьXML): Ошибка преобразования данных XML

    ВызватьИсключение Ошибка;

    🙂

    Вот!

    Reply ↓
  16. kaging

    Хотелось бы вот что еще уточнить: через консоль заданий ставлю в определенное время догружать журнал, ничего не грузит, может что то не так делаю, подскажите плиз. Огромное спасибо.

    Reply ↓
  17. John83

    (17) а напрямую грузит?

    Reply ↓
  18. Алексей777

    Ошибка происходит для следующих данных:

    <v8e:Event>

    <v8e:Level>Information</v8e:Level>

    <v8e:Date>2010-08-18T18:10:31</v8e:Date>

    <v8e:ApplicationName>1CV8</v8e:ApplicationName>

    <v8e:ApplicationPresentation>1С:Предприятие</v8e:ApplicationPresentation>

    <v8e:EventName>_$Access$_.AccessDenied</v8e:EventName>

    <v8e:EventPresentation>Доступ. Отказ в доступе</v8e:EventPresentation>

    <v8e:UserID>0cb84f4c-4b34-45bc-9134-2ff3a0a46d82</v8e:UserID>

    <v8e:UserName>Белоусова Елена</v8e:UserName>

    <v8e:Computer>ZEUS</v8e:Computer>

    <v8e:MetadataName>

    <v8e:Item>Catalog.НастройкиВыполненияОбмена</v8e:Item>

    </v8e:MetadataName>

    <v8e:MetadataPresentation>

    <v8e:Item>Справочник. Настройки выполнения обмена</v8e:Item>

    </v8e:MetadataPresentation>

    <v8e:Comment/>

    <v8e:Data xsi:nil=»true»/>

    <v8e:DataPresentation/>

    <v8e:TransactionStatus>NotApplicable</v8e:TransactionStatus>

    <v8e:TransactionID/>

    <v8e:Connection>2520</v8e:Connection>

    <v8e:Session>4992</v8e:Session>

    <v8e:ServerName>SUPERX</v8e:ServerName>

    <v8e:Port>1662</v8e:Port>

    <v8e:SyncPort>1664</v8e:SyncPort>

    </v8e:Event>

    Как раз на <v8e:MetadataName> — чтение заканчивается, т.к. <v8e:Item> — следующий уровень структуры, а глубина чтения до этого уровня структуры не предусматривалась?

    Reply ↓
  19. kaging

    напрямую грузит все нормально

    Reply ↓
  20. echo77

    (19)

    Как раз на <v8e:MetadataName> — чтение заканчивается, т.к. <v8e:Item> — следующий уровень структуры, а глубина чтения до этого уровня структуры не предусматривалась?

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

    (17) База данных «Журнал регистрации» работает в клиент-серверном варианте? Может быть вы не включили задание, может быть что-то не так настроили в расписании задания

    Reply ↓
  21. cap77

    Привет, попробовал конфигруцию, вылетает по ошибке :

    «{Обработка.ЗагрузитьДанныеXML ( 1128 )}: Ошибка чтения журанала регистрации: E:jurnalЖурнал регистрации1.xml

    {Обработка.ЗагрузитьДанныеXML ( 1237 )}: Ошибка при вызове метода контекста (Записать): Код не уникален!

    »

    Пробовал и из XML и напрямую из базы.

    Reply ↓
  22. echo77

    (22) У вас в базе что-то с событиями. Откройте справочник «События» и посмотрите что там с кодами. Можете попробовать в конфигураторе для того же справочника увеличить длину кода. Видимо, у вас в базе полно разнообразных видов событий.

    Reply ↓
  23. cap77

    Все получилось, спасибо.

    Reply ↓
  24. echo77

    (24). В личку можете скинуть таблицу того что у вас хранится в справочнике «События».

    Если вам понравилась конфигурация — можете плюсануть

    p.s. Есть ли нужда в видео-уроках о том как работать с конфигурацией? Как посмотреть отчет по тем или иным данным.

    Reply ↓
  25. ВНедреНеЦДубль

    Здравствуйте)

    Конвертировал в 8.2, при старте загрузки напрямцю

    {Обработка.ЗагрузитьДанныеXML.МодульОбъекта(81)}: Ошибка открытия журанала регистрации: C:<путь>v8_31C8_e.xml

    {Обработка.ЗагрузитьДанныеXML.МодульОбъекта(531)}: Неверный формат выгрузки журнала регистрации

    ВызватьИсключение Ошибка;

    Reply ↓
  26. Jogeedae

    вводная:

    выгружаем/режем журнал раз в сутки.

    размер lgp-файлов от 100Мб до 2Гб.

    регистируем всё подряд.

    проблема:

    чтение этих файлов.

    1) открытие страницы журнала больше 500Мб занимает от получаса до бесконечности.

    2) отборы, переход на другую запись также занимает уйму времени, а порой и вовсе не возможно.

    3) Пробовал Вашу обработку для этих целей — то же самое, к сожалению.

    Reply ↓
  27. KVS

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

    Reply ↓
  28. John83

    (28) «и после загружаем olap» — можно чуток по-подробней?

    Reply ↓
  29. echo77

    (27) Отбор хорошо работает по реквизиту «данные». Попробуйте в конфигурации Журнал регистрации включить индексирование для интересующих вас измерений/ресурсов регистра сведений

    Reply ↓
  30. scanner1980

    При попытке загрузки журнала из 8.2

    {Обработка.ЗагрузитьДанныеXML(1128)}: Ошибка чтения журанала регистрации: Журнал регистрации.xml

    {Обработка.ЗагрузитьДанныеXML(1057)}: Неверный формат

    Reply ↓
  31. echo77

    (31) Обратите внимание — конфигурация для работы с конфигурациями на платформе 8.1

    Для 8.2 есть честно скопированная и подправленная конфигурация в соседней теме

    Reply ↓
  32. scanner1980

    Отчет по журналу регистрации:

    1. открываем,

    2. нажимаем сформировать

    3.все работает.

    1. Заходим в конструктор,

    2. убираем все поля,

    3. добавляем все поля,

    4. ОК,

    5. Сформировать — Ошибка.

    1. Заходим в настройки отчета

    2. Загрузить стандартные настройки

    3. ОК

    4. Сформировать

    5. Отчет пустой

    Хотя ошибки и не критичные

    Reply ↓
  33. hanio

    а как то поподробнее можно про строку соединения у меня 8.2 и она вываливается если я пишу соедиение что-то типа этого — Srvr=»atlantis»;Ref=»smit_torg»;Usr=»Юзер»;Pwd=»пасс»; Что тут не так???

    Reply ↓
  34. echo77

    (34) Конфигурация не предназначена для работы с базами на платформе 1С 8.2

    Reply ↓
  35. anton-1c

    Зачёт!

    Reply ↓
  36. simuljakr

    Автору — спасибо.

    Файл выгрузки — 2 гига загрузился за 1:11:46

    Reply ↓

Leave a Comment

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