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




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

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 не будет опубликован. Обязательные поля помечены *