hejke

Selection by Table Class Name with Multiple Tables

9 posts in this topic

#1 ·  Posted

Hello! First post here. I've been having fun with autoit for a few weeks now.

So, I'm trying to get a few tables from a website (it's a private one, so I can't give links). The problem is that the index of each table changes for each different search, so I can't use _IETableGetCollection. I searched in the forum and I found this topic, and I adapted it to my needs. The problem is that there's more than one table, and I need all the tables with <table class="detailsform"> to be shown (and then I want to copy them to an excel, but that's not the problem now). Is there any way to do this? Here is what I have:

 

Local $oIE = _IECreate("URL", 1, 1, 1, 1)
$oTables =_IETagNameGetCollection ($oIE, "table")
$index = 0
For $oTable in $oTables
    $sText = $oTable.className
    If String ($oTable.className) = "detailsform" Then
        $aTableData = _IETableWriteToArray ($oTable, True)
        _ArrayDisplay($aTableData)
        ExitLoop
    Else
        ConsoleWrite($index & ":  [" & $oTable.className & "]" & @CR)
        $index += 1
    EndIf
Next
ConsoleWrite($index & ":END [" & $oTable.className & "]" & @CR)

 

I'am VERY new in this, I have just a few weeks of practice.

Thanks in advance!

Share this post


Link to post
Share on other sites



#2 ·  Posted

You haven't indicated what isn't working with your existing code. However, here are a few comments --

  • You could use _IETableGetCollection with an index of -1, which would give the same result as _IETagNameGetCollection
  • If you need this to work for multiple tables, then you will want to remove the ExitLoop command

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

While I couldn't test it do to the fact that the url for your project is private, this should work.  If it doesn't, try changing the "className" property to "classList":

#include <IE.au3>

$oIE = _IECreate ( "URL" )
_IELoadWait ( $oIE )
$tables = _IETableGetCollection ( $oIE )
For $table In $tables
    If StringCompare ( $table.className, "detailsform" ) = 0 Then
        ;put code for actions you want to perform on tables of class=detailsform
    Else
        ContinueLoop
    EndIf
Next

I am pretty impressed with your code.  Everything actually appears to be correct in the snippet you provided with the one exception of the line:

$oTables =_IETagNameGetCollection ($oIE, "table")

Change it to:

$tables = _IETableGetCollection ( $oIE )

And that should work for you.

Edited by MattHiggs

Share this post


Link to post
Share on other sites

#4 ·  Posted

2 hours ago, MattHiggs said:

Everything actually appears to be correct in the snippet you provided with the one exception of the "If" statement in your for loop.  It should be:

If String ($oTable.className) == "detailsform" Then

The "==" performs a comparison operation, but I would still use "StringCompare" if I were you, since it, by default, is case-insensitive.

Ahem, what do you feel is incorrect with the = operator instead?

And why use String() at all?


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#5 ·  Posted

4 minutes ago, jchd said:

Ahem, what do you feel is incorrect with the = operator instead?

And why use String() at all?

Well look at that....  You are right....  Its been awhile since I looked at the comparison operators portion of the help file.  jchd is right, "=" is perfectly ok.  Editing original response....

Share this post


Link to post
Share on other sites

#6 ·  Posted

22 hours ago, Danp2 said:
  • If you need this to work for multiple tables, then you will want to remove the ExitLoop command

That worked... for a while.

Ok, so I removed the ExitLoop command and every was fine. It gave me all the tables in the website, which was that I wanted it.

Then I wanted to put the tables in an excel. I used _ArrayExtrac to select only the last row, that has the information I want, but when I run it two things happened... Here's my code (partly in Spanish, my mother tongue):

#include <IE.au3>
#include <Array.au3>
#include <Excel.au3>
#include <MsgBoxConstants.au3>

; Open Excel
$oExcel = _Excel_Open()
$oWorkbook = _Excel_BookOpen ($oExcel, "path\file.xlsx")
$CeldaA = "A"
$CeldaB = "B"
For $i = 2 to 15
$CelA = String ($CeldaA & $i)
$eXiD = _Excel_RangeRead ($oWorkbook, $oWorkbook.Activesheet, $CelA)
$ID = String ($eXiD)
; Open IExplorer
$oIE = _IECreate ()
_IENavigate ($oIE, "URL", 1)
$o_SearchForm = _IEGetObjById ($oIE, "tbSearch")

