Почему в 1С не получается получить HTML-форму по индексу через COM-объект Internet Explorer и как это исправить?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С:Предприятия с внешними сайтами или веб-сервисами разработчики часто используют COM-соединение с браузером через объект InternetExplorer.Application. В процессе написания кода для взаимодействия с веб-страницей можно столкнуться с неожиданной проблемой: при попытке получить доступ к форме или элементу коллекции по его индексу привычным способом Document.Forms[0] платформа 1С возвращает ошибку «Получение элемента по индексу не определено». При этом в отладчике объект и его коллекция видны, но обратиться к конкретному элементу через квадратные скобки напрямую не получается.

В этой статье мы подробно разберем, почему возникает данная ошибка, как правильно обращаться к коллекциям DOM-документа из 1С и какие современные альтернативы существуют, если целевой сайт перестал поддерживать Internet Explorer.

Выясняем причину ошибки обращения по индексу []

Для начала проанализируем поведение платформы 1С:Предприятие при работе с внешними COM-объектами. Когда мы обращаемся к свойству ie.document.forms, COM-сервер возвращает нам специальный объект коллекции (тип HTMLCollection или NodeList). В языке JavaScript, который выполняется внутри самого браузера, эти объекты являются массивоподобными, поэтому к ним можно без проблем обращаться с использованием квадратных скобок: forms[0].

Однако среда 1С взаимодействует с COM-объектом через универсальный интерфейс IDispatch. Платформа 1С:Предприятие не умеет автоматически транслировать синтаксис квадратных скобок [] во внутренний индексатор COM-объекта, если этот объект явно не описывает свойство по умолчанию. Так как у COM-объекта коллекции Internet Explorer нет явного свойства по умолчанию, понятного 1С, обращение по индексу в квадратных скобках вызывает ошибку выполнения.

Решение: использование встроенного метода .item()

Для обхода этой проблемы необходимо использовать явный вызов методов COM-объекта. Все стандартные коллекции DOM-элементов в Internet Explorer поддерживают метод item(), который принимает в качестве параметра числовой индекс элемента (начиная с 0) или его имя/идентификатор в виде строки.

Рассмотрим подробнее пример правильного кода для получения первой формы на веб-странице:


// Создаем объект браузера и переходим на сайт
ie = Новый COMОбъект("InternetExplorer.Application");
ie.Visible = Ложь; // Запускаем в фоновом режиме
ie.Navigate("https://example.com/login");

// Ожидаем завершения загрузки страницы
Пока ie.ReadyState < 4 Цикл
    ОбработкаПрерыванияПользователя();
КонецЦикла;

Документ = ie.document;

// Попытка обратиться через квадратные скобки вызовет ошибку:
// Неправильно: Форма = Документ.forms[0];

// Правильное обращение через метод item():
Попытка
    Форма = Документ.forms.item(0);
    Сообщить("Форма успешно получена! Имя формы: " + Форма.name);
Исключение
    Сообщить("Не удалось получить форму: " + ОписаниеОшибки());
КонецПопытки;

Важное примечание: Обратите внимание на написание метода. Метод называется именно item (в единственном числе, без буквы "s" на конце). Ошибка в названии метода (например, написание items(0)) также приведет к аварийному завершению работы скрипта.

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


КоличествоФорм = Документ.forms.length;
Для Индекс = 0 По КоличествоФорм - 1 Цикл
    ТекущаяФорма = Документ.forms.item(Индекс);
    Сообщить("Найдена форма с ID: " + ТекущаяФорма.id);
КонецЦикла;

Альтернативные способы поиска элементов на странице

Чтобы сделать ваш код более отказоустойчивым и независимым от порядка расположения элементов (ведь порядок форм на странице может измениться в любой момент, и индекс 0 станет неактуальным), мы рекомендуем использовать другие методы поиска элементов в DOM:

  1. Поиск по уникальному идентификатору (ID): Если форма имеет уникальный атрибут id, используйте метод getElementById. Он возвращает конкретный элемент напрямую, минуя коллекции.
    
    // Получаем элемент напрямую по его ID
    Форма = Документ.getElementById("main_login_form");
    Если Форма <> Неопределено Тогда
        // Работаем с формой напрямую
        Форма.submit();
    КонецЕсли;
    
  2. Поиск по имени (Name): Можно получить элемент по его имени из коллекции элементов формы.
    
    // Обращение к элементу по его строковому имени внутри коллекции
    ПолеВвода = Форма.elements.item("USER_LOGIN");
    ПолеВвода.value = "Администратор";
    

