第0回で配布しました汎用プロシージャのコードの紹介と簡単な解説をやっていきたいと思います!
以下のリンクから .bas ファイルをダウンロードできます(zipファイル)
今回ご紹介するプロシージャは
プロシージャ名 | 概要 |
---|---|
SpeedUp | 処理の高速化(画面更新停止など)を一括制御 |
SearchRow | 指定列から文字列検索(完全一致orあいまい) |
SearchCol | 指定行から文字列検索(完全一致orあいまい) |
前回は指定行または列の最終の番号を取得するというものでしたが、今回は指定行または列の指定した文字が何番目に存在するのかを取得するプロシージャになっております。さらに指定した文字列と完全一致だけでなく指定した文字列が含まれていれば、すなわちあいまい検索の機能も付けました。
では、SearchRow / SearchColのコードをまとめてご紹介します!
SearchRow
Function SearchRow(wordForSearch As String, colNumber As Long, searchMethod As Long, searchDirection As Long, Optional targetSheet As Worksheet) As Long
'------------------------------------------------------------------------------------------------------------------------------
' 概要 |任意のシートで、指定列にある検索対象文字列と一致する最初の行番号を取得
'------------------------------------------------------------------------------------------------------------------------------
' 引数1 |wordForSearch - 検索対象対象文字列(Srting型)
' 引数2 |colNumber - 対象の列番号(Long型)
' 引数3 |searchMethod - 検索方法(1:完全一致、2:あいまい検索)(Long型)
' 引数4 |searchDirection - 検索の方向(1:順方向、2:逆方向)(Long型)
' 引数5 |targetSheet - 対象のワークシートオブジェクト(規定値:ActiveSheet)(Worksheet型)
'------------------------------------------------------------------------------------------------------------------------------
' 戻り値 |Long型 - 検索対象の行番号(データが無い場合は0)
'------------------------------------------------------------------------------------------------------------------------------
' 実装 |Ver.1.0.0(2025/04/20:新規)
'------------------------------------------------------------------------------------------------------------------------------
Dim vLoop As Long '行ループカウンタ
If targetSheet Is Nothing Then Set targetSheet = ActiveSheet
'ユーザー定義エラー
If colNumber < 1 Then
Err.Raise vbObjectError + 1001, "SearchRow", "引数は1以上の整数にしてください"
End If
If searchMethod <> 1 And searchMethod <> 2 Then
Err.Raise vbObjectError + 1002, "SearchRow", "引数は1(完全一致)または2(あいまい検索)にしてください"
End If
If searchDirection <> 1 And searchDirection <> 2 Then
Err.Raise vbObjectError + 1003, "SearchRow", "引数は1(順方向)または2(逆方向)にしてください"
End If
'文字列の検索および行番号の取得
With targetSheet
If searchDirection = 1 Then
For vLoop = 1 To .Cells(.Rows.Count, colNumber).End(xlUp).Row
If searchMethod = 1 Then
If .Cells(vLoop, colNumber) = wordForSearch Then
SearchRow = vLoop
Exit Function
End If
ElseIf searchMethod = 2 Then
If .Cells(vLoop, colNumber) Like "*" & wordForSearch & "*" Then
SearchRow = vLoop
Exit Function
End If
End If
Next vLoop
ElseIf searchDirection = 2 Then
For vLoop = .Cells(.Rows.Count, colNumber).End(xlUp).Row To 1 Step -1
If searchMethod = 1 Then
If .Cells(vLoop, colNumber) = wordForSearch Then
SearchRow = vLoop
Exit Function
End If
ElseIf searchMethod = 2 Then
If .Cells(vLoop, colNumber) Like "*" & wordForSearch & "*" Then
SearchRow = vLoop
Exit Function
End If
End If
Next vLoop
End If
End With
End Function
SearchCol
Function SearchCol(wordForSearch As String, rowNumber As Long, searchMethod As Long, searchDirection As Long, Optional targetSheet As Worksheet) As Long
'------------------------------------------------------------------------------------------------------------------------------
' 概要 |任意のシートで、指定行にある検索対象文字列と一致する最初の列番号を取得
'------------------------------------------------------------------------------------------------------------------------------
' 引数1 |wordForSearch - 検索対象対象文字列(Srting型)
' 引数2 |rowNumber - 対象の行番号(Long型)
' 引数3 |searchMethod - 検索方法(1:完全一致、2:あいまい検索)(Long型)
' 引数4 |searchDirection - 検索の方向(1:順方向、2:逆方向)(Long型)
' 引数5 |targetSheet - 対象のワークシートオブジェクト(規定値:ActiveSheet)(Worksheet型)
'------------------------------------------------------------------------------------------------------------------------------
' 戻り値 |Long型 - 検索対象の列番号(データが無い場合は0)
'------------------------------------------------------------------------------------------------------------------------------
' 実装 |Ver.1.0.0(2025/04/20:新規)
'------------------------------------------------------------------------------------------------------------------------------
Dim hLoop As Long '列ループカウンタ
If targetSheet Is Nothing Then Set targetSheet = ActiveSheet
'ユーザー定義エラー
If rowNumber < 1 Then
Err.Raise vbObjectError + 1001, "SearchCol", "引数は1以上の整数にしてください"
End If
If searchMethod <> 1 And searchMethod <> 2 Then
Err.Raise vbObjectError + 1002, "SearchCol", "引数は1(完全一致)または2(あいまい検索)にしてください"
End If
If searchDirection <> 1 And searchDirection <> 2 Then
Err.Raise vbObjectError + 1003, "SearchCol", "引数は1(順方向)または2(逆方向)にしてください"
End If
'文字列の検索および列番号の取得
With targetSheet
If searchDirection = 1 Then
For hLoop = 1 To .Cells(rowNumber, .Columns.Count).End(xlToLeft).Column
If searchMethod = 1 Then
If .Cells(rowNumber, hLoop) = wordForSearch Then
SearchCol = hLoop
Exit Function
End If
ElseIf searchMethod = 2 Then
If .Cells(rowNumber, hLoop) Like "*" & wordForSearch & "*" Then
SearchCol = hLoop
Exit Function
End If
End If
Next hLoop
ElseIf searchDirection = 2 Then
For hLoop = .Cells(rowNumber, .Columns.Count).End(xlToLeft).Column To 1 Step -1
If searchMethod = 1 Then
If .Cells(rowNumber, hLoop) = wordForSearch Then
SearchCol = hLoop
Exit Function
End If
ElseIf searchMethod = 2 Then
If .Cells(rowNumber, hLoop) Like "*" & wordForSearch & "*" Then
SearchCol = hLoop
Exit Function
End If
End If
Next hLoop
End If
End With
End Function
本プロシージャは…使うことはあんまりないけどいざというときに大活躍する、そんなプロシージャになっています(笑)、主な活躍のフィールドはデータベース処理かなと考えています。
Excelをよく使う方向けに表現するならば、VLOOKUP、HLOOKUPの応用版だと捉えていただければと思います。
簡単ではありますが図を用いて使用例と動作の解説をしていきます。
動作解説
このようなシートがあったとしましょう。よくある社員のデータベース、もう少し一般的な言い方をするとリレーショナルデータベースですね。
このデータベースに対してSearchRow / SearchColを使ってみましょう!
Sub Main()
Dim a As Long
Dim b As Long
Dim c As Long
Dim d As Long
Dim e As Long
Dim f As Long
Dim g As Long
Dim h As Long
a = SearchRow("10001001", 1, 1, 1)
b = SearchRow("田中", 2, 1, 2)
c = SearchRow("1003", 6, 2, 1)
d = SearchRow("1000", 6, 1, 1)
e = SearchCol("名前", 1, 1, 1)
f = SearchCol("東京", 4, 1, 1)
g = SearchCol("東京", 7, 1, 1)
h = SearchCol("経理", 9, 2, 1)
Debug.Print "a = " & a
Debug.Print "b = " & b
Debug.Print "c = " & c
Debug.Print "d = " & d
Debug.Print "e = " & e
Debug.Print "f = " & f
Debug.Print "g = " & g
Debug.Print "h = " & h
End Sub
すべてSheet1(=アクティブなシート)内の検査であるため、第5引数は省略しております。そして実行結果が以下のようになります。
a~hまでの変数ごと見ていきますと
・a:"10001001"は1列目の2行目にあるので戻り値は2
・b:"田中"さんは2列目の最終行から検索すると最初に7行目でヒットするので戻り値は7
※最初に一致したときの値のみを返します
・c:"1003"を含む文字列は6列目の4行目にあるので戻り値は4
・d:"1000"を含む文字列が6列目に存在しないため戻り値は0
・e:"名前"は1行目の2列目にあるので戻り値は2
・f:"東京"は4行目の5列目にあるので戻り値は5
・g:"東京"は7行目に存在しないので戻り値は0
・h:"経理"を含む文字列は9行目の3列目に存在するので戻り値は3
といった動作になります。恐らくこの中で一番よく使われるパターンはeになりますね。例えば大量のExcelファイル(=リレーショナルデータベース)から何らかの情報を取り出したいときに欲しい情報の列番号を検索するという使い方になります。抽出対処のExcelファイルたちのフォーマットが同じであれば必要ありませんが違う場合もそれなりにあるかと思いますのでそのような場面に遭遇した際は使ってみてください!
またbのような最終行または最終列から検索をかける必要があるパターンもたまにありますので抽出したいExcelファイルの中身がどのようになっているのかを一度ざっくりでもよいので把握したうえで必要な処理を選んであげると業務自動化へ大きく前進できます!
直感!VBAシリーズ記事一覧
もしよろしければ他の記事もご覧ください!