Подсистема хранения внешних файлов




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

32 Comments

  1. Ponommax

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

    Reply
  2. sovital

    Потому что подсистемы в БСП пересекается с функционалом УПП (объекты называются одинаково). Для примера ради, попробуйте прикрутить функционал обмена данными из БСП к УПП. Вам придется всю УПП перепахать, вдоль и поперек, к примеру при внедрении 1С:MES.

    Reply
  3. maxkisa

    (2)

    Зачем же так категорично? 🙂

    УПП пересекается со старыми версиями БСП… а для новых предназначено ERP.2.0

    Reply
  4. sovital

    (3) maxkisa, честно сказать не понял я что такого категоричного сказал.

    Смотрите, основная задача подсистемы было внедрение функционала без изменения базового (для облегчения обновления). Предложенный вариант (и вами поддерживаемый) подразумевает под собой постоянную головную боль при обновлениях. Мое мнение, что подсистема должна быть полностью изолированной, со своими точками входа и выхода. Ее функционал ни коим образом не должен мешать функционалу других подсистем. К сожалению, подобной модульности в 1С сложно добиться, но в некоторых случаях вполне решаемая задача, было бы желание.

    Reply
  5. pss1985

    не совсем понял из описания, подскажите, у вас доработки только в виде внешней обработки? или в конфигурации тоже что-то изменено?

    Reply
  6. sovital

    (5) pss1985, в самой конфигурации есть новые объекты, подписки, регистры сведений, формы и т.д. Обработка — это только для того, чтобы с этим работать не меняя конфигурацию стандартных форм.

    Reply
  7. sergey-201

    1) в упп это реализовано я так понял для электронного документооборота, и там есть такие полезности как : кто последний менял, кто сейчас редактирует. в вашем решении это также работает?

    2) а какие новые объекты появились, раз в УПП уже были объекты, такие как тома хранения файлов, справочник прикреленные файлы и т.д. Или у вас собственные справочники, модули, регистры, не пересекающиеся с типовым функционалом?

    Reply
  8. sovital

    (7) sergey-201, все верно, в УПП это все заточено только для хранения во внешнем хранилище информации и файлов по электронному документообороту.

    Функционал, который показывает блокировку элемента, кто последний редактировал также присутствует, даже выделение цветом заблокированного для редактирования файла имеется.

    Объекты добавляли из Управления Торговли 11, только префиксы им давали свои.

    Список добавленных объектов выложил в скриншоты к публикации.

    Reply
  9. sergey-201

    скачал, отлаживаю. наткнулся на

    {ОбщаяФорма.plr_ПрисоединенныеФайлы.Форма(267)}: Метод объекта не обнаружен (ОбновитьПрисоединенныйФайл)

    Если ПрисоединенныеФайлыКлиент.ОбновитьПрисоединенныйФайл(

    У меня в типовой УПП нет такой процедуры. Зато она есть в вашем модуле plr_ПрисоединенныеФайлыКлиент. Разъясните пожалуйста.

    Еще одно замечание, лучше сделать описание на установку правильных типов на реквизиты справочника plr_ПрисоединенныеФайлы. Например, когда объединил, там тип у реквизита Том стал строка. Хорошо, что есть БСП, там посмотрел по аналогии расставил все. Но не все могут догадаться залезть туда и посмотреть как там.

    Reply
  10. sergey-201

    при открытии формы Подчиненные справочники 1С валится с текстом «Самостоятельное использование формы не предусмотрено» и кнопки: завершить работу или перезапустить. Думаю такой случай корректнее должен обрабатываться без закрытия программы.

    Reply
  11. Alik_1c

    я бы реализовал примерно так

    если брать на примере спр. договоры контрагента

    1) добавил в свойства у контрагента путь к папке

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

    3)и переписать чуть чуть кнопочку файлы, что бы хранила просто элемент в справочнике

    Reply
  12. sovital

    (9) sergey-201, эта ошибка появляется после того, как подсистему отдельно вынес в отдельный cf. Соответственно нет типов в конфигурации, на которые он ссылается. Да косяк… если надо могу скинуть наш cf ник. Там будет работать, корректно.

    Reply
  13. sovital

    (11) Alik_1c, ни в чем себе не отказывайте 😉 Делайте так как вам хочется. Это восхитительное чувство, когда получается сделать то, что Вы задумали. Ставить новые задачи, выполнять их, достигать высот — это истинное счастье для человека. Но никогда не говорите, как бы вы сделали…

    Reply
  14. sovital

    (10) sergey-201, косяки к сожалению тоже унаследованы от УТ 11.1. Исправлю его после того, как проект перейдет на стадию поддержки, уровень не критичен.

    К сожалению блок планирования не получиться сделать в виде отдельной подсистемы, там вообще космос получается, разузлование плана производства по участкам из 150-200 штук номенклатуры с количеством переделов 15-17 происходит меньше чем за минуту.

    Эта в качестве затравки на следующие статьи.

    Reply
  15. sergey-201

    (12) так я не понял, что делать с ошибкой, которая появляется при записи элемента справочника ПодчиненныеФайлы. Мне надо вместо «Если ПрисоединенныеФайлыКлиент.ОбновитьПрисоединенныйФайл» заменить на «Если plr_ПрисоединенныеФайлыКлиент.ОбновитьПрисоединенныйФайл» ?

    Reply
  16. sergey-201

    (11) по вашему методу сложнее потом обновлять программу:

    1) в свойствах нет Бизнес-процессов и Задач. Мне как раз нужно хранить файлы по ним.

    2) если в базе есть другие используемые свойства, то придется разграничивать права между пользователями на разные виды свойств. тут думаю, придется вмешаться в типовой функционал. 3 ваш пункт, тоже затрагивает типовой функционал. чем понравилось это решение, так это именно новыми объектами, без изменения имеющихся. У меня старая УПП, в ней нет даже справочника Тома хранения файлов и всего этого функционала с присоединенными файлами, так что мне пришлось к этой публикации добавлять типовые модули и объекты из последней УПП. Попытался из БСП взять, но там потянулись модули и процедуры, которые не нужны.

    Reply
  17. sergey-201

    (14) Ошибка возникала в режиме обычного приложения. это я решил так: убрал в справочнике Основную форму элемента, Основную форму списка и Основную форму выбора.

    Reply
  18. sovital

    (17) sergey-201, а это хорошая идея!

    Reply
  19. sergey-201

    (18) я понял, на (15) не хотите отвечать. буду сам разбираться…

    Reply
  20. sovital

    (19) sergey-201, сорри, этот коммент как-то промелькнул. Давай я тебе свой cf вышлю… скинь мыло свое. У меня там вроде нет ошибок.

    Reply
  21. sovital

    (15) sergey-201, Я сейчас смотрел, не могу воспроизвести ошибку. Не подскажешь как на нее выходил? По логике, подменой на модуль plr_ проблема должна уйти. Вопрос только из какого модуля ошибка сыпется. Если из типового — то нужно подумать как лучше сделать. Подскажи, как ошибку воспроизвести. Сергей, ты как бета тестер у меня ) скоро платить надо будет )

    Reply
  22. sovital

    Еще в одном месте ошибку выявил. Буду думать как исправить. Выявляется при попытке заменить существующий файл файлом с диска.

    Reply
  23. sergey-201

    (21) У меня ошибка возникает когда: после прикрепления файла открывается форма «ПрисоединенныйФайл». я жму кнопку Записать и Закрыть: Метод объекта не обнаружен (ПолучитьНедопустимыеСимволыВИмениФайла). я нашел через остановку по ошибке, что валица здесь: «Если ПрисоединенныеФайлыКлиент.ОбновитьПрисоединенныйФайл»

    Reply
  24. sergey-201

    (22) имеешь ввиду через кнопку «Обновить из файла на диске»? я попробовал через нее, ошибки не возникло, но файл не обновился в каталоге.

    Reply
  25. sovital

    (24) sergey-201, косяки выловил, думаю как в отдельную подсистему выгрузить без потери типов у реквизитов справочника Присоединенные файлы. В навике это конечно проще, чем в 1С. Там объекты можно выгружать как есть.

    Reply
  26. sergey-201

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

    Reply
  27. sovital

    (26) sergey-201, если есть возможность подожди немного, я через поставку сейчас пытаюсь сделать.

    Reply
  28. as7815

    ВНИМАНИЕ!!!! Для тех кто решил скачать файлы.Реквизит «Том» справочника «plr_ПрисоединенныеФайлы» не правильно указан тип файла измените на СправочникСсылка.ТомаХраненияФайлов. А так обработка рабочая и удобная

    Reply
  29. sovital

    (28) as7815, спасибо

    Reply
  30. tireal

    так все же кто скажет почему при попытке открытии справочника «Прикрепленные файлы» метод модуля объекта вызывает закрытие базы ВызватьИсключение(НСтр(«ru = ‘Самостоятельное использование формы не предусмотрено.'»)); ?

    по мне он должен выдавать сообщение пользователю и все, т.е. это исключение должно быть восстановимое…

    Reply
  31. tireal

    сам и отвечу… При работе в режиме 1С:Предприятие могут возникать различные исключительные ситуации, связанные в функционированием прикладного решения. В зависимости от вида исключительной ситуации, работа приложения может быть продолжена или нет.

    Наличие синтаксической ошибки, например, в форме справочника, означает для системы невозможность создания одного из объектов прикладного решения (формы справочника). В этом случае стратегия продолжения работы отсутствует, и прикладное решение завершает работу.

    Reply
  32. Chif13

    да, все работает…

    (28) помимо Тома, еще поменяла Автора и Изменил на справочник Пользователи. Вроде все работает.

    Reply

Leave a Comment

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