tableauという分析ツールがある。接続先が豊富で、通常のデータベース以外にもDropboxにあるファイル、BigQuery等にも接続が可能である。
保存されるファイルの拡張子が.twbであるが、XML形式である。
tableauのユーザーなら分かるだろうけれど、使っていないデータソースができてくることがあり、そういうの調べたいという話があったので、Excel VBA で作成してみた。(ブログ掲載用に少しいじった/挙動には問題ないはず)
参考にしたのは手前味噌だが以下のサイト。
https://ameblo.jp/tech-note/entry-10322208874.html
Option Explicit
Type TYPE_DataSource
DsName As String
isRef As Boolean
End Type
Type TYPE_WorkseetSource
WsName As String
DsName As String
End Type
Sub main_ctrl()
Call ReadXML_DataSourceName("[tableauのtwbファイルをフルパスで]")
End Sub
Sub ReadXML_DataSourceName(psFile As String)
Dim XDoc As MSXML2.DOMDocument60
Dim DsNode As MSXML2.IXMLDOMNode
Dim WsNode As MSXML2.IXMLDOMNode
Dim typDs() As TYPE_DataSource
Dim typWs() As TYPE_WorkseetSource
Dim nDsCnt As Integer
Dim nWsCnt As Integer
Dim ix As Integer
Dim iy As Integer
Dim sWsNodeName As String
nDsCnt = 0
nWsCnt = 0
Set XDoc = New MSXML2.DOMDocument60
' XDoc.async = True '■エラー発生時に調べて追加/今回は効果なし
' XDoc.resolveExternals = False '■エラー発生時に調べて追加/今回は効果なし
' XDoc.validateOnParse = False '■エラー発生時に調べて追加/今回は効果なし
If XDoc.Load("" & psFile) = False Then
' 読み込み失敗時
With XDoc.parseError
Debug.Print " **** Error **** "
Debug.Print " File/URL :" & .URL '■ファイル名
Debug.Print " Code : " & .ErrorCode '■エラーコード
Debug.Print " Msg : " & Replace(.reason, vbCrLf, "") '■エラー理由(改行を取り除く)
Debug.Print " Line : " & .Line '■発生行
Debug.Print " Col : " & .linepos '■発生行のカラム位置
Debug.Print " Pos : " & .filepos '■ファイル内のカラム位置
' Debug.Print " Text : " & .srcText '■発生行の内容
End With
Exit Sub
End If
'DS
For Each DsNode In XDoc.SelectNodes("/workbook/datasources/datasource/@caption")
nDsCnt = nDsCnt + 1
ReDim Preserve typDs(nDsCnt)
typDs(nDsCnt).DsName = DsNode.Text
typDs(nDsCnt).isRef = False
Next
'WS
For Each WsNode In XDoc.SelectNodes("/workbook/worksheets/worksheet/@name")
sWsNodeName = Replace(WsNode.Text, "'", "’") '■WsNode.Text に半角アポストロフィがあった場合、後続でエラーになるので全角化しておく(スラッシュは未確認)
For Each DsNode In XDoc.SelectNodes("/workbook/worksheets/worksheet[@name='" & sWsNodeName & "']/table//datasources/datasource/@caption")
nWsCnt = nWsCnt + 1
ReDim Preserve typWs(nWsCnt)
typWs(nWsCnt).WsName = sWsNodeName
typWs(nWsCnt).DsName = DsNode.Text
Next
Next
'DS - WS
For ix = 1 To nDsCnt
For iy = 1 To nWsCnt
If typDs(ix).DsName = typWs(iy).DsName Then
typDs(ix).isRef = True
End If
Next iy
Next ix
'Debug.print
Debug.Print "-------------------------------------------"
Debug.Print "File Name :" & psFile
Debug.Print "--- Worksheet in Dataset ------------------"
For ix = 1 To nWsCnt
Debug.Print " " & typWs(ix).WsName, typWs(ix).DsName
Next ix
Debug.Print "--- No use Dataset ------------------------"
For ix = 1 To nDsCnt
If typDs(ix).isRef = False Then
Debug.Print " " & typDs(ix).DsName
End If
Next ix
Set XDoc = Nothing
End Sub
コード内のコメントにあるの■の部分が注意点である。
で、こいつで読み込むと、1ファイルだけエラーが出るものがあった。
.ErrorCode : -2147467259
.reason : エラーを特定できません
.linepos : 1051993
googleでの検索でも引っかからないようなのでファイルをいろいろ変更してみて確認したところ、どうやら「1タグの文字列が長すぎる」らしい。
やたらとアトリビュートを抱えているタグがあって、どうもMSXMLのパーサーは1タグ1051993までか、そのひとつ小さい値か、くらいまでしか読めない模様。まあ、1つのタグが105万文字超えるようなものがあるって、通常考えないだろう。
今回の解析では要らない部分だったので減らして実行したら問題なく実行できた。
ちなみに tableauのバージョンは10.3。10.4以降だと少し保存形式が変わるらしいので、このあたり改善されているかも?