Как очистить объекты в Excel vba? - PullRequest
0 голосов
/ 17 октября 2018
Public Sub D_Galoplar()
    Application.ScreenUpdating = False
    Dim Asay(1 To 250)
    Dim Jsay(1 To 100)
    For q = 2 To Sheets("Y").Columns("A:A").Find(What:="boş").Row - 1
        Asay(q - 1) = Sheets("Y").Range("A" & q)
    Next q
    For q = 2 To Sheets("Y").Columns("C:C").Find(What:="boş").Row - 1
        Jsay(q - 1) = Sheets("Y").Range("C" & q)
    Next q
For w = 1 To 250
    Cells.Delete Shift:=xlUp
    Range("A1").Select
    If Asay(w) < 1 Then Exit For

    Dim elem As Object, trow As Object
    Dim R&, C&, s$
    With New XMLHTTP60
        .Open "POST", "https://yenibeygir.com/at/getatdetaytab", False
        .setRequestHeader "content-type", "application/x-www-form-urlencoded; charset=UTF-8"
        .send "tab=galopTab&id=" & Asay(w)
        s = .responseText
    End With
    With New HTMLDocument
        .body.innerHTML = s
        For Each elem In .getElementsByClassName("at_Galoplar")(0).Rows
            For Each trow In elem.Cells
                C = C + 1: Cells(R + 1, C) = trow.innerText
            Next trow
            C = 0: R = R + 1
        Next elem
    End With

    Cells.UnMerge
    Range("A1").Select

    If Range("A1048576").End(xlUp).Row < 2 Then GoTo ATLA2

    Columns("A:A").Insert
    For i = 2 To Range("B1048576").End(xlUp).Row - 1
        Range("A" & i) = Asay(w)
    Next i

    Range("O2").FormulaR1C1 = "=IF(ISBLANK(RC[-9]),""-"",IF(ISNUMBER(RC[-9]),RC[-9]/4,((LEFT(RC[-9],1)*6000)+(MID(RC[-9],3,2)*100)+(RIGHT(RC[-9],1)*10))/400))"
    Range("P2").FormulaR1C1 = "=IF(ISBLANK(RC[-9]),""-"",IF(ISNUMBER(RC[-9]),RC[-9]/6,((LEFT(RC[-9],1)*6000)+(MID(RC[-9],3,2)*100)+(RIGHT(RC[-9],1)*10))/600))"
    Range("Q2").FormulaR1C1 = "=IF(ISBLANK(RC[-9]),""-"",IF(ISNUMBER(RC[-9]),RC[-9]/8,((LEFT(RC[-9],1)*6000)+(MID(RC[-9],3,2)*100)+(RIGHT(RC[-9],1)*10))/800))"
    Range("R2").FormulaR1C1 = "=IF(ISBLANK(RC[-9]),""-"",IF(ISNUMBER(RC[-9]),RC[-9]/10,((LEFT(RC[-9],1)*6000)+(MID(RC[-9],3,2)*100)+(RIGHT(RC[-9],1)*10))/1000))"
    Range("S2").FormulaR1C1 = "=IF(ISBLANK(RC[-9]),""-"",IF(ISNUMBER(RC[-9]),RC[-9]/12,((LEFT(RC[-9],1)*6000)+(MID(RC[-9],3,2)*100)+(RIGHT(RC[-9],1)*10))/1200))"
    Range("T2").FormulaR1C1 = "=IF(ISBLANK(RC[-9]),""-"",IF(ISNUMBER(RC[-9]),RC[-9]/14,((LEFT(RC[-9],1)*6000)+(MID(RC[-9],3,2)*100)+(RIGHT(RC[-9],1)*10))/1400))"
    Range("O2:T2").Copy
    Range("O2:O" & Range("A1048576").End(xlUp).Row).PasteSpecial Paste:=xlPasteFormulas
    Cells.Copy
    Cells.PasteSpecial Paste:=xlPasteValues
    Columns("O:T").Cut Columns("F:K")

    Range("A2:N" & Range("A1048576").End(xlUp).Row).Copy
    Sheets("Galop").Range("A" & Sheets("Galop").Range("A1048576").End(xlUp).Row + 1).PasteSpecial Paste:=xlPasteValues

ATLA2:
    Cells.Delete Shift:=xlUp
Next w
End Sub

Я хочу получить много данных с циклом For Next, но через некоторое время страница зависает.Как я могу сбросить объекты в конце каждого цикла?

Asay числа 10182 10221 10279 10303 10316 10325 10360 10370 10680 11598 11629 11715 11745 12335 12385 12533 ​​12559 13154 13393 13635 13641 13669 13673 14027 14057 14062 14228 14619686767676714743 14770 14778 15197 15217 15323 15382 15507 15775 15828 16077 16335 16510 17149 17513 17867 18532 37964 60176 66067 66255 66581 66582 66896 66998 67056 67309 67356 67379 67473 68008 68012 68162 68298 68312 68320 68332 68333 68353 68383 68545 68702 68775 68922 69445 69606 69817 69963 69968 6998569986 70048 70202 71372 (бош)

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

