HTML5 в ПолеHTMLДокумента на Управляемой форме — fireEvent в действии




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

27 Comments

  1. Patriot1S

    А в Linux будет работать?

    Reply
  2. GusevNA

    (1) Patriot1S, Здесь все сделано стандартными средствами 1С и стандартными средствами HTML-JS. Насчет Linux — все зависит от того, как там реализован элемент управляемой формы ПолеHTMLДокумента.

    Если аналогично Win, тогда нужно проверить платформу на баги (в релизе 8.3.5.1383 в тонком клиенте под Windows 7 просто баг выдавался и через Попытка-Исключение не обрабатывался).

    Так что если кто-нибудь попробует под Linux, буду очень благодарен за комменты.

    Reply
  3. vandalsvq

    (0) Обрати внимание, в ие 9+ createEventObject не поддерживается. Точнее в 9 он остался для обратной совместимости, а в 10 и 11 выпилили. Поэтому я бы советовал использовать следующий код

    if (document.createEvent) {
    var evt = document.createEvent(‘MouseEvents’);
    evt.initEvent(‘click’, true, false);
    document.body.dispatchEvent(evt);
    } else if(document.createEventObject) {
    document.body.fireEvent(‘onclick’);
    }

    И кстати можно еще объявить переменные в корне вроде

    var eventName  = »;
    var eventParam = [];

    Ну а потом обращаться к ним через ДокументHTML.parentWindow.EventName (или EventParam)

    Reply
  4. GusevNA

    (3) vandalsvq, Большое спасибо за код для IE10 — обязательно потестирую, когда время появится.

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

    Чтобы не тестировать HTML-JS для других версий IE, 9-я версия фиксирется строкой:

    <meta http-equiv=»X-UA-Compatible» content=»IE=9″ />

    Она обозначает, что страница находится в режиме совместимости именно с IE9, даже если установлен IE10 или IE11.

    А вот вызовы типа

    ДокументHTML.parentWindow.EventName

    начиная с IE9 не работают — для этого и используется fireEvent

    Чтобы такие вызовы заработали, можно попробовать раздел реестра:

    HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerMainFeatureControlFEATURE_USE_LEGACY_JSCRIPT

    Более подробно про режимы совместимости можно почитать здесь:

    https://msdn.microsoft.com/ru-ru/library/cc288325%28v=vs.85%29.aspx

    и здесь:

    http://xiper.net/manuals/html/meta-tags/http-equiv/x-UA-Compatible

    Про FEATURE_USE_LEGACY_JSCRIPT здесь:

    http://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version

    Reply
  5. sikuda

    В Linux

    не работает никакой fireEvent не работает

    Элементы.НТМЛ.Документ.getElementById («BufferData»).innerHTML — работает!!! 8.3.6.1920

    Reply
  6. vandalsvq

    (4) не соглашусь на счёт параметров. Тестил режимы совместимости 9,10,11. В системе стоит ie11, win7 sp2. Все работало.

    Линух пока не тестил.

    Reply
  7. vandalsvq

    (5) sikuda, А мой пример с createEvent работает?

    Reply
  8. sikuda

    (7) vandalsvq, Да я честно не осознал зачем вообще fireEvent

    Элементы.НТМЛ.Документ.getElementById («SendEvent»).click() — работает и в Windows и в Linux.

    И в функции ExecCommand () добавь строку alert(navigator.userAgent); Ты будешь сильно удивлен своим IE9.

    Reply
  9. Поручик

    navigator.userAgent покажет IE 7, какой бы режим совместимости не устанавливать.

    Reply
  10. yukon

    (9) Поручик,

    navigator.userAgent покажет IE 7, какой бы режим совместимости не устанавливать.

    Это смотря где устанавливать. Если здесь: https://msdn.microsoft.com/en-us/library/ie/ee330730(v=vs.85).aspx#browser_emulation , то может и взетит.

    Reply
  11. GusevNA

    Еще раз по поводу вызовов типа ПолеHTMLДокумента.document.parentWindow.MyFunc1 ()

    <!DO CTYPE html>

    <ht ml>

    <head>

    <title>1C JS Interchange</title>

    <met a http-equiv=»Content-Type» content=»text/html; charset=utf-8″ />

    <met a http-equiv=»X-UA-Compatible» content=»IE=8» />

    <sc ript>

    var var1 = «Debug_var»;

    function Debug1 ()

    {

    alert («Debug»);

    }

    </sc ript>

    </head>

    <body>

    <p>Body</p>

    </body>

    </html>

    Вызовы работают:

    Рез = Элементы.НТМЛ.Документ.parentWindow.var1;

    Сообщить (Рез); // выводит Debug_var

    Элементы.НТМЛ.Документ.parentWindow.Debug1 (); // выводит MsgBox «Debug»

    Если написать

    <met a http-equiv=»X-UA-Compatible» content=»IE=9» />

    При настройках IE по умолчанию ВЫЗОВЫ НЕ РАБОТАЮТ

    Если вызовы все-таки работают, значит, накручены настройки IE в самом IE или в реестре.

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

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

    Reply
  12. GusevNA

    Насчет fireEvent и Click

    Click также отлавливается элементом ПолеHTMLДокумента в событии ПриНажатии, так что можно использовать и такой метод. (тестировалось на Win7 32 bit 1С 8.3.5.1517). Судя по комментам, должно работать и в Linux.

    Но, как я понял замысел разработчиков IE, click () — это непосредственное нажатие кнопки мыши, а fireEvent — это именно программный вызов события, так что с точки зрения правильности кода все-таки стоит использовать fireEvent

    И еще насчет ПолеHTMLДокумента в Windows и Linux.

    ПолеHTMLДокумента, насколько я знаю, использует ActiveX-компонент Webbrowser, а он работает на движке IE.

    По крайней мере, так было в обычных формах. В УФ, возможно, также, только надстройка над компонентом Webbrowser изменена.

    А в Linux на коком браузерном движке работает ПолеHTMLДокумента? Может, кто знает, напишите, плиз.

    Reply
  13. sikuda

    (12) В Linux старенький web-kit:

    Mozilla/5.0 (X11; Linux i686) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15

    Насчет fireEvent не буду переубеждать.

    Reply
  14. GusevNA

    (13) sikuda, Спасибо, буду иметь ввиду. Попозже буду тестить под Linux на Virtualbox и отпишусь по результатам.

    Кстати сказать, если вызовы fireEvent в 1С и JS заменить на вызов click (), то все работает также. Наверно, под Linux так и нужно делать.

    Reply
  15. GusevNA

    (3) vandalsvq, Если указать IE10

    <met a http-equiv=»X-UA-Compatible» content=»IE=10» />

    выдается ошибка «Произошла исключительная ситуация…» и для fireEvent и для click (). Ошибка не отлавливается Попыткой-Исключением. Точнее сказать, JS-функция отрабатывает, а потом выдается ошибка.

    Похоже, это баг платформы, аналогичный тому, который был в 8.3.5.1383, только теперь уже под IE10.

    Так что полноценного тестирования под движок IE10 не получается.

    Reply
  16. MarSeN

    fireEvent используется в http://infostart.ru/public/142204/

    Reply
  17. Feelthis

    Может есть у кого примеры (хотя бы текстом, лучше картинки может и т. д.) реализаций крутых возможностей Javascript + 1C? Для чего полезного вы используете JavaScript?

    У себя мы реализовывали только работу с картой google и yandex и построение маршрутов в 1С.

    Reply
  18. Yashazz

    Поправьте, если ошибаюсь, но то чудо, которое засунуто в 1С под видом ПолеHTML, ведь никак не выше версии IE 8, так?

    Reply
  19. vandalsvq

    (0) хочу сказать что в своем сообщении (3) я был немного введен в заблуждение поведением платформы 1С.

    8.3.5- получение параметров через точку невозможно, 8.3.6.1960 — работает.

    И метод CreateEvent работает как то странно. Покопавшись, соглашусь с ранее высказанной мыслью что click() — самый универсальный способ (тем более как говорит sikuda он еще и кроссплатформенный).

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

    HTML

    <div id=’name’ data-eventName=» data-eventParam=» …></div>

    JS

    getElementById(‘name’).setAttribute(‘data-eventName’, ‘ИмяПроцедуры1С’);
    getElementById(‘name’).getAttribute(‘data-eventName’);

    имена могут быть любые, но я делаю с префиксом data, надеясь что когда нибудь дата-атрибуты будут поддерживаться правильно (через dataSet).

    Reply
  20. GusevNA

    (18) Yashazz, Сейчас уже точно поддерживает движок IE 9 в релизе 8.3.5.1517. Все описанные фичи HTML5 для IE9 есть, так что налицо движение вперед:-))

    Reply
  21. sikuda

    (19) vandalsvq, Да причем с точки зрения браузера не обязательно в HTML их прописывать.

    <div id=’name’></div>

    getElementById(‘name’).getAttribute(‘data-eventName’); -> NULL

    getElementById(‘name’).setAttribute(‘data-eventName’, ‘Значение’);

    Работает! и в 8.1

    Reply
  22. GusevNA

    После установки релиза 1С 8.3.1570 пример заработал для IE10:

    <meta http-equiv=»X-UA-Compatible» content=»IE=10″ />

    И странный эффект — перестала выдаваться ошибка в релизе 8.3.1517

    Проверялось на Windows 8 32 bit

    Reply
  23. SmokeAce

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

    Reply
  24. Dilovar9

    А как быть если innerHTML перестал работать в IE 11 ???

    Reply
  25. GusevNA

    (24) Dilovar9, Можно попробовать разные варианты строки:

    <meta http-equiv=»X-UA-Compatible» content=»IE=8″ />

    Весь HTML должен работать как в IE8

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

    Reply
  26. Businka76

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

    FEATURE_BROWSER_EMULATION позволяет выставить любой браузер.

    10000 (0x2710) IE10

    9000 (0x2328) IE9

    8000 (0x1F40) IE8

    7000 (0x1B58) IE7

    более полно о доступных значениях ключей и что с ними делать есть здесь

    https://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx

    Reply
  27. GusevNA

    (26) Businka76, бывает, что не работает из-за настроек Windows (IE все-таки компонент Windows) или из-за антивирусов

    Reply

Leave a Comment

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