Программная доработка форм, настраиваемая в режиме Предприятия




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

15 Comments

  1. sergey512
    &НаСервере

    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    //…

    ДоработкиФорм.ИзменитьФорму(ЭтаФорма, Тип(«СправочникСсылка.Справочник1»));

    КонецПроцедуры

    Эта единственная строка кода, которую нужно будет поддерживать при обновлении.

    Не согласен, что это будет единственная строка за которой нужно будет следить.

    Команды, обработчики элементов формы — за этим кодом кто будет следить?

    Если добавить одну универсальную команду и один обработчик, а сам код команд и обработчиков хранить по аналогии в регистре сведений, и выполнять его посредством оператора «Выполнить». В таком случае придется следить за одной командой, одним обработчиком и строкой указанной выше. Но не стоит забывать, что режиме запуска веб-клиент оператор «Выполнить» не поддерживается.

    Reply
  2. Alex_YAM

    (1) sergey512,

    При обновлении добавленные обработчики команд никуда не пропадут, если, конечно, их не пометить вручную на удаление. При этом естественно в имена процедур своих обработчиков нужно добавлять какой-нибудь специальный префикс, чтобы не совпасть с типовой.

    А если Вы имеете ввиду код внутри обработчиков — то , да, его нужно поддерживать, как и любой другой собственный код в конфигурации.

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

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

    Reply
  3. Сурикат

    В последних типовых конфигурация такие функции уже встроены.

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

    И у вас второй параметр лишний, т.к. по имени формы понятно какая форма к нам попала

    Reply
  4. Alex_YAM

    (3) Сурикат,

    У меня в Бухгалтерии 3.0 такого модуля нет.

    Весь смысл в регистре сведений. Потому что можно исправить ошибку без конфигуратора.

    Как Вы отследите то, что в типовой поменяли имя группы элементов с ГруппаЛеваяКолонка на ГруппаКолонкаЛевая ? Конфигуратор никаких ошибок не увидит. Проверять все используемые в коде элементы по очереди? Если доработок много, то это очень долго.

    у вас второй параметр лишний, т.к. по имени формы понятно какая форма к нам попала

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

    Reply
  5. Сурикат

    (4) Alex_YAM,

    проверьте события при создании на сервере, может как-то по-другому называется =)

    Я меняю программно. Тем более есть обработка по декомпозиции управляемых форм, которая формирует код создания новых элементов. Все-таки для обработки новых метаданных я сторонник программного решения, не завязанного на какие-то таблицы БД.

    И если ваши доработки выполняют функции модификации данных, то их полностью можно заменить на «Внешние обработки заполнения»

    Reply
  6. artemusII

    (1) sergey512, Привет, Серега!)

    Reply
  7. tregard

    На один элемент формы может быть несколько обработчиков событий. Правильней создавать два регистра — один на создание элементов, а второй для назначения обработчиков.

    К тому же у элементов формы намного больше свойств, которые потребуется изменять. Сходу вижу, что данная структура регистра не достаточно для отрисовки страниц и групп. Получается все возможные свойства элементов форм должны быть представлены ресурсами регистра. Или сделать какой-то ресурс с типом ХранилищеЗначений и там это как-то хранить.

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

    Хотя идея интересная.

    Reply
  8. sorb

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

    Примеры:

    УТ 10, КА 1, УПП 1: МеханизмНумерацииОбъектов.УстановитьДоступностьПоляВводаНомера — вызывается при открытии формы практически всех объектов.

    БП 3.0 (точнее практически любая конфигурация на БСП): ДополнительныеОтчетыИОбработки.ПриСозданииНаСервере — есть практически везде, требует включения ФО доп. отчетов и обработок.

    Также можно обрабатывать одно событие у программно добавленных элементов вообще без изменений:

    Для УТ 10, КА 1, УПП 1: практически в любой форме есть метод ДействияФормыРедактироватьНомер(Кнопка), из него идет вызов МеханизмНумерацииОбъектов.ИзменениеВозможностиРедактированияНомера; указываем его в качестве обработчика нужного события, далее в общем модуле делаем что требуется

    БП 3.0: Подключаемый_ВыполнитьКомандуПечати, остальное аналогично

    В итоге если очень припекло, то в 90% случаев вообще ничего не меняем,кроме одного-двух общих модулей.

    Reply
  9. Alex_YAM

    (7) tregard,

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

    Можно просто создать справочник НастройкиЭлементовФормы в который включить все нужные свойства, он будет единственным ресурсом.

    Reply
  10. Alex_YAM

    (7) tregard,

    (8) sorb,

    Да, в БП 3.0 в любой форме документа есть:

    УправлениеПечатью.ПриСозданииНаСервере

    ДополнительныеОтчетыИОбработки.ПриСозданииНаСервере

    ВерсионированиеОбъектов.ПриСозданииНаСервере

    Но как на счет форм Справочников? Обработок? ПВХ? Плана счетов? Регистров? и т.п.

    Reply
  11. sorb

    (10) Alex_YAM, на счет форм справочников все действительно, проверьте. ПВХ, планы счетов и регистры — за 15 лет так и не понадобилось, поэтому решение не искал. Для остального в случае УФ разумней использовать расширения, и только для ОФ иногда приходится трогать формы. Это имхо, но основанное на личном опыте.

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

    Reply
  12. Alex_YAM

    (7) tregard,

    (8) sorb,

    (3) Сурикат,

    Спасибо за комментарии.

    Убрал лишний параметр, дописал про общие модули, действительно их использовать намного удобнее.

    Reply
  13. maxx

    Полезная штука при обновлениях типовых. Спасибо.

    Ещё добавил возможность добавлять группы, порядок добавления (сортировка) важен при создании групп, до 5 событий увеличил назначение к элементам формы, ширину поле формы, растягивать/не растягивать по ширине — пока этого хватилою

    Reply
  14. invertex

    «Используется» не место в измерениях, это ресурс. Иначе возможны две записи в регистре — «Используется» и «Не используется». Какая правильней? =)

    Reply
  15. Alex_YAM

    (16)

    Обе правильные, просто одна используется, а другая нет. =) Так удобнее посмотреть разные варианты.

    Reply

Leave a Comment

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