Имя: Пароль:
1C
1С v8
HTML поле и цикл с JavaScript
0 kofe88
 
24.02.13
23:48
Здравствуйте! Необходима помощь с 1c 8.2 . Есть HTML поле в форме документа, при создании документа в него загружается страница, затем в этом HTML поле необходимо несколько раз выполнить JavaScript и получить из него данные, если выполнять 1 раз, то всё ок, а если выполнять несколько раз через цикл, то цикл не ждет ответа от этой функции, получается сперва пробегает цикл, n-ое кол-во раз, а затем подряд приходят значения от функции. Вопрос в следующем,как сделать так, чтобы цикл ждал, пока функция ответит, затем переходил к новому элементу, снова вызывал функцию и так далее?

Текст процедуры ниже, если необходим текст скрипта, то тоже приложу:

Процедура Кнопка1Нажатие(Элемент)
   // Вставить содержимое обработчика.
   Выборка = Справочники.ЛокальныеЦентры.Выбрать();
   //или Выборка = Справочники.Сотрудники.ВыбратьИерархически();
   Пока Выборка.Следующий() = 1 Цикл
       Сообщить(Выборка.Наименование);
       Буковки = Выборка.Адрес;
       Расстояние = ЭлементыФормы.ПолеHTMLДокумента1.Документ.parentWindow.eval("getDistanceFor2Point('" + Буковки + "','Россия, Cанкт-петербург, 6-я линия, 1/25')");
       Обработка();
   КонецЦикла;

КонецПроцедуры
1 kofe88
 
24.02.13
23:51
Смысл в том, что в переменную Расстояние, не заносится ответ от функции, а цикл просто выводит n раз Наименование, если без цикла, то ответ заносится в переменную, ай нид хелп.
2 Fragster
 
гуру
24.02.13
23:52
русский китч?
3 Fragster
 
гуру
24.02.13
23:53
все интерактивные события происходят после того, как очистится стек вызовов, тут надо курить, что написано в getDistanceFor2Point
4 Fragster
 
гуру
24.02.13
23:54
может там сетинтервал или еще что
5 Asmody
 
25.02.13
00:06
Прозреваю, что там ajax, со всеми вытекающими
6 sikuda
 
25.02.13
00:11
Проще сначала получить полностью твой массив буковок. А потом запустить твой скрипт.
7 Юрий Лазаренко
 
25.02.13
00:11
Может попробовать в яваскрипте во время выполнения функции перезагружать документ и в коде 1с ожидать выполнения события призагрузкедокумента() или как его там?
8 kofe88
 
25.02.13
00:27
Сам скрипт, нахождение расстояния по прямой(не по маршруту) между 2-мя гео точками (адресами) :
<script type="text/javascript">
       function getDistanceFor2Point(Point1, Point2) {
       var summuryDistance;
           ymaps.geocode(Point1).then(function (res) {
           var PointOne = res.geoObjects.get(0).geometry.getCoordinates();
           ymaps.geocode(Point2).then(function (res) {
           var PointTwo = res.geoObjects.get(0).geometry.getCoordinates();
           alert(ymaps.coordSystem.geo.getDistance(PointOne, PointTwo));
           summuryDistance = ymaps.coordSystem.geo.getDistance(PointOne, PointTwo);
       });
   
   });
   return summuryDistance;
   }
</script>

т.е. как я понимаю без танцев с бубном проблему решить не удасться? есть идея динамически сформировать таблицу со значениями в html поле и в сааааамом конце выполнить скрипт по разбору таблицы, вроде такого:

<script type="text/javascript">
function tabl() {
var table = document.getElementById('finallyTab');
var trList= table.getElementsByTagName('tr');
for (var i=0;i<trList.length;i++)
{
 var tdList = trList[i].getElementsByTagName('td');
 
 for (j=0;j<tdList.length;j++)
 {
 alert('trList['+i+'] tdList['+j+'].innerHTML='+tdList[j].innerHTML);
 }
}
}
</script>

