2015-01-07 2 views
-1

Я хочу, чтобы мой макрос excel перешел на этот сайт, войдите в систему и скопируйте всю таблицу и вставьте ее в таблицу Excel.Excel VBA: Войдите на сайт, вытащите данные из таблицы

Я не слишком хорошо знаком с ExcelVba, и я не знаю, что делать после входа на сайт.

Заранее спасибо.

Sub DataPulling() 

Dim ieApp As InternetExplorer 
Dim ieDoc As Object 
Dim URL As String 
Dim ReportURL As String 
Dim CurrentSheet As Worksheet 
Dim HTML_Element As IHTMLElement 
Dim HTMLDoc As HTMLDocument 

'set CurrentSheet as Active Worksheet 
Set CurrentSheet = ActiveSheet 

'On the Error, go Err_Clear 
On Error GoTo Err_Clear 

'Create a new instance of IE 
Set ieApp = New InternetExplorer 

'Declare Web Addresses 
URL = "http://www.login-page.com" 
ReportURL = "http://www.the-table-page.com" 

ieApp.Visible = True 
ieApp.Silent = True 

'Go to the main website 
ieApp.navigate URL 

Do 
    Loop Until ieApp.readyState = READYSTATE_COMPLETE 
    Set HTMLDoc = ieApp.document 
    HTMLDoc.all.UserId.Value = "userid" 
    HTMLDoc.all.password.Value = "password" 

    For Each HTML_Element In HTMLDoc.getElementsByTagName("input") 
     If HTML_Element.Type = "submit" Then HTML_Element.Click: Exit For 
    Next 

ieApp.navigate ReportURL 

Do While ieApp.Busy 
    DoEvents 
Loop 

'I dont know what to put here..!!?? 

ieApp.Quit 

Set ieApp = Nothing 
Set ieDoc = Nothing 

и исходная страница сайта выглядит примерно ниже ..

<div id="divDt" class="dt"> 
<table id="tblActiveProjects" class="display dt" cellspacing="0"> 
    <thead> 
     <tr> 
      <th>ContentA1</th> 
      <th>ContentA2</th> 
      <th>ContentA3</th> 
      <th>ContentA4</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr> 
      <th>ContentB1</th> 
      <th>ContentB2</th> 
      <th>ContentB3</th> 
      <th>ContentB4</th> 
     </tr> 

ответ

0

Этот фрагмент кода может помочь вам:

Dim tb As Object, tr As Object, th As Object 
    Dim yourValue As String 

    Set tb = HTMLdoc.getElementById("tblActiveProjects") 'tb is the Table object 

    For Each tr In tb.Rows 'loop through the <tr> rows of your table 
     For Each th In tr.cells 'loop through the <th> cells of your row 
     yourValue = th.outerText 'your value is now in the variable "yourValue" 
     Next th 
    Next tr 

Значение, содержащееся в каждом th элемент получает временно сохраненный в переменной yourValue. Я позволяю вам решить, если вы хотите добавить его в коллекцию значений:

Dim myValues As New Collection 
'... 
    myValues.Add th.outerText 

... или печать его в ячейку таблицы ...

Range("A" & j).Value = th.outerText 
j = j + 1 

... или что-то еще вы бы как делать с вашими значениями. Обратите внимание, что это начальный ввод, вам, вероятно, потребуется настроить код, чтобы он полностью соответствовал вашим потребностям.

EDIT - как иметь дело с «объект не установлен»

В основном, веб-страница представляет собой файл, загруженный из машины сервера через Интернет. Когда вы автоматизируете Интернет, вы «работаете» с VBA (Ferrari) против сервера, загружающего HTML-файл и его содержимое из баз данных через подключение к Интернету (старик на старом осле).

Другими словами, вам нужно сообщить программе VBA, что дождаться загрузки веб-страницы, иначе вы рискуете начать поиск переменной до того, как сервер переместит ее на веб-страницу. Вы на самом деле уже делать что-то вроде этого в коде:

Do While ieApp.Busy 
    DoEvents 
Loop 

Этот код будет цикл до тех пор, оператор ieApp.Busy вернется False; когда он больше не занят, он освободит код и снова запустит его.

Что может случиться с вами иногда?

В зависимости от архитектуры хост-сервера вашего веб-сайта, а также от дизайна веб-страницы может случиться так, что иногда приложение освобождается до того, как оно действительно загрузило данные. Следовательно, когда вы попытаетесь посмотреть For Each tr In tb.Rows, вы не найдете Rows в свой tb, потому что в тот момент, когда ваше исполнение имеет Set tb = HTMLdoc.getElementById("tblActiveProjects), этот объект был по-прежнему пуст.

Следовательно, «неэлементное», но лучшее решение, чтобы избежать такого рода задержек, заключается в том, чтобы поставить официанта физического времени в случае ошибки. Для того, чтобы говорить «в коде»:

'we turn on the error handler. If there is an error, it will ignore it and go to the next instruction 
    On Error Resume Next 
    'we try to set the element. We don't know how it will go... 
    Set tb = HTMLdoc.getElementById("tblActiveProjects") 'tb is the Table object 

    If Err.Number <> 0 Then 'if an error occurred, we wait for 5 seconds and then we re-try 
     Application.Wait TimeSerial(Hour(Now()), Minute(Now()), Second(Now()) + 5) 
     Set tb = HTMLdoc.getElementById("tblActiveProjects") 'we retry, it should be fine 
     On Error GoTo 0 'we re-turn the error to 0 
    End If 

    On Error Resume Next 'we re-turn the error handler on 
    Set whatever = tb.Rows 'we see if there's something wrong here 

    If Err.Number <> 0 Then 'if an error occurred now, it means the table existed but was empty, so we wait for 5 seconds and then we re-set the object that this time should be filled up 
     Application.Wait TimeSerial(Hour(Now()), Minute(Now()), Second(Now()) + 5) 
     Set tb = HTMLdoc.getElementById("tblActiveProjects") 'we retry, it should be fine 
     On Error GoTo 0 'we re-turn the error to 0 
    End If   

    'we restart our code execution regularly, this time we're almost sure our browser has been able to load the content 

    For Each tr In tb.Rows 'loop through the <tr> rows of your table 
     For Each th In tr.cells 'loop through the <th> cells of your row 
     yourValue = th.outerText 'your value is now in the variable "yourValue" 
     Next th 
    Next tr 

Опять же, это не очень хорошее решение, но с веб-соскоб (т.е.необработанное очищение данных, а не использование какого-либо лучшего API), это все о работе, которая работает в 99% случаев.

+0

Здравствуйте, @Matteo, ваш код отлично работает большую часть времени, но иногда я получаю это сообщение об ошибке «Ошибка времени выполнения 91»: переменная объекта или с переменной блока не установлена ​​»в вашем первом цикле. можно ли это исправить? Благодарю. –

+0

Привет @JLee, конечно. Где это происходит точно? –

+0

Это происходит на этой линии -> Для каждого tr In tb.Rows –