Заполнение дополнительных реквизитов при программном открытии формы из другой формы




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

14 Comments

  1. ducks01

    (0) это работает примерно так:

    ОписаниеОбъекта = Форма.Объект;
    
    ОписаниеСвойств = УправлениеСвойствамиСлужебный.ЗначенияСвойств(
    ОписаниеОбъекта.ДополнительныеРеквизиты.Выгрузить(),
    Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта,
    Ложь,
    ОписаниеОбъекта);
    
    Для каждого ОписаниеСвойства Из ОписаниеСвойств Цикл
    
    ИмяРеквизитаЗначение = «ДополнительныйРеквизитЗначение_»
    + СтрЗаменить(ВРег(Строка(ОписаниеСвойства.Набор.УникальныйИдентификатор())), «-«, «x»)
    + «_»
    + СтрЗаменить(ВРег(Строка(ОписаниеСвойства.Свойство.УникальныйИдентификатор())), «-«, «x»);
    
    Форма[ИмяРеквизитаЗначение] = «тут значение вам необходимое»;
    
    КонецЦикла;
    

    Показать

    Reply
  2. bugtester

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

    заполнить доп.реквизит в другой полученной форме (форме документа отпуска, не меняя модуль формы этого документа),

    например, как здесь https://infostart.ru/public/901823/

    Вы находитесь в форме документа, а я нахожусь в форме обработки,

    и там в процедуре ЗагрузитьДокумент25() заполняю полученную форму документа Отпуск

    И исполнение вашего кода на клиенте? Этот код весь отрабатывает на клиенте?

    Reply
  3. bugtester

    (1) Смотрите, что получается, если ваш код на клиенте (а он на клиенте, т.к. на сервере он может быть только, когда находится в модуле формы объекта и эта форма создается на сервере, иначе управляемую форму на сервер не получится передать):

    Переменная не определена (УправлениеСвойствамиСлужебный)

    ОписаниеСвойств = <<?>>УправлениеСвойствамиСлужебный.ЗначенияСвойств( (Проверка: Тонкий клиент)

    Reply
  4. ducks01

    (3) на клиенте, я делал это в расширении 1с. по вашей ошибке понятно что у вас нет этого Типового модуля, ищите аналог и используйте.

    Reply
  5. bugtester

    (4) Неверные у вас выводы. Этот общий модуль с процедурой есть в конфигурации, используется типовая ЗУП 3.1.

    И в моей статье в частности тоже используется УправлениеСвойствамиСлужебный.ЗначенияСвойств()

    (у общего модуля УправлениеСвойствамиСлужебный галочки «сервер», «внешнее соединение»),

    только УправлениеСвойствамиСлужебный.ЗначенияСвойств() у меня вызывается из серверной процедуры модуля формы обработки. Код моей статьи работает.

    С клиента модуля формы обработки процедура этого общего модуля не может вызываться, см. ошибку выше — ваш код не работает.

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

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

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

    Reply
  6. bugtester

    (4) в каком месте расширения 1С вы использовали этот код?

    Reply
  7. bugtester

    (4) у серверного общего модуля УправлениеСвойствамиСлужебный нет галочки «вызов сервера»,

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

    https://infostart.ru/public/86838/

    со стороны клиента можно вызывать

    1) клиентские процедуры данного модуля, с директивой &НаКлиенте;

    2) серверные процедуры данного модуля, с директивой &НаСервере;

    3) клиентские процедуры общего модуля, с директивой &НаКлиенте(при условии наличия в свойствах доступности в нескольких контекстах, «Клиент» обязателен и др.);

    4) все процедуры клиентского общего модуля , в свойствах общего модуля должно быть только свойство «Клиент(управляемое приложение)». Директиву &НаКлиенте в общем модуле в этом случае не пишут;

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

    Reply
  8. ducks01

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

    Reply
  9. ducks01

    (6) ввел в заблуждение, использовал в новом серверном общем модуле

    Reply
  10. bugtester

    (9) А форма как попадает в процедуру на серверном общем модуле?

    Из ПриСозданииНаСервере же в модуле той формы?

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

    у Павла Чистова есть хороший текст про существование формы на сервере и на клиенте http://goo.gl/oMYBcM

    Reply
  11. bugtester

    (8) Рука-лицо. А то что этот вопрос был в анонсе статьи, как затравка для дальнейшего раскрытия, вас не смутило?)

    Reply
  12. bugtester

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

    Это пример рабочего кода, как процедуру УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме(УправляемаяФорма) можно модифицировать, если передавать в параметры не форму, а объект формы.

    PS У Павла Чистова есть хороший текст про существование формы на клиенте и на сервере http://goo.gl/oMYBcM

    Reply
  13. ducks01

    (11) не заметил, на форуме они идут в одном списке только иконки отличаются. Можете очистить ветку если такая возможность есть. А я не пойму что это вы так агрессивно доказываете ) удачи вам!

    Reply
  14. bugtester

    (13) Ок, разобрались)

    Reply

Leave a Comment

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