Должно ведь в принципе прокатить?
9 kofe88
 
25.02.13
00:28
а затем из него вернуть массив со значениями и разобрать в 1с-ке?
10 Конфигуратор1с
 
25.02.13
00:31
(8) так а откуда знаешь что результат не возвращается?
11 Конфигуратор1с
 
25.02.13
00:31
Пока Выборка.Следующий() = 1 Цикл
       Сообщить(Выборка.Наименование);
       Буковки = Выборка.Адрес;
       Расстояние = ЭлементыФормы.ПолеHTMLДокумента1.Документ.parentWindow.eval("getDistanceFor2Point('" + Буковки + "','Россия, Cанкт-петербург, 6-я линия, 1/25')");
       Обработка();
   КонецЦикла;
с учетом (1) скорее всего он віполняет возвращает значение и так в цикле пока не дойдет до конца. Вот в последнем проходе цикла и не заполняется переменная
12 Конфигуратор1с
 
25.02.13
00:32
Если так Пока Выборка.Следующий() = 1 Цикл
       Сообщить(Выборка.Наименование);
       Буковки = Выборка.Адрес;
       Расстояние = ЭлементыФормы.ПолеHTMLДокумента1.Документ.parentWindow.eval("getDistanceFor2Point('" + Буковки + "','Россия, Cанкт-петербург, 6-я линия, 1/25')");
       Обработка();
Сообщить(Расстояние );
   КонецЦикла;
13 Mashinist
 
25.02.13
00:54
я подымал подобный вопрос
v8: Проблема с COMОбъект("InternetExplorer.Application") для IE9

вывод: дождаться выполнения JavaScript можно только таймаутом и если он меняет собственно документ, то значит можно ждать появления нужного значения в документе
14 kofe88
 
25.02.13
01:12
(12) Пробовал, сперва выдает в окно сообщений в столбик подряд результат от
Сообщить(Выборка.Наименование);
А через некоторое время alert'ы из скрипта, написанные для теста, тоже подряд, но уже после отработки цикла в 1ске, а не так, что Сообщить, alert, Сообщить, alert....
А выходит Сообщить,Сообщить,Сообщить.... alert,alert,alert... (13) Пока извратился так, дописал в скрипт в конце динамическое формирование таблицы, куда забиваю значения:

<script type="text/javascript">
       function getDistanceFor2Point(Point1, Point2) {
       var summuryDistance;
           ymaps.geocode(Point1).then(function (res) {
           var PointOne = res.geoObjects.get(0).geometry.getCoordinates();
           ymaps.geocode(Point2).then(function (res) {
           var PointTwo = res.geoObjects.get(0).geometry.getCoordinates();
           alert(ymaps.coordSystem.geo.getDistance(PointOne, PointTwo));
           summuryDistance = ymaps.coordSystem.geo.getDistance(PointOne, PointTwo);
           var x = document.getElementById('finallyTab').insertRow(0)
           var p1_cell=x.insertCell(0);
           var p2_cell=x.insertCell(1);
           var d_cell=x.insertCell(2);
               
           p1_cell.innerHTML=Point1;
           p2_cell.innerHTML=Point2;
           d_cell.innerHTML=summuryDistance;
           d_cell.value=summuryDistance;
       });
   
   });
   return summuryDistance;
   }
</script>

В теле страницы прописал таблицу:

<body>
<table id="finallyTab" width="488" border="1">
 <tr>
   <td width="165"></td>
   <td width="214"></td>
   <td id = "dist" value width="87"></td>
 </tr>
</table>
</body>

Куда собственно забивается всё, дописал функцию разбора сформированного в html поле документа и передачи массива из JS в 1С :

