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教えてくれ~記事少なすぎるんじゃ~
この記事が気に入ったらサポートをしてみませんか?