Попробуйте установить для этого объекта значение Nothing, как показано ниже:

Set elem = Nothing
Set trow = Nothing

Я не уверен, нужны ли вам объявления переменных в цикле, вы можете вывести их из цикла, это может сэкономить некоторыевремя.

Но я думаю, что ваши HTTP-запросы занимают так много времени, а не VBA-код.

ОБНОВЛЕНИЕ

Попробуйте установить Application.EnableEvents и Application.ScreenUpdating до False в начале макроса и возвращение их к True в конце.

0 голосов
/ 17 октября 2018

Замедление может быть вызвано ограничением сети, если вы пытаетесь зайти на сайт слишком много раз подряд.Это особенно вероятно, учитывая ваш метод доступа.Лучше было бы посмотреть, доступен ли API для массового доступа к информации.Вы, вероятно, пройдете через много сетей, чтобы попасть на эту страницу.Может быть возможно получить некоторую основную информацию о задержках из команды TRACERT из командной строки.

Вы выполняете POST, поэтому помните, что на стороне сервера происходит довольно много вещей, посколькуЧто ж.

Вам не нужно устанавливать elem на Nothing, так как он существует только во время вашего For Loop.То же самое для tRow.

Помещение .getElementsByClassName("at_Galoplar")(0).Rows в переменную обеспечит более быструю ссылку.

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

Использование ключевого слова New может привести к неожиданному поведению.Вы можете создать один экземпляр HTMLDocument и работать с ним при условии, что у вас будет хорошая обработка ошибок. У меня были случайные случаи в цикле, когда мне приходилось устанавливать HTMLDocument в Nothing перед повторным циклом.


Лично я бы обманул и переписал бы это для того, чтобы использовать GET-запросы для получения той же информации.Я использую класс для хранения объекта XMLHTTP и массив для хранения результатов.Я пишу результаты за один раз.Это займет несколько секунд, чтобы бежать за мной.Числа асей находятся в диапазоне Sheet1 A1:A84.

Модуль класса clsHTTP

Option Explicit    
Private http As Object

Private Sub Class_Initialize()
    Set http = CreateObject("MSXML2.XMLHTTP")
End Sub

Public Function GetString(ByVal url As String) As String
    Dim sResponse As String
    With http
        .Open "GET", url, False
        .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
        .send
        sResponse = StrConv(.responseBody, vbUnicode)
        GetString = sResponse
    End With
End Function

Стандартный модуль 1

Option Explicit
Public Sub DGaloplar()
    Dim asays(), ws As Worksheet, asay As Long, html As HTMLDocument
    Dim http As clsHTTP, url As String, headers(), numberOfRequests As Long

    headers = Array("Asay", "Tarih", "Sehir", "Kg", "Jokey", "400", "600", "800", "1000", "1200", "1400", "Ç", "Pist", "Durum")
    Set http = New clsHTTP
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Set html = New HTMLDocument
    asays = Application.Transpose(ws.Range("A1:A84").Value) 'Load asay values from sheet 1

    Const numTableRows As Long = 11
    Const numTableColumns As Long = 15
    Const BASE_URL As String = "https://yenibeygir.com/at/getatdetaytab/?tab=galopTab&id="

    numberOfRequests = UBound(asays)

    Dim results(), headerRow As Boolean, tRows As Object, tRow As Object, iRow As Long
    Dim tCells As Object, tCell As Object, r As Long, c As Long, hTable As HTMLTable
    ReDim results(1 To numTableRows * numberOfRequests, 1 To numTableColumns)

    Application.ScreenUpdating = False

    For asay = 1 To numberOfRequests
        headerRow = True
        url = BASE_URL & asays(asay)
        html.body.innerHTML = http.GetString(url)
        Set hTable = html.querySelector(".at_Galoplar")
        Set tRows = hTable.getElementsByTagName("tr")

        For Each tRow In tRows
            If Not headerRow Then
                c = 2: r = r + 1
                results(r, 1) = asays(asay)
                Set tCells = tRow.getElementsByTagName("td")
                For Each tCell In tCells
                    results(r, c) = tCell.innerText
                    c = c + 1
                Next
            End If
            headerRow = False
        Next
    Next

    With ws
        .Cells(1, 3).Resize(1, UBound(headers) + 1) = headers
        .Cells(2, 3).Resize(UBound(results, 1), UBound(results, 2)) = results
    End With
    Application.ScreenUpdating = True
End Sub

Ссылки:

  1. Библиотека объектов Microsoft HTML
0 голосов
/ 17 октября 2018

В общем случае Set elem = Nothing - это то, что вам нужно.

В вашем коде вы присваиваете переменные в цикле for-each, поэтому даже если вы установите их в Nothing позже, не будетбонус за производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...