範囲内の文字列を配列化するFunction

範囲内の各セルの値(文字列)を配列化するFunction

範囲内の文字列の配列化

この間、

特定の文字列のみ狙い撃ちでゴシック体にする

みたいなくそめんどくさい作業に遭遇した。

もちろん、ちゃちゃっとコード書いて瞬殺したんですが、そのときに、

対象の文字なり文字列なりをワークシートに表で作っておいて、Functionで配列化できたら便利なんじゃね?

と思っただけです。

コーディング

次のようなFunctionを作った。

リスト1 標準モジュール
Public Function getValueArray(ByVal targetRange As Range) _
                                    As String()    '……(1)'
  Dim countOfCells As Integer
  countOfCells = targetRange.Count    '……(2)'
  Dim tmpArray() As String    '……(3)'
  ReDim tmpArray(countOfCells - 1)
  Dim n As Integer
  Dim targetCell As Range
  For Each targetCell In targetRange    '……(4)'
    tmpArray(n) = targetCell.Value
    n = n + 1
  Next
  getValueArray = tmpArray    '……(5)'
End Function

まず、(1)の

Public Function getValueArray(ByVal targetRange As Range) As String()

でFunctionの名前と引数、返り値の型を指定。

引数としてセル範囲を与えると、String型の配列を返すFunctionにしている。

(2)の

countOfCells = targetRange.Count

では、引数で渡されたRangeオブジェクト(targetRange)に含まれるセルの個数をCountプロパティを参照して獲得し、変数countOfCellsにぶち込んでいる。

(3)からの2行

Dim tmpArray() As String
ReDim tmpArray(countOfCells - 1)

では、String型の配列変数tmpArray()をとりあえず宣言しておき、すかさずReDim。配列の添え字の最大数は、要素数-1なので、「countOfCells - 1」になる。

(4)からの4行

For Each targetCell In targetRange
  tmpArray(n) = targetCell.Value
  n = n + 1
Next

では、「For Each ~ Next」を使って引数で渡された範囲の各セルを巡回し、それぞれの値を配列変数tmpArrayにぶち込んでいく。通常の「For ~ Next」と違って、ブロック内で n をインクリメントしておかないとアホな結果になるので注意。

あとは、(5)の

getValueArray = tmpArray

で配列tmpArrayを返り値としてreturnしてやればおk。

使ってみる

f:id:akashi_keirin:20180120094626j:plain

こんなふうに範囲を選択して、次のコードで使ってみる。

スト2 標準モジュール
Public Sub getValueArrayTest()
  Dim ar() As String
  ar = getValueArray(Selection)    '……(1)'
  Dim i As Integer
  For i = 0 To UBound(ar)    '……(2)'
    If ar(i) = "" Then ar(i) = "*"
    Debug.Print ar(i)
  Next
End Sub

(1)の

ar = getValueArray(Selection)

は、getValueArrayに引数として「Selection」(選択中のセル範囲)を渡し、返り値を配列変数 ar にぶち込む、という意味。配列用の変数名がなげやりですまんw

あとは、(2)からの4行

For i = 0 To UBound(ar)
  If ar(i) = "" Then ar(i) = "*"
  Debug.Print ar(i)
Next

では、Forループを使って配列 ar の各要素を取り出してイミディエイトに表示するようにしている。UBoundはこういうときに欠かせない組み込み関数ですな。

一応、配列の要素が「""」(長さ0の文字列)だったら代わりに「*」を表示するようにした。

実行結果

f:id:akashi_keirin:20180120094635j:plain

このように、「*」が表示されているところを見ると、「For Each ~ Next」では、結合されたセルも一つ一ついわゆる「Zオーダー」で巡回する仕様になっているようだ。

おわりに

使いどころ、他にあるかいな……。あと、Zオーダー以外の順番にも対応する必要があるかも知れん。でもそうなると、Dictionaryでやる方が便利かなあと思ったり。

@akashi_keirin on Twitter