Как в 1С 7.7 получить список вариантов (options) из элемента select?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При автоматизации взаимодействия 1С 7.7 с веб-сервисами или при парсинге веб-страниц часто возникает необходимость программно извлечь данные из выпадающих списков (тег select). В 1С 7.7 нет встроенных средств для работы с HTML-документами, поэтому мы вынуждены использовать внешние COM-объекты, предоставляемые операционной системой. Рассмотрим подробнее несколько способов решения этой задачи, начиная от использования браузера Internet Explorer и заканчивая разбором HTML как XML-структуры.

Способ 1. Использование объекта InternetExplorer.Application

Этот метод наиболее удобен, если вам нужно не просто прочитать HTML-код, а взаимодействовать со страницей в реальном времени (например, после авторизации или нажатия кнопок). Мы можем создать экземпляр браузера, загрузить страницу и обратиться к её объектной модели (DOM).

Проанализируем ситуацию, когда нам нужно получить все значения из списка с известным id. Для этого мы будем использовать коллекцию options, которая есть у каждого элемента select в объектной модели Internet Explorer.

Рассмотрим по шагам пример кода для получения данных:


// Создаем объект браузера
ИЕ = СоздатьОбъект("InternetExplorer.Application");
ИЕ.Visible = 0; // Окно браузера будет скрыто
ИЕ.Navigate("http://www.пример-сайта.рф");

// Ожидаем полную загрузку страницы
Пока ИЕ.ReadyState <> 4 Цикл
    Состояние("Загрузка страницы...");
КонецЦикла;

// Получаем объект нужного нам селекта по его ID
Попытка
    Селект = ИЕ.document.getElementById("ContentPlaceHolder1_DropDownList3");
    КолвоВариантов = Селект.options.length;
    
    Для Ном = 0 По КолвоВариантов - 1 Цикл
        ТекВариант = Селект.options(Ном);
        Значение = ТекВариант.value; // Значение атрибута value
        Текст = ТекВариант.text;     // Видимый текст в списке
        
        Сообщить("Элемент №" + Ном + ": Значение = " + Значение + ", Текст = " + Текст);
    КонецЦикла;
Исключение
    Сообщить("Элемент на странице не найден!");
КонецПопытки;

Важный момент: Обратите внимание на различие свойств value и text. Первое обычно содержит технический идентификатор, который отправляется на сервер, а второе — то, что видит пользователь на экране.

Способ 2. Использование легковесного объекта htmlfile

Если у вас уже есть текст HTML-кода (например, вы получили его через WinHttp.WinHttpRequest.5.1 или прочитали из файла), запускать полноценный процесс iexplore.exe избыточно. В этом случае мы рекомендуем использовать объект htmlfile. Он работает гораздо быстрее и потребляет меньше ресурсов.

Выясним, как реализовать этот подход:


// Предположим, переменная ТекстHTML содержит ваш код со списком
HTMLДок = СоздатьОбъект("htmlfile");
HTMLДок.write(ТекстHTML);

// Ищем элемент
Селект = HTMLДок.getElementById("ContentPlaceHolder1_DropDownList3");

Если ПустоеЗначение(Селект) = 0 Тогда
    Для и = 0 По Селект.options.length - 1 Цикл
        Вариант = Селект.options(и);
        Сообщить("Найдено: " + Вариант.text + " [" + Вариант.value + "]");
    КонецЦикла;
КонецЕсли;

Способ 3. Парсинг через Microsoft.XMLDOM

Иногда HTML-код страницы достаточно строгий (соответствует стандартам XHTML), что позволяет рассматривать его как обычный XML. В этом случае можно использовать объект Microsoft.XMLDOM. Этот метод требует рекурсивного обхода узлов, так как структура документа может быть вложенной.

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


Процедура ОбработатьУзел(Узел, Уровень=0)
    КолвоУзлов = Узел.childNodes.length;
    Для СчУзлов = 0 По КолвоУзлов-1 Цикл
        ТекУзел = Узел.childNodes.item(СчУзлов);
        
        // Нас интересуют только узлы типа "Элемент" (Type 1)
        Если ТекУзел.nodeType <> 1 Тогда 
            Продолжить; 
        КонецЕсли;
        
        // Если нашли тег option, выводим его данные
        Если Врег(ТекУзел.tagName) = "OPTION" Тогда
            Значение = ТекУзел.getAttribute("value");
            Текст = ТекУзел.text;
            Сообщить("Опция XML: " + Текст + " (val=" + Значение + ")");
        КонецЕсли;
        
        // Рекурсивно идем глубже
        ОбработатьУзел(ТекУзел, Уровень+1);
    КонецЦикла;
КонецПроцедуры

// Использование:
Иксемель = СоздатьОбъект("Microsoft.XMLDOM");
Иксемель.Load(ИмяФайла);
Корень = Иксемель.DocumentElement;
ОбработатьУзел(Корень);

Предупреждение: Данный способ может вызвать ошибку, если HTML-код страницы не является валидным XML (например, есть незакрытые теги <br> или <img>). Для "грязного" HTML лучше использовать способы с объектами Internet Explorer.

Особенности работы с ASP.NET (PostBack)

Проанализируем структуру select из примера автора. Там присутствует атрибут onchange="javascript:setTimeout('__doPostBack(...)', 0)". Это характерная черта сайтов на платформе ASP.NET. Если ваша задача — не просто прочитать список, но и выбрать в нем значение так, чтобы страница обновилась, обычного изменения selectedIndex будет недостаточно.

Чтобы имитировать выбор пользователя и заставить сайт обновить данные, выполните следующий скрипт после смены индекса:


// Выбираем второй элемент (индекс 1)
Селект = ИЕ.document.getElementById("ContentPlaceHolder1_DropDownList3");
Селект.selectedIndex = 1;

// Инициируем событие изменения, чтобы сработал JavaScript сайта
ИЕ.document.parentWindow.execScript("__doPostBack('ctl00$ContentPlaceHolder1$DropDownList3','')");

Использование регулярных выражений для быстрого извлечения

Если вам нужно очень быстро получить список всех вариантов из огромного HTML-файла, не строя дерево объектов DOM, можно воспользоваться объектом VBScript.RegExp. Посмотрим на пример шаблона:


RegExp = СоздатьОбъект("VBScript.RegExp");
RegExp.IgnoreCase = 1;
RegExp.Global = 1;
RegExp.Pattern = "<option.*?value=[""']?(.*?)[""']?>(.*?)</option>";

Matches = RegExp.Execute(ТекстHTML);
Для и = 0 По Matches.Count - 1 Цикл
    Match = Matches.Item(и);
    Значение = Match.SubMatches(0);
    Текст = Match.SubMatches(1);
    Сообщить("RegExp нашел: " + Текст + " = " + Значение);
КонецЦикла;

Подведем итог. Для надежной работы с элементами select в 1С 7.7 наиболее предпочтительным является использование COM-объекта Internet Explorer или htmlfile, так как они предоставляют готовую коллекцию options и корректно обрабатывают все нюансы HTML-разметки.

← На главную