Выполнение JavaScript кода из 1С в объекте Поле HTML Документа (HTML 5) и вызов события в 1С ПриНажатии




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

49 Comments

  1. DrAku1a

    По выполнению JS из 1С — вроде было что-то попроще, вроде eval или EvalExpr. По поводу возврата результата — думаю, будет полезно!

    Reply
  2. igo1

    (1) DrAku1a, Да, раньше выполнять скрипты можно было с помощью конструкции ПолеHTMLДокумента.Документ.parentWindow.eval(«Скрипт»); , но с переходом на IE8 и выше такой возможности больше нет. Да и статья показывает не только, что можно вызвать JS код, но и изменить поведение HTML документа, загруженного в ПолеHTMLДокумент.

    Reply
  3. Yashazz

    (2) и это в общем логично. Поле HTML и выполнение в нём произвольного js, да ещё с eval, было страшенной дырой в безопасности. Поэтому и возможности поля порезали, и вообще.

    Интересный способ, спасибо. Как-нибудь на досуге попробую.

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

    Статья так понравилась, особенно эта фраза, что щёлкнул звёздочку даже дважды)

    Reply
  4. igo1

    (3) Yashazz, Вот всегда так, паришься, а потом все по два раза звездочку жмут (((

    Reply
  5. Yashazz

    (4) а просто не люблю попрошаек. Статья дельная, и я было щёлкнул, а потом дочитал до конца и даже расстроился.

    Reply
  6. igo1

    (5) Yashazz,

    Я просто на другие статьи посмотрел, дак там даже Яндекс кошель прицеплен. Да, и к тому же, не понятно нормальная статья или нет, звездочку не жмут и Комменты не пишут. Вот и думай стоит писать еще или нет.

    Но не в это суть. Статья гуд и отлично )

    Reply
  7. sikuda

    Наш человек http://sikuda.ru/archives/732

    Reply
  8. igo1

    (7) sikuda, Спасибо за коммент, посмотрел вашу статью.

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

    Reply
  9. YPermitin

    (2) скажите, а не пытались ли вы использовать объект XMLHttpRequest для отправки запрос из поля HTML-документа?

    Вроде как функция эта заблочена, но вдруг есть обходной путь)

    Reply
  10. igo1

    (9) YPermitin, XMLHttpRequest не понимаю какую цель вы хотите этим достичь. вроде запросы из ПолеHTMLДокумент нормально уходят, проверил в помощью тега «Кнопка».

    Reply
  11. ut11

    Опробовал методику, столкнулся с тем, что при повторных вызовах обработки происходит ошибка:

    «Ошибка при вызове метода контекста (setAttribute)

    ДИВ.setAttribute(«onclick», ТекстСкрипт);

    по причине:

    Произошла исключительная ситуация: Не поддерживается»

    либо «Произошла исключительная ситуация (0x800a01b6)»

    кто нибудь решал такую проблему?

    Reply
  12. igo1

    Да такая проблема была на платформе 8.3.5 обновите и все ОК, или посмотрите эту публикацию http://infostart.ru/public/506854/ (11) ut11,

    Reply
  13. ut11

    у клиента 8.2.19 и обновить нет возможности 🙁

    Reply
  14. ut11

    а что именно там смотреть? я ту обработку и брал за образец

    Reply
  15. igo1

    Это поправили в 8.3.7 как я знаю. Не понятно почему нельзя обновить, режим совместимости вполне работает.

    Reply
  16. ut11

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

    Reply
  17. Zixxx

    Ни как не получается в Поле HTML Документа отобразить следующую страницу

    http://wsde.ru/timeline/index.html

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

    Подскажите плиз как сделать

    Reply
  18. igo1

    (16) ut11, Это косяк платформы, методов обхода мне найти не удалось

    Reply
  19. igo1

    (17) Zixxx, попробуйте поиграть с этим тегом <meta http-equiv=»X-UA-Compatible» content=»IE=9″/>. сначала откройте свой HTML с эти тегом(1с запустит эмуляцию IE). а потом переходите по ссылке

    Reply
  20. Rie

    (2) можно определить функцию в самом документе — и вызывать её:

    <script type=»text/javascript»>

    function exec(script) { eval(script); }

    </script>

    и затем в 1С:

    Элементы.ПолеHTMLДокумента1.Документ.parentWindow.exec(«alert(‘OK’)»);

    Reply
  21. igo1

    (21) alex_ua85, Либо я не очень понятно написал, либо читать вам надо внимательней. Так есть определяется функция в самом документе и вызывается (Это для передачи данных из 1с в док), а ели у вас произошло событие в документе, определен второй вариант с вызовом из документа в 1с через события «ПриНажатии» с передачей строковых данных.

    Reply
  22. igo1

    (20) Rie, Надо попробовать.

    Reply
  23. Al-77

    (16) ut11, Добрый день, вам удалось решить проблему на платформе 8.2 ?

    Reply
  24. igo1

    (24) Al-77, Ее не решить на 8.2, там COM объект после вызова события разваливается. только 8.3.7 и выше. под 8.2 должен работать старый метод eval просто поставьте <meta http-equiv=»X-UA-Compatible» content=»IE=9″/> в место IE=9 -> IE=7. должно заработать. Пример такой работы в моей старой обработке http://infostart.ru/public/238697/

    Reply
  25. SherifSP

    При использовании тега <meta http-equiv=»X-UA-Compatible» content=»IE=edge»/>, недоступно обращение через функцию eval html документа, как можно обратится к функции html документа с этим тегом?

    Reply
  26. Дмитрий_кдс

    Добрый день. Подскажите, как обойти проблему Eval() на обычных формах 8.3? Ругается на метод Евал при открытии карты((

    Reply
  27. igo1

    (27) Дмитрий_кдс, Статья сверху (Весь текст) посвещен именно этому вопросу

    Reply
  28. igo1

    (26) SherifSP, к сожалению работу с edge (это не IE) не тестировал …..

    Reply
  29. vaxhab

    Вроде все хорошо

    Reply
  30. zan_od

    (21), использование JS из 1С имеет право на жизнь. Использование уже готовых библиотек, как минимум. Я, например, использовал JS библиотеки для расчета SHA-1 и HMAC-SHA1. Только запускал JS через «MSScriptControl.ScriptControl»

    Reply
  31. dablack

    Игорь, спасибо! очень кстати нашел вашу статью.

    Reply
  32. igo1

    (32) всегда рад )

    Reply
  33. antz

    А ДобавитьОбработчик совсем никто не юзает, только я?

    Reply
  34. igo1

    (34) Такой статьи ДобавитьОбработчик + HTML я еще не видел, это ваш шанс заявить о себе. И мне тоже будет интересно.

    Reply
  35. antz

    (35) насчет статьи не знаю, в общем, там просто все. Но меня выручило прямо. Вот, для событий onclick и oncontextmenu.

    Reply
  36. igo1

    Посмотрел обработчик, хороший пример. можно и так.

    Reply
  37. Mzybo

    У меня есть практический вопрос. Как получить файл Excel с сайта?

    http://grls.rosminzdrav.ru/GRLS.aspx (в правом верхнем углу)

    Сейчас я получаю данные элемента через функцию

    а = Элементы.Реквизит1.Документ.getElementById(«ctl00_plate_tdzip»);

    Как дальше выполнить этот код, чтобы иметь возможность сохранить файл?

    Reply
  38. igo1

    (38)Это делается с помощью GET запроса, в вашем случае объект HTMLДокумент не нужен.

    Reply
  39. ZhokhovM

    (38)в личку

    Reply
  40. v.l.

    (40) Не стесняйся, не держи в себе! Пиши здесь.

    Reply
  41. Green2

    Тут упущен важный момент, на какой версии IE работает данная обработка.

    Потому что в режиме IE 11 функции

    var evt = document.createEventObject();

    document.fireEvent(‘onclick’,evt)

    Не работают.

    По стандарту надо писать

    var event = document.createEvent(«Event»);

    event.initEvent(«hello», true, true);

    elem.dispatchEvent(event) ;

    но почему то эти события 1С не ловит…

    Reply
  42. igo1

    (42)

    fireEvent

    Думаю ответ тут.

    https://developer.mozilla.org/ru/docs/Web/API/Event/initEvent

    Reply
  43. Green2

    (43) Я попробовал этот код

    // Create the event.
    var event = document.createEvent(‘Event’);
    
    // Create a click event that bubbles up and
    // cannot be canceled
    event.initEvent(‘help’, true, false);
    
    // Listen for the event.
    elem.addEventListener(‘click’, function (e) {
    // e.target matches elem
    }, false);
    
    elem.dispatchEvent(event);

    Показать

    Но он не позволяет вызвать событие onHelp в 1С.

    Поэтому приходится вызывать fireEvent, но он работает только в старой версии IE.

    Reply
  44. igo1

    (44)

    При создании объекта «Поле HTML Документа» можно указать версию IE.

    Reply
  45. rassigor

    Привет, в справочник номенклатура был добавлен редактор HTML для редактирования описания и выгрузки на сайт.

    до версии 8.3.14 все прекрасно работало, сейчас после перехода перестало работать, так как в версии 8.3.14 — webkit

    html = Элементы.Body.Документ.parentWindow.eval(«CKEDITOR.instances.editor1.getData();»); вот этот код выдает ошибку

    Подскажите пожалуйста, как перевести на webkit

    Reply
  46. user1275865

    Всё вышеперечисленное перепробовал, но тщетно: fireEvent не работает, CustomEvent, у которого можно задать detail — тоже не взлетел (detail всё время равно 1)…

    Решение нашёл такое: если нужно выполнить некую функцию на JS, достаточно объявить эту функцию в глобальном контексте:

    <script type=»text/javascript»>
    function myCustomFunction() {
    return «My valuable JS data»;
    }
    </script>
    

    Глобальный контекст доступен в 1С через свойство window объекта Документ:

    Данные = ЭлементыФормы.ПолеHTMLДокумента.Документ.window.myCustomFunction();
    
    Reply
  47. igo1

    На какой платформе пробовали?

    Reply
  48. Konstatine

    Скажите, почему не работает на 8.2?

    Reply
  49. SlavaKron

    Что в IE, что в WebKit, чтобы вызвать функцию js поля HTML из 1С, достаточно в скрипте объявить эту функцию, как переменную документа:

    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
    Реквизит1 =
    «<html>
    | <head>
    |  <script language=’JavaScript’ type=’text/javascript’>
    |
    |   document.helloWorld = function() {helloWorld()};
    |
    |    function helloWorld() {
    |    document.getElementById(‘text’).innerHTML = ‘Hello World!’
    |   }
    |
    |  </script>
    | </head>
    |
    | <body>
    |  <h1 id=’text’> </h1>
    | </body>
    |
    |</html>»;
    
    КонецПроцедуры
    
    &НаКлиенте
    Процедура Команда1(Команда)
    Элементы.Реквизит1.Документ.helloWorld();
    КонецПроцедуры

    Показать

    Reply

Leave a Comment

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