Вывод и печать таблиц и списков значений для 1С 7.7




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

37 Comments

  1. Ёпрст

    >>>данные могут не обновляться при переходе между колонками

    Это не бага, это многолетний баян..

    Лечение — в одной строчке кода..

    Reply
  2. CheBurator

    (1) Типа как в кресте на ТЗ..?

    Reply
  3. CheBurator

    (0) Не вижу сохранений сделанных настроек вывода ТЗ — если я много раз вывожу одинаковую по структуре ТЗ — я что, не могу воспользоваться заранее сделанной в первый раз настройкой??? Низачот!!! 😉

    .

    сформируй для ТЗ уникальный ИД из наименований и типов колонок — и используй его…

    Reply
  4. Angelike

    [от имени Aexeel (аккаунт залочен, почему-то)]

    (1) Просто раньше не встречалось, вот и не знал. Исправлю, как разлочат. Спасибо за информацию.

    (3) В плане доработок, но не на первом месте. Так часто пользуешься отборами? Обычно это разовая операция. Гораздо важнее просмотр подчиненных ТЗ. А это реализовано.

    Reply
  5. aexeel

    Все разлочили. Счастье.

    (3, 4) Аналогичная ситуация с сохранением списков сортировки и видимости колонок. Под это дело, кстати, создан неиспользуемый пока слой «Невидимый».

    Reply
  6. Shaman100M

    (1) А как, интересно? Две невидимых кнопки на форму с горячими клавишами, или попроще?

    Reply
  7. Ёпрст

    (6) проще.

    Форма.Обновить в функции на тексте… Можно и по условию.

    Reply
  8. aexeel

    (7) Проблема как раз в том, что формула («функция на тексте») не вызывается.

    Reply
  9. aexeel

    Обновил обработку. Изменения в текущей версии:

    — исключена оставленная ранее отладочная информация;

    — обработка больше не требует наличия в том же каталоге обработки-редактора условий отбора (в предыдущей версии она также не использовалась);

    — при попытке вызова без указания в параметре формы списка или таблицы значений выдается соответствующее предупреждение и обработка не открывается;

    — на закладках «Структура» и «Данные» выведены краткие подсказки.

    Reply
  10. Арчибальд

    Автор, послушайся Ёпрста и Чебура. Они плохому не научат ;))

    Reply
  11. aexeel

    (10) Я сторонник политики Эппла: мнение пользователя, конечно, важно, но делать мы будем всё равно по-своему :))

    А если серьезно, мнение Чебура, конечно, правильное — сохранению настроек быть. Но вот предложенное решение слегка поверхностное. ИД по имени-типу исключит отборы при незначительном изменении структуры (например, в процессе разработки добавили/удалили колонки, по которым отборы и не строились даже). К тому же, как я и написал раньше, пользоваться им будут единицы, а вот просмотр вложенных списков/таблиц куда более актуален. Да и сам отбор еще не до конца доделан. В следующем плановом обновлении будет отбор по (не)вхождению в список и в числовой интервал.

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

    Reply
  12. aexeel

    Обновил пример использования. Теперь в нем можно выбирать способ вызова обработки обработки: из внешнего файла или внутренней обработки. В первом случае необходимо будет указать полное имя файла (можно выбрать в соответствующем диалоге), во втором — идентификатор обработки (можно выбрать из списка).

    Reply
  13. Ёпрст

    (8) >>>(7) Проблема как раз в том, что формула («функция на тексте») не вызывается.

    Ну ё… Форма.Обновить() воткни — будет вызываться всегда..

    Reply
  14. aexeel

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

    Reply
  15. aexeel

    (15) у себя проверял? уже несколько раз написал, что у меня не ловит перемещение между (!!!) колонками (!!!) таблицы на форме. При перемещении между строками той же таблицы все работает.

    Reply
  16. Ёпрст
  17. aexeel

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

    Чтобы быть до конца уж откровенным, при последующем переходе между строками , работать стало.

    Reply
  18. Altair777

    (2) Ой, и меня упомянули. Мелочь, а приятно 🙂

    Reply
  19. aexeel

    (17, 18): аналогичная проблема с любой другой строкой, которая становится текущей при открытии формы. Добавление метода в «ПриОткрытии()», «ВводНового()» или модуль инициализации не помогает. Пробовал даже программно менять закладки и в «ПриВыбореЗакладки» вызывать обновление формы, но результат тот же.

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

    Reply
  20. Altair777

    (20) Юзайте Формекс «ПослеОткрытия()» и будет Вам счастье. 🙂

    Reply
  21. aexeel

    (21) Переход к использованию ВК равносильно отказу от универсальности. В этой обработке я стремлюсь, скорее, к последнему. А за «+» спасибо. Хоть я и не сторонник рейтинговых систем, но, ИМХО, она того стоит.

    Reply
  22. Ёпрст

    (18) Детсад на марше ?

    Не умеешь затавить обновится форму при открытии?

    Чего, уже всё надо разжевывать?

    Reply
  23. Ёпрст
  24. aexeel

    (23, 24) Блин, круто. Не знал. Спасибо.

    Reply
  25. artbear

    (22) Про ВК и отход от универсальности зря говоришь.

    Как раз некоторые ВК и позволяют достичь универсальности 🙂

    Reply
  26. artbear

    Посмотри автора ADirks здесь и/или на проклубе, у него давно уже есть отличный «Редактор ТЗ», в котором нами сделано очень многое, в т.ч. и просмотр, и печать, и редактирование ТЗ, СЗ и даже ИТЗ из 1С++.

    Reply
  27. aexeel

    (26) Только давай без холивара на тему ВК :)) Согласен, они значительно расширяют функциональность, но вносят дополнительные требования к установленному набору. Даже если будешь постоянно носить все с собой (у военных, например, Интернет не подключен вообще), ни факт, что дадут права админа, чтобы это дело установить (фанатичная шизофреничность безопасников это обыденное явление).

    (27) Это не редактор, а просмотр и работа с отборами/сортировками у меня реализована лучше, на большее пока не претендую.

    Reply
  28. Altair777

    (28) Не думаю, что с тем же FormEx’ом, например, могут быть проблемы при установке.

    Reply
  29. aexeel

    (29) м.б., но в данном случае удалось решить проблему без его использования

    Reply
  30. Altair777

    (30) Я раньше тоже был противником ВК.

    Первое, что пришлось использовать — это 1С++ и только ради одного метода ReconnectNative().

    Но жизнь в лице заказчиков(работодателей) заставляет совершенстоваться.

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

    Не потому, что я отучился по-другому, а просто потому что их нельзя сделать иначе.

    Кстати, и в своей повседневной работе тоже тяжко без OpenConf, Телепат, Colorer и т.д.

    Reply
  31. aexeel

    (31) OpenConf, Телепат, Colorer использую сам, благо влияют они только на процесс, а к конечному продукту они не имеют непосредственного отношения.

    >> Я раньше тоже был противником ВК

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

    >> ReconnectNative()

    Прям на больную мозоль стал :). Согласен, проблема реконнекта у нас решена не самым оптимальным способом. Но решена и прирост производительности есть.

    Reply
  32. Altair777

    (32) А, понятно. Если запрещено, тогда да…

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

    И такая разработка, удет быстрее всего и красивее, и быстрее.

    Reply
  33. vligm

    Понравилось.

    Есть пожелание — для документов сделать отбор по списку.

    А еще лучше — по подчиненным для какого-либо дока.

    Это так, на вскидку в ключе моих личных проблем :-)))

    Reply
  34. aexeel

    (33)Спасибо за отзыв и «+»

    >>отбор по списку

    Вроде где-то в комментах упоминал. Первая в очереди (уже в процессе разработки т.е.). Скоро будет. Следите за обновлениями.

    >>подчиненным для какого-либо дока

    Тоже запланировано, но следующим этапом, т.к. связано со отбором по списку

    (34) 🙂 «там где можно обойтись, стараюсь обходиться».

    Насчет быстрее/красивее очень спорно. Говорить о скорости при интерактивной работе при текущем уровне развития выч. средств не шибко актуально. Самой медленной составляющей системы в этом случае остается пользователь.

    Кстати, в тему загрузки процессора (тоже где-то раньше было). Погонял на разных машинах. В принципе, не сильно-то он и загружается при обновлении формы. Так что, еще раз спасибо Ёпрсту, окончательный вариант вполне работоспособен.

    Reply
  35. vligm

    я часто использую в таблицах «ЗначениеВСтрокуВнутр»

    Для просмотра списков и таблиц, упакованных таким образом, я добавил немного кода в процедуру

    «ТЗ_Форма_ОбработкаВыбора()»:

    ИначеЕсли ТипЗначенияСтр(ЗначТекЯчейки) = «Строка» Тогда

    Если (Лев(ЗначТекЯчейки,5) = «{«»VT»»») ИЛИ (Лев(ЗначТекЯчейки,5) = «{«»VL»»») Тогда

    Данные = ЗначениеИзСтрокиВнутр(ЗначТекЯчейки);

    КонецЕсли;// Если Лев(ЗначТекЯчейки,5) = «{«»V…

    СпПараметров = СоздатьОбъект(«СписокЗначений»);

    СпПараметров.Установить(«ЗаголовокОбработки», ЗаголовокОбработки + » -> R» + НомТекСтр + «C'» + ИмяТекКол + «‘»);

    СпПараметров.Установить(«Данные», Данные);

    СпПараметров.Установить(«ИмяВнутрОбработки», «Undef»);

    Если ПустаяСтрока(ПолнИмяФайлаОбработки) = 0 Тогда // внешняя обработка

    ОткрытьФорму(«Отчет#», СпПараметров, ПолнИмяФайлаОбработки);

    Иначе

    Попытка

    ОткрытьФорму(«Обработка.» + ИмяВнутрОбработки + «#», СпПараметров);

    Исключение

    Предупреждение(«Не удается открыть форму внутренней обработки » + ИмяВнутрОбработки);

    КонецПопытки;

    КонецЕсли;

    Reply
  36. klen17

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

    Reply

Leave a Comment

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