はじめに
Excel内で階層構造を表現したパラメータを連結して表現したいことがある。
…あるかな?
あった。
あったので記事に残しておく。
一例
例えば「日本の関東地方の東京都の江東区」の様に階層構造(親子関係)を持つパラメータを以下のように表現することが出来る。
日本
┗関東地方
┗東京都
┗江東区
それをExcelでインデントを空のセルで表し以下のように表現できる。
資料として参照するには見やすい場合もあるが、データとして読み込むには些か不便な形式といえる。
(これをなんと表現するのかが難しい…。方眼紙?)
その階層構造を以下の様に変換したい。
日本.関東地方.東京都.江東区
読み込みの具体例
画像の一番右の様に変換したい。
ソース
Typeの定義:保持したいデータ構造を定義する。
連結したパラメータはfullの方に、連結前の1セルのパラメータはfullでない方に。
Type データ定義
param_full As String
param As String
End Type
関数「main」:ボタン等から呼び出させる主関数
Public Sub main(path As String)
Dim wb As Workbook
Set wb = Workbooks.Open(path)
Call read(wb)
End Sub
関数「read」:セル範囲を上から順に読み込む
Private Sub read(wb As Workbook)
With wb.Sheets("対象のシート名")
Dim r As Range
Set r = Range("C4:E42") '読み取り範囲
End With
Dim data() As データ定義
ReDim data(r.Rows.Count - 1) As データ定義
Dim 階層1 As String, 階層2 As String, 階層3 As String
For i = 1 To r.Rows.Count
'パラメータがどのセルに入ってるかで処理を変える
If r(i, 1) <> "" Then
data(i - 1).param = r(i, 1).Value
階層1 = r(i, 1).Value
階層2 = ""
階層3 = ""
ElseIf r(i, 2) <> "" Then
data(i - 1).param = r(i, 2).Value
階層2 = r(i, 2).Value
階層3 = ""
ElseIf r(i, 3) <> "" Then
data(i - 1).param = r(i, 3).Value
階層3 = r(i, 3).Value
ElseIf r(i, 4) <> "" Then
'data(i).param = r(i, 4).Value
Else
End If
data(i - 1).param_full = 連結(階層1, 階層2, 階層3)
Next
End Sub
関数「連結」:複数の引数をもとに連結した文字列を返却する
Private Function 連結(p1 As String, p2 As String, p3 As String) As String
Dim 連結用リスト() As String
ReDim 連結用リスト(0)
連結用リスト(0) = p1
If p2 <> "" Then
ReDim Preserve 連結用リスト(1)
連結用リスト(1) = p2
If p3 <> "" Then
ReDim Preserve 連結用リスト(2)
連結用リスト(2) = p3
End If
End If
連結 = Join(連結用リスト, ".")
End Function
最初は&で連結しようと思ったが、性能がより良さそうときいたJoinで実装
最後に
自分の適当に作ったソースを見せるのは恥ずかしい