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以降だと少し保存形式が変わるらしいので、このあたり改善されているかも?