+ Reply to Thread
Results 1 to 9 of 9

Reading HTML OL as a variant array

Hybrid View

  1. #1
    Valued Forum Contributor
    Join Date
    08-29-2012
    Location
    In lockdown
    MS-Off Ver
    Excel 2010 (2003 to 2016 but 2010 for choice)
    Posts
    1,766

    Reading HTML OL as a variant array

    I have this Ordered List (OL) element read and set to an object variable in a VBA function I'm working on

    I'm trying to work out some way I can read all rows/columns to a 2D array. Is this doable?

    Also; Would it be possible to make this generic enough so it could be reusable for any OL element or is that wishful thinking? (I never learnt HTML so don't laugh :S )
    Last edited by mc84excel; 05-28-2015 at 11:07 PM. Reason: Updated to specify array to be 2D
    *******************************************************

    HELP WANTED! (Links to Forum threads)
    Trying to create reusable code for Custom Events at Workbook (not Application) level

    *******************************************************

  2. #2
    Forum Moderator Leith Ross's Avatar
    Join Date
    01-15-2005
    Location
    San Francisco, Ca
    MS-Off Ver
    2000, 2003, & 2010
    Posts
    23,259

    Re: Reading HTML OL as a variant array

    Hello mc84excel,

    It would help if you posted the HTML code you want to parse.
    Sincerely,
    Leith Ross

    Remember To Do the Following....

    1. Use code tags. Place [CODE] before the first line of code and [/CODE] after the last line of code.
    2. Thank those who have helped you by clicking the Star below the post.
    3. Please mark your post [SOLVED] if it has been answered satisfactorily.


    Old Scottish Proverb...
    Luathaid gu deanamh maille! (Rushing causes delays!)

  3. #3
    Valued Forum Contributor
    Join Date
    08-29-2012
    Location
    In lockdown
    MS-Off Ver
    Excel 2010 (2003 to 2016 but 2010 for choice)
    Posts
    1,766

    Re: Reading HTML OL as a variant array

    Thanks Leith Ross but the most pressing need I have for this contains too much confidential data to easily remove. Also I am after a function that is reusable for any OL element

  4. #4
    Forum Guru Kyle123's Avatar
    Join Date
    03-10-2010
    Location
    Leeds
    MS-Off Ver
    365 Win 11
    Posts
    7,239

    Re: Reading HTML OL as a variant array

    Like this:
    Dim ol      As HTMLListElement
    Dim li      As HTMLLIElement
    Dim x       As Long
    Dim data()  As String
    
    With New HTMLDocument
    
        .body.innerHTML = "<ol id='OrderedList'><li>Point1</li><li>Point2</li></ol>"
        
        Set ol = .getElementById("OrderedList")
        ReDim data(1 To ol.Children.Length)
        
        For Each li In ol.Children
            x = x + 1
            data(x) = li.innerText
        Next li
    
    End With

  5. #5
    Valued Forum Contributor
    Join Date
    08-29-2012
    Location
    In lockdown
    MS-Off Ver
    Excel 2010 (2003 to 2016 but 2010 for choice)
    Posts
    1,766

    Re: Reading HTML OL as a variant array

    Sorry Kyle, my mistake. I have stuffed up again.

    Firstly thank you for the code provided +1 for that

    My problem is that I forgot to specify in the opening post that I was looking to return a 2D array!

    Dont worry about it. I am tinkering away on this and in a day or so I will know if there is any chance of success (or not)

  6. #6
    Forum Guru Norie's Avatar
    Join Date
    02-02-2005
    Location
    Stirling, Scotland
    MS-Off Ver
    Microsoft Office 365
    Posts
    19,645

    Re: Reading HTML OL as a variant array

    Why a 2D array?

    What would be in the second dimension?
    If posting code please use code tags, see here.

  7. #7
    Valued Forum Contributor
    Join Date
    08-29-2012
    Location
    In lockdown
    MS-Off Ver
    Excel 2010 (2003 to 2016 but 2010 for choice)
    Posts
    1,766

    Re: Reading HTML OL as a variant array

    Quote Originally Posted by Norie View Post
    Why a 2D array?

    What would be in the second dimension?
    Columns.

    For example The OL I am most interested in is an online contacts directory. Each page is an OL element. Each contact is a new LI element in that OL. And there are phone/email etc details inside each of these LI elements.

  8. #8
    Forum Guru Kyle123's Avatar
    Join Date
    03-10-2010
    Location
    Leeds
    MS-Off Ver
    365 Win 11
    Posts
    7,239

    Re: Reading HTML OL as a variant array

    Then you're going to need to post some markup

  9. #9
    Valued Forum Contributor
    Join Date
    08-29-2012
    Location
    In lockdown
    MS-Off Ver
    Excel 2010 (2003 to 2016 but 2010 for choice)
    Posts
    1,766

    Re: Reading HTML OL as a variant array

    I solved it.

    Each item I wanted to pick up is a span element of the li element. So I set an object to hold all the span elements of the li element and then loop through those, recording the innertext value (if exists) & recording the span classname as the field/header name.

    Some of the span elements are nested. So I added an optional argument 'blnOnlyReturnBaseData' to only record the field & value if the span element length was 0.

    extract below
    ...rest of function
    
        'get collection of LI in OL element
        Set objCollectionLI = objCollectionLI.getElementsByTagName("li")
        If objCollectionLI Is Nothing Then
            GoTo ExitProcedure
        End If
        On Error GoTo 0
    
        alngRow = objCollectionLI.Length
        alngHeaders = 1
        ReDim avarOutput(1 To alngRow, 1 To alngHeaders)
        ReDim avarHeaders(1 To alngHeaders)
    
        'loop through each LI & populate array
        For alngRow = LBound(avarOutput, 1) To UBound(avarOutput, 1)
    
            'grab collection of child objects for row (LI)
            Set objCollectionSPAN = objCollectionLI(alngRow - 1).getElementsByTagName("span")
    
            If Not blnOnlyReturnBaseData Then
                'expand arrays for any extra columns
                alngHeaders = UBound(avarHeaders)
                alngColSPAN = objCollectionSPAN.Length
                If alngColSPAN > alngHeaders Then
                    alngHeaders = alngColSPAN
                    ReDim Preserve avarOutput(LBound(avarOutput, 1) To UBound(avarOutput, 1), 1 To alngHeaders)
                    ReDim Preserve avarHeaders(1 To alngHeaders)
                End If
            End If
    
            'loop through columns - headers
            For alngColSPAN = 1 To objCollectionSPAN.Length
    
                If Not blnOnlyReturnBaseData Then
                    'populate is default
                    blnPopulateHeader = True
                    blnAlreadyMatched = False
                Else
                    blnPopulateHeader = (objCollectionSPAN(alngColSPAN - 1).all.Length = 0)
                    blnAlreadyMatched = False
                End If
    
                If blnPopulateHeader Then
                    'check for match #1 (same col)
                    If Not alngColSPAN > UBound(avarHeaders) Then
                        If avarHeaders(alngColSPAN) = objCollectionSPAN(alngColSPAN - 1).Classname Then
                            'already matched
                            'so dont populate
                            blnAlreadyMatched = True
                            blnPopulateHeader = False
                        End If
                    End If
    
                    'check for match #2 (other cols)
                    If Not blnAlreadyMatched Then
                        If fnlngGetPositionOfArgIn1dArr(avarHeaders, objCollectionSPAN(alngColSPAN - 1).Classname) > 0 Then
                            'match found in another col
                            'so dont populate
                            blnAlreadyMatched = True
                            blnPopulateHeader = False
                        End If
                    End If
    
                    'populate + no match found
                    If Not blnAlreadyMatched Then
                        'set alngHeaders
                        If Not alngColSPAN > UBound(avarHeaders) Then
                            alngHeaders = alngColSPAN
                            If Len(avarHeaders(alngHeaders)) > 0 Then
                                alngHeaders = UBound(avarHeaders)
                            End If
                        Else
                            alngHeaders = UBound(avarHeaders)
                        End If
    
                        'if field in header arr already in use, expand arrs by 1
                        If Len(avarHeaders(alngHeaders)) > 0 Then
                            alngHeaders = UBound(avarHeaders) + 1
                            ReDim Preserve avarOutput(LBound(avarOutput, 1) To UBound(avarOutput, 1), 1 To alngHeaders)
                            ReDim Preserve avarHeaders(1 To alngHeaders)
                        End If
    
                        'add new field to header arr (this element always empty due to fix above)
                        avarHeaders(alngHeaders) = objCollectionSPAN(alngColSPAN - 1).Classname
                    End If
                End If
    
            Next alngColSPAN
    
    
            'loop through columns - data
            For alngColSPAN = 1 To objCollectionSPAN.Length
    
                If Not blnOnlyReturnBaseData Then
                    'populate is default
                    blnPopulateHeader = True
                Else
                    blnPopulateHeader = (objCollectionSPAN(alngColSPAN - 1).all.Length = 0)
                End If
    
                If blnPopulateHeader Then
    
                    If alngColSPAN > UBound(avarHeaders) Then
                        'this to avoid err 9 on next
                        alngHeaders = UBound(avarHeaders)
                    Else
                        alngHeaders = alngColSPAN
                    End If
    
                    'locate position and use to set alngHeaders
                    If objCollectionSPAN(alngColSPAN - 1).Classname = avarHeaders(alngHeaders) Then
                        'matched, so use SPAN col
                        alngHeaders = alngColSPAN
                    Else
                        'locate col to use in header arr
                        alngHeaders = fnlngGetPositionOfArgIn1dArr(avarHeaders, objCollectionSPAN(alngColSPAN - 1).Classname)
                    End If
    
                    'copy innertext to arr
                    On Error Resume Next
                    If Len(objCollectionSPAN(alngColSPAN - 1).innertext) > 0 Then
                        avarOutput(alngRow, alngHeaders) = objCollectionSPAN(alngColSPAN - 1).innertext
                    End If
                    On Error GoTo 0
                End If
    
            Next alngColSPAN
    
    
            'scrap object
            If Not TypeName(objCollectionSPAN) = "Nothing" Then
                Set objCollectionSPAN = Nothing
            End If
        Next alngRow
    
    
        If IsArray(avarOutput) Then
            ReDim avarJagged(1 To 2)
            avarJagged(1) = avarOutput
            avarJagged(2) = avarHeaders
        End If
    
    ...rest of function

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. [SOLVED] Reading out Variant Array to an inactive worksheet
    By TheRobsterUK in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 01-11-2015, 08:19 PM
  2. Does setting a variant acting as an array equal to "" accomplish same as "Erase" variant?
    By dmasters4919 in forum Excel Programming / VBA / Macros
    Replies: 1
    Last Post: 11-21-2014, 05:59 PM
  3. Array problem: Key words-Variant Array, single-element, type mismatch error
    By davidm in forum Excel Programming / VBA / Macros
    Replies: 6
    Last Post: 11-09-2005, 01:54 AM
  4. Array problem: Key words-Variant Array, single-element, type mismatch error
    By davidm in forum Excel Programming / VBA / Macros
    Replies: 1
    Last Post: 11-08-2005, 12:30 AM
  5. ReDim Object array as parameter of Variant array
    By Peter T in forum Excel Programming / VBA / Macros
    Replies: 4
    Last Post: 05-10-2005, 10:06 AM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1