Что делать, если целевой сайт не работает в Internet Explorer?

Современные веб-технологии стремительно развиваются, и многие сайты полностью прекращают поддержку браузера Internet Explorer (даже версии IE11), называя его устаревшим. В результате скрипты автоматизации 1С через COM-объект InternetExplorer.Application начинают завершаться с ошибками выполнения JavaScript на стороне сайта.

Проанализируем современные варианты решения этой проблемы в среде 1С:Предприятие:

Вариант 1. Использование встроенного «Поля HTML-документа» на движке WebKit (Chromium)

Если ваша задача состоит в отображении сайта и управлении им непосредственно в интерактивном режиме внутри формы 1С, вам больше не нужен Internet Explorer. Начиная с версии платформы 8.3.14, фирма «1С» полностью перевела встроенный элемент управления «Поле HTML-документа» на современный движок WebKit / Chromium.

Теперь любой сайт будет отображаться корректно прямо внутри формы вашей обработки. Однако при переходе на новый движок WebKit изменятся методы программного управления страницей из кода 1С:

Пример программного взаимодействия с новым движком WebKit в управляемой форме 1С:


// Получаем объект окна браузера WebKit
ОкноБраузера = Элементы.ПолеHTMLДокумента.Документ.defaultView;

// Заполняем поле формы и отправляем ее через выполнение JS-кода
СкриптЗаполнения = "
|document.forms[0].elements['USER_LOGIN'].value = 'Администратор';
|document.forms[0].submit();
|";

ОкноБраузера.eval(СкриптЗаполнения);

Вариант 2. Автоматизация современных браузеров (Chrome, Edge, Firefox) через Selenium WebDriver

Если вам требуется фоновая автоматизация внешнего полноценного браузера без показа интерфейса пользователю, напрямую запустить Chrome через COM-объект наподобие Новый COMОбъект("GoogleChrome.Application") не получится, так как современные браузеры не предоставляют COM-интерфейсов для Windows.

Для решения этой задачи используется профессиональный инструмент автоматизации — Selenium WebDriver. Схема взаимодействия выглядит следующим образом:

  1. На компьютере запускается консольное приложение веб-драйвера (например, chromedriver.exe для браузера Google Chrome). Этот драйвер выступает в роли локального HTTP-сервера.
  2. Из кода 1С с помощью объекта HTTPСоединение отправляются команды на этот локальный сервер в формате JSON-запросов (по протоколу W3C WebDriver).
  3. Веб-драйвер принимает запросы от 1С, транслирует их в команды для Chrome, выполняет действия (открытие страниц, поиск элементов, клики, ввод текста) и возвращает результат обратно в 1С.

Посмотрим на пример отправки HTTP-запроса из 1С к ChromeDriver для инициализации новой сессии браузера Chrome:


// Настраиваем соединение с запущенным chromedriver.exe (по умолчанию порт 9515)
Соединение = Новый HTTPСоединение("localhost", 9515);

// Подготавливаем JSON-параметры запуска Chrome
ПараметрыЗапуска = Новый Соответствие;
ПараметрыЗапуска.Вставить("capabilities", Новый Соответствие);

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапуска);
ТелоЗапроса = ЗаписьJSON.Закрыть();

HTTPЗапрос = Новый HTTPЗапрос("/session");
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Попытка
    HTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
    Если HTTPОтвет.КодСостояния = 200 Тогда
        Сообщить("Сессия Chrome успешно запущена. Браузер готов к автоматизации!");
    КонецЕсли;
Исключение
    Сообщить("Не удалось запустить Chrome через WebDriver: " + ОписаниеОшибки());
КонецПопытки;

Использование связки 1С и Selenium WebDriver позволяет полностью отказаться от устаревших COM-объектов Internet Explorer, обеспечивая быструю, стабильную и современную работу с любыми веб-ресурсами непосредственно из кода вашей конфигурации.

← На главную