SeleniumBasicVBAでテーブルの結合を崩さずに配列として取り出す

tableタグにcolspanとrowspanが設定されているとエクセルへ出力した際に表が崩れてしまう。

何とかそのまま取り出したい

調べてもなかったのでつくった。
どうしても表を崩したくない人向け。

' // tableの結合を崩さずに配列として取り出す //
Function AsTable(eleTableTag As Object) As Variant()
  Dim domTableTag As Object: Set domTableTag = SelenToDOM(eleTableTag)
  Dim table As Object: Set table = domTableTag.getElementsByTagName("table")(0)
  Dim data As Variant: data = ImportHTMLTable(table)
  AsTable = data
End Function

' // SelenElementをHTMLDocument化しDOM操作に対応させる //
' // ⇒スクレイピングが高速化する //
Function SelenToDOM(SelenElement As Object) As Object
  Set SelenToDOM = ToDOM(SelenElement.Attribute("outerHTML"))
End Function

' // DOMText(outerHTML)をHTMLDocument化しDOM操作に対応させる //
' // ⇒スクレイピングが高速化する //
Private Function ToDOM(DOMText As String) As Object
  Dim DOMElement As Object: Set DOMElement = CreateObject("htmlfile")
  DOMElement.Write DOMText
Set ToDOM = DOMElement
End Function

' // DOMText(outerHTML)をHTMLDocument化したTableをDom操作にて配列を取り出す //
Private Function ImportHTMLTable(table As Object) As Variant
  Dim row As Object, cell As Object
  Dim n As Long: n = 0
  'ヘッダーの列数をnへ格納
  For Each cell In table.Rows(0).Cells
    If cell.colSpan > 1 Then
      n = n + cell.colSpan
    Else
      n = n + 1
    End If
  Next cell
  'tableデータの縦列の総数とヘッダーの総数で配列を定義
  Dim ArrList As Variant: ReDim ArrList(1 To table.Rows.Length + 1, 1 To n + 1)
  '縦への処理
  Dim rowNum As Integer: rowNum = 1
  For Each row In table.Rows
    '横への処理
    Dim colNum As Integer: colNum = 1
    For Each cell In row.Cells
      Do
        If colNum >= UBound(ArrList, 2) Then Exit For
        If ArrList(rowNum, colNum) = "" Then Exit Do
        colNum = colNum + 1
      Loop
      '<td>の結合プロパティが1以上で処理を切り分け
      If cell.rowSpan > 1 Or cell.colSpan > 1 Then
        '縦
        For y = 0 To cell.rowSpan - 1
          '横
          For x = 0 To cell.colSpan - 1
            '配列へ値を格納
            ArrList(rowNum + y, colNum + x) = cell.innerText
            '後に配列の値の有無で処理を分けるので空の場合”-”を格納
            If ArrList(rowNum + y, colNum + x) = "" Then ArrList(rowNum + y, colNum + x) = "-"
          Next x
        Next y
        '既に値が格納されている場合の処理
        Else
          ArrList(rowNum, colNum) = cell.innerText
        End If
        colNum = colNum + 1
      Next cell
      rowNum = rowNum + 1
  Next row
  
  ImportHTMLTable = ArrList
End Function

基本 AsTable(eletabletag) で使える。
eletabletagにはテーブルのWebelementを代入、進捗表示に何か文字を代入しておくとステータスバーへメッセージとして進捗が表示される。

自分用の備忘録なので詳しい説明は無しで・・・
あともうちょい洗練したいです。
だれかSeleniumVBA教えてくれ~記事少なすぎるんじゃ~

この記事が気に入ったらサポートをしてみませんか?