; Login if it's not
If @error Then
    _IENavigate ($oIE, "URL/LOGIN", 1)
    $Usrname = "user"
    $Passwrd = "pass"
    $oSearchUsr = _IEGetObjById ($oIE, "ctl00_content__login_UserName")
    _IELoadWait ($oIE)
    _IEFormElementSetValue ($oSearchUsr, $Usrname)
    $oSearchPwd =_IEGetObjById ($oIE, "Password")
    _IEFormElementSetValue ($oSearchPwd, $Passwrd)
    $oButton = _IEGetObjById($oIE, "ctl00_content__login_ImageButton1")
    _IEAction ($oButton, "click")
    _IELoadWait($oIE)
EndIf

; Search the value in the "A" column
_IENavigate ($oIE, "URL", 1)
$o_SearchForm = _IEGetObjById ($oIE, "tbSearch")
_IEFormElementSetValue ($o_SearchForm, $ID)
$oButton = _IEGetObjByName($o_SearchForm, "ctl22")
_IEAction ($oButton, "click")
_IELoadWait($oIE)
_IELinkClickByText ($oIE, $ID)
_IELoadWait ($oIE)

; Search table
$oTables =_IETagNameGetCollection ($oIE, "table")
$index = 0
For $oTable in $oTables
    $sText = $oTable.className
    If String ($oTable.className) = "detailsform" Then
        $aTableData = _IETableWriteToArray ($oTable)
    EndIf
Next

; Writes the table in Excel in the B column
$CelB = String ($CeldaB & $i)
;~ Local $iRow2Write2 = $oWorkBook.Activesheet.UsedRange.Rows.Count + 1
Local $aTableRow = _ArrayExtract ($aTableData, 2, 2, 0, 6)
_Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $aTableRow, $CelB)
_IEQuit($oIE)
Next

I'm trying to search a value that is in "A2", "A3"... "A15" in an Excel file, get all the tables in the new URL, take the last row of each table, and write them next to the value in the Excel, that is, in "B2", "B3"... "B15".

So when I removed the ExitLoop command first I tested it in a new Excel, BUT every time it wrote a new table, the last one was erased... I mean, it wrote the first table in "A1", but when it wrote the second table in "A2", "A1" was blank. It didn't "record" each new cell. ($iRow2Write2 = $oWorkBook.Activesheet.UsedRange.Rows.Count + 1 is for counting the last value in the column, but it dind't work either).

So I made a search in the forum, with no results. 

Then I tried to do it with the actual code, although the test didn't worked, and I only got ONE table, which is not the first one (is in the middle).

I couldn't find a solution to this, so I'm asking your help again.

 

This is what I want: a value that is in "A2", "A3"... "A15" in an Excel file, get all the tables in the new URL, take the last row of each table, and write them next to the value in the Excel, that is, in "B2", "B3"... "B15". But actually I need each table to be written in the same row of the value, so the value in "A2" should have the last row of the first table in "B2:F2", the second table in "G2:K2", and so on. Then the same with "A3", etc.

 

Thank you again! And sorry for the mess.

Share this post


Link to post
Share on other sites

#7 ·  Posted

As is, your code won't run (there is a Next without a matching For). $aTableData gets overwritten every time that you call _IETableWriteToArray. So you will need to move your code with that For...Next loop and perform the Excel actions for each table that is processed.

Share this post


Link to post
Share on other sites

#8 ·  Posted

16 hours ago, Danp2 said:

As is, your code won't run (there is a Next without a matching For). $aTableData gets overwritten every time that you call _IETableWriteToArray. So you will need to move your code with that For...Next loop and perform the Excel actions for each table that is processed.

The For is in the line 11, Next line 56. The other For line 43, Next line 48. What am I missing?

I don't understand the part of "perform the Excel actions for each table that is processed". Could you please rephrase it?

Share this post


Link to post
Share on other sites

#9 ·  Posted

Ok... I missed the initial for due to the lack of indention. Plus, why would you be logging in for each iteration of the outer loop?

You have a For...Next loop where you are processing the tables (output from _IETagNameGetCollection). Since the results of $aTableData gets overwritten on each pass through the loop, it would make sense to me to move your Excel activity to within this same loop so that you were operating on the array for the current table.

If I've misunderstood your needs, please restate them so that we can try to assist further.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now