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




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

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