Как с помощью конкретной технологии решить конкретную задачу? Или опыт разработки мобильного приложения на платформе 8.3.




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

21 Comments

  1. maxx

    Интересно спасибо!

    Единственное так и не понял за счёт чего все-таки ускорился обмен. Только лишь за счёт того вместо справочников воспользовались регистрами сведений? А почему как вы думаете?

    Reply
  2. pablo_escobar

    Я так понимаю обмен ускорился за счет того, что при использовании справочников выгружались остатки по все номенклатуре, а при использовании регистров сведений только изменившееся данные? Leo_A, вы что запустили в работу на мобильной платформе 8.3.6 (судя по скринам)? На 8.3.4 и 8.3.5 наблюдались ли произвольные вылеты приложения? Разрушение базы? У нас порядка 20 агентов, у всех периодически вылеты моб. платформы (1-2 раза в день) Иногда портится база, но это редко. Планшеты разные.

    Reply
  3. flyer

    Автор молодец! однозначно плюс. вижу что версия 8.3.6 не всякий бы решился на тестовой версии внедрять. если не сложно напишите про функционал подбора товара. что удобного сделано. была аналогичная задача. и на каких устройствах ставили программу.

    Reply
  4. Leo_A

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

    (2) pablo_escobar, про ускорение написал выше, а про версию платформы пожалуй расстрою Вас, т.к. на 8.3.6 делались только скрины, запуск же делался на 8.3.5. Но проблем с вылетами и убиванием базы проблем совсем не было. Устройства у всех агентов samsung galaxy tab 2. Про другие устройства к сожалению вообще ничего не скажу, т.к. это первый опыт. Единственное, запускал приложение на телефоне lenovo s860, но активно не работал.

    (3) flyer, спасибо, я не волшебник, я только учусь 🙂 Запускались на 8.3.5, в ближайшее время, если тестовая эксплуатация 8.3.6 пройдет хорошо, перейдем на нее, уж больно она глаз радует. С подбором пришлось немного похитрить, т.к. у клиента товар с характеристиками. Получилось все уложить в пределы одного экрана, чтобы не бегать между окнами, в остальном вроде все стандартно, кнопки ввода количества, отображение остатков и подобранного количества в таблице, открытие картинки товара по кнопке. Цели сделать универсальный механизм небыло, все писалось индивидуально, под требования клиента, а так, можно конечно расширить функционал подбора, например: подбор в упаковках, история продаж, выделение категорий товаров.

    Reply
  5. Makushimo

    Это введение к циклу статей?

    Reply
  6. qwed557

    Тоже интересует ответ на вопрос с порчей базы, У нас тоже бывало что портились базы у агентов, верней пока то случилось только один раз, но было сильно неприятно, когда потерялись заявки. Пока решили архивировать заявки за день в xml чтобы можно было быстро восстановить. Сколько по времени и как интенсивно работают агенты?

    Reply
  7. _Z1

    (0) Скажите а в каком формате хранит мобильное приложение данные ?

    т.е. это бд sqlite или что-то другое.

    Reply
  8. DitriX

    (7) в том же, что и стационарная файловая.

    По поводу регистров — не до конца понятно: вы вообще не пользовались справочниками или там хранили только ссылки?

    Reply
  9. maxx

    (4)так и не понял по скорости насчет регистров и справочников. С точки зрения выгрузки что 100 элементов справочника выгружать или 100 записей регистра думаю скорость будет одинаковой. С точки зрения загрузки , тут да запись 100 элементов будет медленней чем одна запись набора записей, но это речь идет о первоначальной загрузке только?

    Reply
  10. Leo_A

    (5) Makushimo, возможно. Если будет достаточно времени — постараюсь причесать приложение и выложу с кодом на обозрение.

    (6) qwed557, агенты работают уже с полгода, интенсивность не сильно высокая, заявок по 5-10 в день.

    (8) DitriX, в мобильное приложение выгружались все справочники, кроме номенклатуры и характеристик. Точнее справочник номенклатуры выгружался, но выгружались только группы, для сохранения иерархии, в регистре есть отдельное измерение «Родитель», по которому делается отбор.

    (9) maxx, не совсем так, выгрузка 100 элементов справочника выполняется в разы медленнее, чем выгрузка одного набора записей со 100 строками. Это особенность конвертации данных, возможно если писать свою выгрузку, большой разницы не будет. Теперь на счет загрузки. Как раз основной прирост скорости получился на этапе загрузки, по объектная запись 200 000 элементов выполнялась больше 20 часов, точно уже не скажу, просто в один момент устал следить за процессом и убрал планшет в стол, потом через пару дней увидел, что процесс завершился и даже удачно. Загрузка регистра с таким же количеством записей выполнилась за несколько секунд, я по началу даже подумал, что данные не выгрузились, но когда увидел, что они все же есть, приятно удивился. Еще один положительный момент в том, что размер файла выгрузки сильно меньше и всегда есть возможность при сбое выполнить полную очистку и загрузку данных прямо «в поле». Опять же, если писать обмен руками, размеры файлов думаю отличаться не будут, но скорость загрузки думаю не сильно вырастит.

    Reply
  11. Leo_A

    (6) qwed557, кстати до этого много работал с расширением для карманных компьютеров (РКК) от 1С на win mobile. Для одного из клиентов тоже писал выгрузку заявок в текстовый файл, т.к. база редко но падала.

    Reply
  12. LaNaite

    А проблема с «порчей базы» популярна, да? У меня она появилась недавно, после того как переписала с 8.3.4 на 8.3.5 с использованием фоновой передачи данных. Каждые 3 минуты из регистра сведений «сливалась» информация на сервер (порядка 50-100 записей). В этом регистре периодически появлялись строки с ошибкой «Объект не найден», и при очередной попытке записи — закрывалась текущая форма, и выкидывало на рабочий стол. Пересматриваю код, не могу понять к чему придраться. Использую не планы обмена, а web-сервисы.

    Reply
  13. Leo_A

    (12) LaNaite, какого плана информация сливается из РС, данные по заявкам от клиентов? Для какого типа объектов появляется надпись «Объект не найден»?

    Просто использование web-сервисов и планов обмена — понятия немного не связанные. Планы обмена предназначены для регистрации изменений, а web-сервисы для миграции данных.

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

    Reply
  14. LaNaite

    (13) Спасибо за отклик на проблему!

    У меня два регистра: «Контакты» и «КонтактыПереданные».

    РС «Контакты» не подчинен регистратору, периодичность «в пределах секунды».

    Измерения: «Отчет» — ссылка на одноименный документ.

    Ресурс: «Результат контакта» — ссылка на перечисление.

    «КонтактыПереданные» — дублирует регистр «Контакты».

    За 3 минуты в регистре может накопиться порядка 50-70 записей.

    Раз в 3 минуты я передаю все записи из регистра «Контакты» на сервер, дублирую их в регистр «КонтактыПереданные» и очищаю первый.

    (Все в транзакции).

    На веб-сервер передаю записи не по одной, а пакетом (таблицей).

    Одновременно могут работать около 100 пользователей.

    Для какого типа объекта появляется надпись «Объект не найден» — не могу понять. Если на планшете открыть регистр, то в нем сначала отображаются, например, 3 записи. Если отсортировать по любой колонке, то появятся еще несколько! Поле <Объект не найден 78921789hejkwh879> в ячейках отсутствует. Казалось бы нет битых объектов. Но при попытке открыть запись, появляется ошибка «Объект не найден».

    Я склоняюсь к корявому коду в реализации фоновых заданий. Может они в параллели как-то идут и конфликтуют. Буду ковырять пока здесь, т.к. до этого — проблем не было.

    Reply
  15. Leo_A

    (14) LaNaite, всегда рекомендую при явно воспроизводимой ошибке писать в 1С, это поможет и вам избавиться от проблемы и другим в будущем не напороться.

    Что касается ошибки, тип определить не сложно, достаточно вызвать ТипЗнч и даже для битой ссылки оно вернет корректный тип, можно начать с этого.

    Опять же не совсем понял, Объект не найден появляется на мобильном устройстве или в базе, в которую переносятся данные?

    Reply
  16. Яна44

    Leo_A, расскажите подробней пожалуйста как вы реализовали обмен приложения с центральной базой, если у них различные метаданные. Как вы доработали процедуры выгрузки/загрузки данных с использованием конвертации данных. Очень интересует этот вопрос, так как пишу диплом и передо мной стоит та же проблема обмена.

    Reply
  17. Leo_A

    (16) Яна44,

    Если Вы про доработку демо базы от 1С, то выгрузка/загрузка была реализована с использованием механизма конвертации. Правила для обмена пишутся с помощью конфигурации «Конвертация данных», куда выгружаются обе структуры конфигураций. В процедурах загрузки/выгрузки, с использованием типовой обработки встроенной во все типовые конфигурации «УниверсальныйОбменДаннымиXML» выполняется чтение пакета и этой же обработкой выполняется выгрузка в обратную сторону. Сжатое сообщение обмена передаются через пакет XDTO в переменной типа «DataStorge».

    Вот и вся концепция.

    Reply
  18. k4rimov

    Интересно.

    Вот только момент, что справочник Номенклатура загружается на устройство только в виде Групп.. а дальше, как подобрать конкретный элемент Номенклатуры? Или реализована on-line прогрузка данных по группе?

    Для работы в «поле» может быть критично, если данные не доступны offline, касательно торговых агентов, которые могут прийти к клиенту на Торговую точку в «подвал» или еще куда)

    А так есть куда расти — мерчендайзинг, предварительный сбор заказов, расширение CRM, майнинг лидов и тп.

    Будем последить)

    Reply
  19. Leo_A

    (18) k4rimov,

    Не совсем так, группы загружаются только для того, чтобы сохранилась иерархия справочника, все данные и ссылки на номенклатуру хранятся в регистре, т.е. в регистре есть измерение «Родитель»-по нему делается фильтр при переходе между группами и «Номенклатура»-ссылка на номенклатуру без фактического наличия объекта, а наименование, коэффициенты упаковок и прочая нужная информация для отображения и расчетов содержатся в ресурсах регистра. Никаких дополнительных подгрузок данных в поле не осуществляется, максимум загрузка свежих остатков при необходимости.

    Reply
  20. k4rimov

    (19)

    и «Номенклатура»-ссылка на номенклатуру без фактического наличия объекта, а наименование, коэффициенты упаковок и прочая нужная информация для отображения и расчетов содержатся в ресурсах регистра

    А ну понятно) Фактически, объект это совокупность его реквизитов и код) Вы просто грузите необходимые реквизиты объекта в регистр.

    Еще вопрос — т.е. все данные по одной номенклатуре у вас находятся в одном регистре? И единица измерения с коэффициентами и наименованием единицы тоже? Почему отказались от второго регистра, типа ЕдиницыИзмерения со списком всех единиц, и не стали хранить КлючЗаписи регистра ЕдиницИзмерения (описывающий экземпляр единицы изм.) в общем регистре с Номенклатурой?

    Reply
  21. Leo_A

    (20) k4rimov,

    Почему отказались от второго регистра, типа ЕдиницыИзмерения со списком всех единиц

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

    Я описал концепцию, остальное развитие естественно возможно, все же зависит от потребностей. На данном этапе просто не было необходимости создать универсальное приложение.

    Reply

Leave a Comment

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