VBA: getHTML как пользовательская функция - избегайте нескольких повторов HTML - PullRequest
0 голосов
/ 26 сентября 2018

Я использую это для извлечения HTML из веб-страницы

Function GetHTML(url As String) As String    
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", url, False
        .Send
        GetHTML = .ResponseText
    End With

End Function

Я создал другую пользовательскую функцию (fromthewebpage) для извлечения информации из HTML и помещения ее в 2d массив.

Function fromthewebpage(month,user)
    testtext=GetHTML("http://example.com")
    ....
    ....
    fromthewebpage= udarray(month,user)
End function

Когда мне нужна информация на листе, я вспоминаю ее с помощью = fromthewebpage (x, y) в ячейке.

Но размер массива составляет 13 * 4, и мне нужен весь массив икаждое использование функции fromthewebpage (x, y) вызывает GetHTML независимо, что приводит к 52 поискам страницы.Существуют ли способы вызывать GetHTML только один раз и повторно использовать эту информацию для каждого использования fromthewebpage.

Я представляю либо 1) вызов GetHTML при открытии книги и сохранение информации в постоянном массиве, на который я могу ссылаться при использовании с thewebpageили 2) сделать из веб-страницы функцию массива.Но я не знаю, возможно ли это и как это сделать.

1 Ответ

0 голосов
/ 26 сентября 2018

Итак, я упомянул в комментариях идею использования подпрограммы для извлечения информации HTML и возврата вашего массива на лист.Затем вы можете использовать функцию или формулы для индексации этой информации.

В приведенном ниже подпункте выбирается URL-адрес из диапазона A1 рабочего листа1.Вы можете привязать сабвуфер к кнопке или событию изменения рабочего листа с целевым значением A1, поэтому обновляется при изменении URL.

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

GetHTML возвращает массив на лист.Функция GetInfo позволяет индексировать этот массив и возвращать элемент, указав строку и столбец в массиве.Он предназначен для отражения двух указанных вами аргументов в сигнатуре функции для извлечения строки.

Option Explicit
Public Sub GetHTML()
    Dim html As htmldocument, ws As Worksheet
    Set html = New htmldocument: Set ws = ThisWorkbook.Worksheets("Sheet1")
    On Error GoTo errhand
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", ws.[A1], False
        .Send
        html.body.innerhtml = .ResponseText
    End With

    Dim arr(0 To 13, 0 To 4)
    Dim i As Long, r As Long, c As Long
    Dim aNodeList As Object
    Set aNodeList = html.querySelectorAll("#question-mini-list h3 > a[href]")
    For i = 0 To (14 * 5) - 1
       If i = 0 Then
           arr(r, c) = aNodeList.Item(i)
       ElseIf i Mod 5 = 0 And i <> 0 Then
           r = r + 1: c = 0
           arr(r, c) = aNodeList.Item(i)
       Else
          c = c + 1
          arr(r, c) = aNodeList.Item(i)
       End If
    Next

    ws.[B1].Resize(UBound(arr, 1) + 1, UBound(arr, 2) + 1) = arr
errhand:
    If Err.Number <> 0 Then Err.Clear
End Sub

Public Function GetInfo(ByVal r As Long, ByVal c As Long) As String
    GetInfo = ThisWorkbook.Worksheets("Sheet1").Range("B1:F14").Cells(r + 1, c + 1)
End Function

В листе вызова UDF:

enter image description here


Событие Worksheet_Change

Если связать выполнение sub GetHTML с событием Worksheet_Change с URL в A1, а затем в коде листа 1панель:

Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    If Target.Address = [A1].Address Then
        GetHTML
    End If
    Application.EnableEvents = True
End Sub
...