ВСТАВИТЬ В Справочник.Номенклатура (Код, Наименование) ЗНАЧЕНИЯ ("001", "Новый товар")




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

54 Comments

  1. vasilev2015

    Перед исполнением запроса таблицы блокируются также, как бы это сделала СУБД ?

    Reply ↓
  2. m-rv

    (1) никаких специальных блокировок не накладывается, но цикл изменений происходит в одной транзакции.

    Reply ↓
  3. t.v.s.

    Идея отличнейшая!

    Для полного счастья не хватает конструкции

    ВСТАВИТЬ [ИЛИ ИЗМЕНИТЬ] <Имя таблицы> ВЫБРАТЬ ИЗ…
    Reply ↓
  4. m-rv

    (3) Запрос ВСТАВИТЬ (INSERT) ожидается, следите за обновлениями

    Reply ↓
  5. vano-ekt

    <Объект не найден>

    Reply ↓
  6. Dream_kz

    1С-никам не просто так запретили запросы на запись)

    Reply ↓
  7. kote

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

    Reply ↓
  8. baton_pk

    (10)

    это невозможно по определению

    не, ну… выгрузить конфу в файлы, поменять/добавить/удалить, загрузить обратно и обновить.

    Reply ↓
  9. baton_pk

    Идея — огонь! Сам ночами просыпался с мыслью сделать подобное!

    Reply ↓
  10. kote

    (11) потом выгнать всех пользователей, применить изменения, загнать всех обратно.. и обязательно не забыть на каком месте остановились, чтоб с этого же места продолжить.

    Reply ↓
  11. baton_pk

    (13) ну да. для этого ещё пара другая обработок. 🙂

    Reply ↓
  12. German_Tagil

    конфигурация КА 1.1 — не запустилось

    Reply ↓
  13. German_Tagil

    жааааль

    Reply ↓
  14. m-rv

    (16) уж не обычные ли это формы?

    Reply ↓
  15. German_Tagil

    пишу самый простой запрос

    изменить Документ.ЗаказПоставщику.Товары

    УСТАНОВИТЬ Проект = &ПроектН

    где Проект = &Проект

    вылетает по ошибке

    Reply ↓
  16. m-rv

    (19) текст ошибки в студию!

    Reply ↓
  17. German_Tagil

    формы обычные запускаю из конфигуратора управляемое приложение

    простой запрос

    типа

    ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ

    ЗаказПоставщикуТовары.Номенклатура,

    ЗаказПоставщикуТовары.Количество,

    ЗаказПоставщикуТовары.Заявка,

    ЗаказПоставщикуТовары.Проект

    ИЗ

    Документ.ЗаказПоставщику.Товары КАК ЗаказПоставщикуТовары

    ГДЕ

    ЗаказПоставщикуТовары.Проект = &Проект

    отрабатывает нормально

    Reply ↓
  18. German_Tagil

    1с ЛОЖИТСЯ

    Reply ↓
  19. German_Tagil

    1CV8.exe — обнаружена ошибка. Приложение будет закрыто. Приносим извинения за неудобства.

    Reply ↓
  20. m-rv

    (23) это что-то совсем страшное. а какая платформа?

    Reply ↓
  21. German_Tagil

    причем простой запрос

    на изменение реквизитов документа работает

    1С:Предприятие 8.2 (8.2.19.90)

    Reply ↓
  22. German_Tagil

    у меня как раз задачка достаточно простая есть под данную консоль

    Reply ↓
  23. m-rv

    (25) единственное что приходит в голову — начать построчную отладку и понять от какой конкретно инструкции платформа крашится.

    Reply ↓
  24. German_Tagil
    Reply ↓
  25. German_Tagil

    Функция СтрЗаканчиваетсяНа не нашел

    Reply ↓
  26. m-rv

    (29) это функции 8.3, в 8.2 их нет. недавно выкладывали их реализацию для подобных случаев.

    Reply ↓
  27. German_Tagil

    неправильно сформулировал извиняюсь — я понял что эти функции для 8.3

    а ссылку можете указать? подправлю — может взлетит

    Reply ↓
  28. German_Tagil

    Функция ВыполнитьПакет(РасширенныйЗапрос) Экспорт

    ИнициализироватьПараметрыРасширенногоЗапроса(РасширенныйЗапрос, Ложь);

    Запрос = ИнициализироватьЗапросПолученияДанных(РасширенныйЗапрос);

    МассивРезультатов = Запрос.ВыполнитьПакет();

    ВыполнитьИзменениеДанных(РасширенныйЗапрос, МассивРезультатов);

    Возврат МассивРезультатов;

    КонецФункции

    На ВыполнитьИзменениеДанных выносит

    Reply ↓
  29. German_Tagil

    посмотрел отладчиком

    ОбъектРедактирования.Записать();

    на этом ее и выносит

    Reply ↓
  30. German_Tagil

    функции СтрНайти,стрРазделить,СтрСоединить,СтрЗаканчиваетсяНа,СтрНачинаетсяС

    проверил в ка 2.4 — рабочие

    не вылетает

    Reply ↓
  31. m-rv

    (34)

    ошибка на строке

    ОбъектРедактирования.Записать();

    говорит о том, что проблема с записью самого объекта, при чем характер ошибки намекает на ее платформенную природу. попробуйде провалиться в обработчики/подписки перед/при записи.

    Reply ↓
  32. German_Tagil

    в общем похоже у меня база тестовая с ошибками была

    на другой заработало

    Reply ↓
  33. Necytij

    Я так понимаю эта красота скорости не добавляет, и сделана сугубо чтобы «скоротать вечерок» и по несколько минут на каждое МАССОВОЕ изменение реквизитов, которое по какой-то причине групповой обработкой править не получается. Честно говоря вообще тяжеловато понять суть тогда зачем в принципе такая вещь, если большую часть всего этого можно было сделать стандартными обработками чем извращаться создавая запрос через конструктор, потом менять текст вручную и программно парсить его обратно… Команду инсерт на 1 объект в итоге писать+запускать дольше чем просто открыть в режиме в 1С и создать вручную, нет?

    Лучше бы изменяемую схему СКД + групповое изменение, насколько помню уже давно есть такие консоли.

    Reply ↓
  34. m-rv

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

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

    соответственно, аналитики и консультанты теперь имеют альтернативный инструмент массового изменения данных. да и программисту по-короче набросать две строчки запроса, чем писать «запрос = новый запрос();…».

    Reply ↓
  35. m-rv

    (37) да, и что касается

    извращаться создавая запрос через конструктор, потом менять текст вручную

    так извращаться действительно нет смысла. если вы не можете набросать запрос без конструктора — переходить к запросам на изменение рановато..

    Reply ↓
  36. Necytij

    (38) Я свои ассоциации называть не буду. Но про хлеб — «на вкус и цвет», про Ауди — хотя бы разница в цене тут цена производительности таже, цена программирования очень спорна. Примеры, мне кажется, не подходят.

    Я и спрашиваю преимущества в чем? В том, что есть люди которым удобнее писать запрос вручную наизусть зная структуру имен полей? Чем перетащить из таблички? И по вашему ответу тоже не вижу ни одного реального примера. Представите хоть один реальный, значимый?

    Чем кстати этот инструмент шире по сравнению с хорошей групповой обработкой?

    «да и программисту по-короче набросать две строчки запроса», я тоже могу придираться к словам, а не вычленять их смысл. Запрос написанный в 2 стандартных коротких строчки запроса не задача для написания такого инструмента и даже изучения такого инструмента не стоит, имхо.

    Reply ↓
  37. zarucheisky

    (10) Тогда TRUNCATE

    Reply ↓
  38. echo77

    (0) Зачем это может пригодится? Можете привести жизненный пример?

    Reply ↓
  39. maxx

    Прикольно, мне кажется полезным может оказаться Веберам, которые с 1с приходится сталкиваться немного типа Номенклатуры или Контрагентов, а они знают чистый SQL

    Reply ↓
  40. Casey1984

    (42) Ого, только сегодня заметил эту разработку! Читаю это:

    «Поддерживается редактирование всех первичных таблиц:

    таблицы ссылочных типов (документов, справочников…)

    табличные части ссылочных типов

    регистры подчиненные и не подчиненные регистратору»

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

    Reply ↓
  41. Patrio_O_Muerte

    Руки оторвать за реализацию.

    Reply ↓
  42. m-rv

    (45) ваша лучше?

    Reply ↓
  43. Patrio_O_Muerte

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

    Конечно идея хорошая, но к таким вещам необходимо ограничивать доступ.

    Фирма 1С сколько ее не ругай сделала очень грамотный ход — она просто отказалась от реализации подобных возможностей из режима предприятия.

    Reply ↓
  44. m-rv

    (47) здесь, кстати, не в первый раз упоминают о том, что вот есть какие-то «Программисты 1С», которые щас все это возьмут и как начнут все портить!!!

    если серьезно, без шуток и ёрничания: в чем опасность? почему плохо, что такой инструмент будет у всех?

    Reply ↓
  45. m-rv

    (47) и согласитесь, пока сюда не начнет постить комментарии Сергей Георгиевич — о мотивах фирмы 1С мы ничего не узнаем.

    Reply ↓
  46. Darklight

    Вещь вполне интересная. Я буду в лагере тех, кто за такое и кто ждёт такого в будущих редакциях 1С: Предприятия уже во встроенном в платформу виде (но, конечно же, с уже оптимизацией проведение операций массовых изменений в данных — это очень был бы вотребовано на проектах с BIG DATA)! А кто говорит, что правильно, что 1С не добавила — обоснуйте в чём правильность-то, на мой взгляд они просто поленились.

    Reply ↓
  47. m-rv

    (50) с оптимизацией будут большие проблемы: если запрос ИЗМЕНИТЬ транслировать напрямую в UPDATE — выпадет целая область функциональности слоя платформы (подписки, события объекта, регистрация на планах обмена…). Хотя, может быть, можно что-то придумать, типа множественного аргумента в подписке как в команде…

    Reply ↓
  48. Darklight

    (51)Я согласен — оптимизировать сложно — это уже архитектурная задача для будущих редакций 1С Предприятие (скорее всего уже 9-го поколения, где, на мой взгляд, уже архитектурно должна быть заложена обработка не одиночных данных — а целых наборов (причём с предположением, что они могут быть очень большими) — во всех местах алгоритмов, в т.ч. в параллельном режиме). Это очень важный шаг на пути расширения облачных технологий и BIG DATA — это тренды начала XXI века.

    Reply ↓
  49. IsiKosta

    А если помечать на удаление, например «Справочник.Договоры», то процедура «ПередЗаписью» будет отрабатываться ?

    Reply ↓
  50. m-rv

    (53) будет

    Reply ↓
  51. muskul

    Зачем все хотят запросы на данные? что вы такого в таблицы пытаетесь записать.

    Reply ↓
  52. m-rv

    (55) это позволяет удобнее манипулировать данными в некоторых ситуациях. Не в коде писать, а в пользовательской консоли, когда надо подправить данных на внедрении или типа того..

    Reply ↓
  53. muskul

    (57) Приведите пример такой правки. Вот что напрямую легче.

    Reply ↓
  54. m-rv

    (58) ну заливали данные в новую базу, продолбали ИспользованиеХарактеристик у номенклатуры. Решение в консоли:

    ИЗМЕНИТЬ Справочник.Номенклатура

    УСТАНОВИТЬ ИспользованиеХарактеристик = ВидНоменклатуры.ИспользованиеХарактеристик

    ГДЕ НЕ ИспользованиеХарактеристик = ВидНоменклатуры.ИспользованиеХарактеристик

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

    Reply ↓

Leave a Comment

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