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




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

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