Обработка для отладки обработок заполнения табличных частей документов




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

40 Comments

  1. WiseSnake

    Скриншоты? Описание?

    Чем лучше например http://www.infostart.ru/public/15601/?

    В связи с новыми правилами лично я даже качать не буду в таком состоянии…

    Reply
  2. WiseSnake

    Скриншот появился…

    А посмотреть потом заполненную ТЧ как?

    Reply
  3. Borisych

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

    Дополнил описание и обновил файл

    (1) в связи с новыми правилами и некоторыми постами, вносящими неясность к употреблению той обработки, например, зачем её подключать к документу? лично я бы не стал ей пользоваться и скачивать.

    Считаю что выложенная выше вещь — удобная, полезная, универсальная и сделана качественно, ничего лишнего

    Reply
  4. Borisych

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

    Reply
  5. poppy

    Не удалось протестировать эти обработки:

    http://www.infostart.ru/public/20302/

    http://www.infostart.ru/public/18828/

    {Форма.Форма(16)}: Поле объекта не обнаружено (Объект)

    Обр.Объект = ЭлементыФормы.ВыбДок.Значение.ПолучитьОбъект();
    Reply
  6. poppy

    (3) по (1)

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

    Действия тестируемой обработки можно отменить.

    Reply
  7. Borisych

    (5) Обработка расчитана на наличие реквизита «Объект» в обработке заполнения табличной части (если тип этого реквизита ограничен типами ссылок на документы к которым подключается обработка заполнения ТЧ, а не установлен в «Любая ссылка», тогда в поле выбора «Документ для заполнения табличной части» будем выбирать из ограниченного множества. Это удобно)

    Reply
  8. Borisych

    (1) скачал обработку — хорошая

    Reply
  9. artbear

    (7) 1. Эта информация должна быть в описании

    2. было бы удобно, если бы наличие/отсутствие реквизита «Объект» проверялось автоматом и в случае отсутствия выдавалось вменямое сообщение об этом.

    Вопрос: документ всегда сохраняется?

    ИМХО в (6) значительно удобнее, можно легко отказаться от неверных исправлений.

    Reply
  10. e.kogan

    (7) Следовательно, она не является подспорьем для тестирования ОЗТЧ, написанных по стандартной технологии.

    Reply
  11. Borisych

    (9)-(10) Лично я всегда создаю реквизит «Объект», привык к такому порядку, что ж теперь делать?

    (9) А сообщение, что реквизита нет, выводится в строке сообщений

    Reply
  12. artbear

    1. Где про Объект написано в описании?

    2. Что по сохранению документа ?

    3. (10) перечеркивает универсальность, тем более, что и в описании об ограничении по Объект ничего не написано.

    Reply
  13. Borisych

    (12).2 документ записывается после заполнения

    Reply
  14. WiseSnake

    (13) Не было меня давно. Вставлю свои 5 копеек.

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

    Лично я поступаю просто:

    1. Пользуюсь обработкой poppy (если не лень подключать)

    2. У меня все внешние обработки с формами: из формы обработки я просто открываю сформированный документ не сохраняя его…

    Reply
  15. Borisych

    (14.2) тоже вариант

    Reply
  16. artbear

    В общем, неудобно и неуниверсально 🙁

    Не в обиду автору поставлю минус — у poppy намного лучше 🙁

    Reply
  17. Borisych

    Ничего страшного, я не обидчивый 😉

    Мне во всяком случае удобен такой подход — если форма подключается к паре видов документов, то выбирать только из них.

    Кесарю кесарево

    Reply
  18. A_kryl

    Я тоже не создаю реквизит объект в обработке заполнения, так поправить — это два слова в сабже убрать. Немного доработал напильником и все ок.

    Reply
  19. Smile1984arm

    Огромное вам спасибо, очень полезная вещь!!!

    Reply
  20. Borisych

    (19) — (20)

    Reply
  21. Borisych

    Вот ещё полезности —

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

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

    3. для формирования кода заполнения макета ПФ — создается макет со всеми параметрами/шаблонами,

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

    Макет = ПолучитьМакет(«ИМЯ_МАКЕТА»);
    ТекстЗаполненияПараметровМакета =
    »
    |ТабДок = Новый ТабличныйДокумент;
    |ТабДок.АвтоМасштаб   = Истина;
    |ТабДок.Защита    = Истина;
    |ТабДок.ОтображатьСетку  = Ложь;
    |ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
    |ТабДок.ИмяПараметровПечати = «»ПАРАМЕТРЫ_ПЕЧАТИ_»» + ЭтотОбъект.Имя;
    |
    |ИмяМакета = «»ИМЯ_МАКЕТА»»;
    |Макет = ПолучитьМакет(ИмяМакета);
    |»;
    
    
    Для каждого Обл Из Макет.Области Цикл
    ТекстЗаполненияПараметровМакета = ТекстЗаполненияПараметровМакета + Символы.ПС +
    СтрЗаменить(  «// Область «»ОбластьМакета»»
    |ОбластьОбластьМакета = Макет.ПолучитьОбласть(«»ОбластьМакета»»);
    |ОбластьОбластьМакета.Параметры.Заполнить(ДанныеЗаполнения);»,
    «ОбластьМакета»,
    Обл.Имя) + Символы.ПС;
    ОблМ = Макет.ПолучитьОбласть(Обл.Имя);
    Для сч_строк = 1 По ОблМ.ВысотаТаблицы Цикл
    Для сч_столбцов = 1 По ОблМ.ШиринаТаблицы Цикл
    Яч = ОблМ.Область(«R»+ Формат(сч_строк,»ЧГ=0») + «C» + Формат(сч_столбцов,»ЧГ=0″));
    Если Яч.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Параметр Тогда
    ТекстЗаполненияПараметровМакета = ТекстЗаполненияПараметровМакета +
    «Область» + Обл.Имя + «.Параметры.» + Яч.Параметр + » = ДанныеЗаполнения.» + Яч.Параметр + «;» + Символы.ПС;
    КонецЕсли;
    Если Яч.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Шаблон Тогда
    МассивСтрок = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(Яч.Текст, «[«);
    Для каждого ЭлМассива Из МассивСтрок Цикл
    Если Найти(ЭлМассива,»]») > 0 Тогда
    ИмяП = СокрЛП(СтрЗаменить(ЭлМассива,»]»,»»));
    ТекстЗаполненияПараметровМакета = ТекстЗаполненияПараметровМакета +
    «Область» + Обл.Имя + «.Параметры.» + ИмяП + » = ДанныеЗаполнения.» + ИмяП + «;» + Символы.ПС;
    КонецЕсли;
    КонецЦикла;
    
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;
    ТекстЗаполненияПараметровМакета = ТекстЗаполненияПараметровМакета  +
    СтрЗаменить(«ТабДок.Вывести(ОбластьОбластьМакета);», «ОбластьМакета», Обл.Имя) + Символы.ПС;
    КонецЦикла;
    Сообщить(«», СтатусСообщения.БезСтатуса);
    Сообщить(ТекстЗаполненияПараметровМакета, СтатусСообщения.БезСтатуса);
    

    Показать

    Reply
  22. artbear

    (20) Это ты про что пишешь?

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

    Reply
  23. Borisych

    (22) Завтра-послезавтра сниму видео с демонстрацией

    Reply
  24. DimDimych

    Очень удобная обработка для отладки работает в любых конфигурациях спасибо автору

    Reply
  25. Borisych

    (24) Спасибо, пункт (23) откладывается на выходные…

    Reply
  26. lyubashonka

    Спасибо огромное за обработку — очень помогла!!!

    Reply
  27. Borisych

    (26) lyubashonka, пожалуйста! 🙂

    Reply
  28. Riper

    Очень удобная обработка для отладки спасибо автору — очень помогла!!!

    Reply
  29. Borisych

    (22) artbear, кстати, вот видео снял — как ВПФ сделать : http://infostart.ru/public/66570/ — четвертый файл, также он лежит тут: http://files.mail.ru/BDNTCN

    Reply
  30. nnurik

    Спасибо автору. Использую при отладке, оч. хорошее средство.

    Reply
  31. oiter

    Спасибо автору! Очень часто раньше приходилось использовать формы в тестировании.

    Reply
  32. Borisych

    (31) oiter, посмотрите и другие мои публикации — шаблон ВПФ тоже полезная вещь и дерево метаданных конфигурации

    Reply
  33. unoDosTres

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

    Reply
  34. Manticor

    Друзья, есть ли подобная вещь для управляемых форм под тонкий клиент? очень нужно

    Reply
  35. Borisych

    (34) Manticor, у меня пока нет, скачал с ИС отладку ВПФ под БСП

    Reply
  36. Manticor

    (35) просто без подобной обработки такго рода встает вся отладка на тонком(((

    Reply
  37. Borisych

    (36) Manticor, приспичит самому тестить ОЗТЧ — сделаю, а пока и так зашиваюсь

    Reply
  38. TODD22

    {Форма.Форма.Форма(19)}: Метод объекта не обнаружен (Записать)

    Обр.Объект.Записать();

    Вот такая ошибка при попытке заполнить ТЧ. 🙁

    Reply
  39. Borisych

    (38) TODD22, посмотри в отладчике — что в Обр.Объект находится? наверняка Неопределено или что-то ещё не ссылочного типа

    Reply
  40. IsiKosta

    Не хватает кнопки «Закрыть» и подстановки имени табличной части при выборе типа, первой в списке ТЧ.

    Reply

Leave a Comment

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