Запись значения в поле ввода/формы со срабатыванием события ПриИзменении




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

38 Comments

  1. hopter

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

    Reply
  2. PowerBoy

    Классно. Обязательно использую. Спасибо за подробный пример.

    Reply
  3. karat60

    спасибо +1

    Reply
  4. fez

    Супернужная возможность для автоматического тестирования. Спасибо.

    Reply
  5. BlackLeon

    а что подразумевается под режимом редактирования строки?

    установить текущую строку и текущую колонку и выполнить ИзменитьСтроку()?

    извените. просто не смог запустить:) проблема оказалась в том что форма должна быть открыта:(

    Reply
  6. Girl_Tat

    Большое спасибо за процедуры!!!!! Очень помогли!!!

    Reply
  7. Жолтокнижниг

    Огромный жирный плюс, а нет предложений как програмно нажимать кн. «Ок»

    у меня только одна идея эмуляция ctrl+enter, но чтот не гут так извращаться

    Reply
  8. agressor

    +1

    Reply
  9. rar_xxx

    Жирный плюс !!! Можешь помочь с обработкой таблицы управляемой формы ?

    Делаю так:

    ФормаДок.Элементы.Товары.ТекущаяСтрока = 0;

    Получилось в качестве колонки пока только это скормить: ФормаДок.Товары.ПодчиненныеЭлементы.ТоварыЦенаСоСкидкой Но значение на форме не появилось

    Reply
  10. denny_dv

    Супер крутая процедурка!!! Добавил в копилку! Префикс оставлю чтобы помнить. +

    Reply
  11. mcarrowd

    В 8.3 вторая процедура не работает — надо вызывать ТаблицаФормы.ИзменитьСтроку() в процедуре или где-то ранее по коду

    Процедура ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля(ТабличноеПоле, Колонка, Значение, ФормаИнициатор = Неопределено) Экспорт
    
    ТабличноеПоле.ТекущаяКолонка = Колонка;
    ТабличноеПоле.ИзменитьСтроку();
    ЛксИнтерактивноЗаписатьВЭлементУправления(Колонка.ЭлементУправления, Значение, ФормаИнициатор);
    
    КонецПроцедуры
    

    Показать

    Reply
  12. tormozit

    (11) Видимо не читал описание метода?

    Reply
  13. mcarrowd

    (12) видимо только первую строку.

    Reply
  14. ardn

    Спасибо,

    Внес этот трюк в модуль тестирования обычных форм

    Reply
  15. hopter

    а на управляемых формах возможно нечто подобное соорудить?

    Reply
  16. ardn

    (15) hopter,

    На управляемых формах логичнее использовать автоматизированное тестирование

    Reply
  17. tormozit

    На управляемых формах это тоже работает.

    Кстати про тестирование форм (обычных и управляемых) рекомендую посмотреть инструмент «Тестирование метаданных» из подсистемы Инструменты разработчика, где этот прием используется.

    Reply
  18. hopter

    ясно, посмотрю про тестирование

    Reply
  19. uri1709

    Все таки не ясно, как должна выглядеть процедура 2 для УФ, там используется вместо ТабличногоПоля, ТаблицаФормы. Методы конечно похожие, но что-то до конца не получилось у меня разобраться. Проверял на УТ 11.2. Вторую процедуру сделал так:

    &НаКлиенте
    Процедура ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля(ТабличноеПоле, Колонка, Значение, ФормаИнициатор = Неопределено) Экспорт
    
    ТабличноеПоле.ТекущийЭлемент = Колонка;
    ЛксИнтерактивноЗаписатьВЭлементУправления(ТабличноеПоле.ТекущийЭлемент, Значение, ФормаИнициатор);
    
    КонецПроцедуры // ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля()
    

    Сделал обработку с полями Партнер, Номенклатура и командой выполнить:

    &НаКлиенте
    Процедура Заполнить(Команда)
    Форма = ОткрытьФорму(«Документ.РеализацияТоваровУслуг.ФормаОбъекта»);
    
    Форма.ЛксИнтерактивноЗаписатьВЭлементУправления(Форма.Элементы.Партнер, Партнер, ЭтаФорма);
    
    
    Форма.Элементы.Товары.ДобавитьСтроку();
    
    Форма.ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля(Форма.Элементы.Товары, Форма.Элементы.Товары.ПодчиненныеЭлементы.ТоварыНоменклатура, Номенклатура, ЭтаФорма); //Форма.Элементы.ТоварыНоменклатура
    Форма.ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля(Форма.Элементы.Товары, Форма.Элементы.Товары.ПодчиненныеЭлементы.ТоварыЦена, 100, ЭтаФорма); //Форма.Элементы.ТоварыЦена
    Форма.ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля(Форма.Элементы.Товары, Форма.Элементы.Товары.ПодчиненныеЭлементы.ТоварыКоличествоУпаковок, 100, ЭтаФорма);
    
    КонецПроцедуры
    

    Показать

    В результате на форме заполнилось: Партнер,Контрагент

    Номенклатура — пустое поле, Цена=100,Количество=100,Сумма=10 000.

    Мне не понятен момент почему не заполнилась Номенклатура и не сработало событие «ПриИзменении», ведь для «Цены» и «Количества» это событие сработало.

    Хотя воспроизвел, в чистой базе создал документ «РеализациятоваровУслуг» с Партнером и табличной частью Номенклатура,НоменклатураНаименование-строка, Цена, Количество, Сумма

    сделал обработчики событий для Номенклатуры при изменении заполняется поле НоменклатураНаименование, для Цены и Количества обработчики при изменении расчета Суммы.

    Запустил эту обработку НоменклатураНаименование заполнилось и сумма рассчиталась. Все обработчики событий сработали.

    Странно, почему в УТ 11.2 не отработало

    Reply
  20. hopter

    (19) uri1709, аналогичная проблема

    В ЗУП 3 при заполнении дополнительного отпуска в табличной части вид не проставляется, а даты нормально

    пока не разобрался

    Reply
  21. hopter

    еще не могу понять можно ли так флажок установить

    Reply
  22. hopter

    флажок похоже нельзя, т.к. это не поле ввода

    Reply
  23. tormozit

    (22) Да, нельзя. В теме же написано четко «Поле ввода»

    Reply
  24. Toolfan

    По поводу отработки обработчика у Номенклатуры, та же самая проблема, решить не удается

    Так и не у кого не получилось решить?

    Reply
  25. SlavaKron

    (22) В УФ можно менять вид поля формы на клиенте. «Поле флажка» можно поменять на «Поле ввода».

    Reply
  26. tormozit

    Обновил код. Теперь там есть поддержка обычных и управляемых форм (табличных полей и таблиц формы).

    Reply
  27. mszsuz

    Если бы такое оформление условий использовалось в типовых, можно было получить вывих мозга

    Reply
  28. tormozit

    (27) Это обсуждаем тут https://infostart.ru/public/152801/

    Reply
  29. acsent

    А не проще ли сделать расширение, где будет

    Процедура расш_ПриИзменении() экспорт
    ПриИзменении()
    КонецПроцедуры
    Reply
  30. tormozit

    (29) Так обработчика может не быть. К тому же есть внутренние обработчики платформы при изменении значения в поле ввода. Они не вызываются при вызове прикладного обработчика.

    Reply
  31. acsent

    (30) А какой тогда пересчет нужно вызвать, если обработчика то и нет?

    Reply
  32. tormozit

    (31) Например очистка связанных полей ввода.

    Reply
  33. lev6975

    Неработает… вышибает 1С с дампом памяти

    Можно подробнее описать что такое «Табличное поле» здесь конкретно и «Колонка»?

    Для подстановок в процедуры

    Reply
  34. tormozit

    (33) Если приложение аварийно завершается, то надо сделать пример для воспроизведения проблемы. Тогда возможно я чем то помогу. Но такую проблему читаю впервые. А по поводу табличного поля и колонки все описано в комментариях перед методом.

    Reply
  35. lev6975

    И вообще, тут, по — моему, опечатка — в функции идут 4 параметра — табличноеполе, колонка, значение, инициатор и два левых булёвых

    А во внутренней функции их уже три… может из за этого — все сдвигается и поэтому глючит

    Reply
  36. ZanderZ

    (33)

    Так же вылетает с дампом…на строке ТабличноеПоле.ИзменитьСтроку();

    Reply
  37. tormozit

    (36) Часто в таких ситуациях причиной является бесконечная рекурсия.

    Reply
  38. ZanderZ

    (37) я пытаюсь из заполнения объекта вызвать не в цикле

    ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ВладелецФормы.Элементы.Сотрудники,ВладелецФормы.Элементы.Сотрудники.ПодчиненныеЭлементы.СотрудникиКоличествоДней,10,,Ложь);

    и вылетает с дампом…

    Reply

Leave a Comment

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