function tabl() {
var fruits = [];
//return myCars;
var table = document.getElementById('finallyTab');
var trList= table.getElementsByTagName('tr');
for (var i=0;i<trList.length;i++)
{
 var tdList = trList[i].getElementsByTagName('td');
 
//  for (j=0;j<tdList.length;j++)
//  {
   fruits[i]=tdList[2].innerHTML;
//    fruits.push(tdList[2].innerHTML);
//    alert('trList['+i+'] tdList['2'].innerHTML='+tdList[j].innerHTML);
//  }
}
return fruits;
}
</script>

Взят индекс 2, т.к. нужна только третья колонка, ну и процедура в 1С:

Процедура Кнопка3Нажатие(Элемент)
   // Вставить содержимое обработчика.
   ОтветJS = ЭлементыФормы.ПолеHTMLДокумента1.Документ.parentWindow.eval("tabl()");
//    Для каждого ЭлементМассива Из ОтветJS Цикл
//    Сообщить(ЭлементМассива);
//    КонецЦикла;
  // Сообщить(ОтветJS);
  инд = 0;
   Пока 1 = 1 цикл
       Попытка
           сообщить(ОтветJS[строка(инд)]);
           инд = инд + 1;
       Исключение
           прервать;
       КонецПопытки
   КонецЦикла;
КонецПроцедуры

Позаимствовал цикл перевода числового индекса в строковый отсюда v8: Передача массива из JavaScript в 1С , а то почему то тоже ругается, мол индексы не числовые.
В итоге значения получены, но через огромную Ж, буду дальше копать.
15 Asmody
 
25.02.13
01:31
Ну точно ajax, да еще вложенный.  Значится, нужно в самой последней callback-функции дернуть событие, которое умеет перехватывать 1Ска. У меня где-то был пример, попробую найти, если вспомню
16 Юрий Лазаренко
 
25.02.13
10:35
(15) Можно генерить onClick(), 1С его ловит
17 kofe88
 
06.03.13
01:16
Ребят, новый трабл, суть в том, выполняю все те же скрипты, в справочнике 27 объектов, цикл пробегает 27 раз

Если так Пока Выборка.Следующий() = 1 Цикл
       Сообщить(Выборка.Наименование);
       Буковки = Выборка.Адрес;
       Расстояние = ЭлементыФормы.ПолеHTMLДокумента1.Документ.parentWindow.eval("getDistanceFor2Point('" + Буковки + "','Россия, Cанкт-петербург, 6-я линия, 1/25')");
       Обработка();
Сообщить(Расстояние );
   КонецЦикла;

Соответственно функция getDistanceFor2Point выполняется 27 раз и результат я получаю, с этим всё ок, затем я перезагружаю страницу, чтобы выполнить этот же цикл, но для объектов из справочника Магистрали, а их 236, функция отрабатывает 236 раз и соответственно выводит ответы в html поле, но вот когда я это поле разбираю, то там находится только 27 ответов, а остальные 1Ска не видит, причем если сначала выполнить цикл с 236 объектами, а затем с 27, то всё ок, а если наоборот, то где-то теряется информация, как я понимаю в 1С есть кеш какой-то для этой страницы или что-то типа этого? Как его сбросить? пробовал перезагружать страницу между циклами так

ЭлементыФормы.ПолеHTMLДокумента1.Документ.parentWindow.location.reload();

и так

ЭлементыФормы.ПолеHTMLДокумента1.Перейти("about:blank");
ЭлементыФормы.ПолеHTMLДокумента1.Перейти("E:\geocode_new.html");

Результат всё тот же, пробовал в двух разных html полях, не помогло, пробовал пересоздавать документ в отладчике соответственно, и то же самое, помогает только перезапуск 1С, вот где оно может храниться? Всю голову сломал(
18 kofe88
 
09.03.13
18:19
Решил проблему, убрал функцию обработки таблицы tabl, оставил только функцию getDistanceFor2Point, в ней вызываю событие onHelp и отлавливаю его в 1Ске, спс (16) Юрий Лазаренко за наводку, решил делать onHelp а не OnClick, т.к. мало ли кто-то случайно кликнет в поле =)