あぁ、フィルタよ、フィルタよ・・・
結構ややこしかったぞよ。
1つの列に対する複数条件の設定とか、フィルタ解除の方法やら、マクロの記録で出力されないロジックを調べるのに時間がかかった。
1) フィルタの解除
' フィルタが設定されていたら解除しちゃうよ
Private Sub ClearAutoFilter(target_ws as Worksheet)
If target_ws.AutoFilterMode Then target_ws.AutoFilterMode = False
End Sub
2) 1つの列に対する複数条件設定
これが結構難しかった。というより、参考になるサイトがあまりなく、やっとこさで探し当てた。
別のところで配列(Variant型)を作っとく。
たとえば、
Dim arr As Varient
arr = Split(“あ,い,う”)
として、
SetAutoFilterAt Activesheet.Range(“A1:E100”), 1, arr
ってな感じで下のプロシージャを呼び出す。
すると、「あ」「い」「う」に該当するレコードが抽出される。
Private Sub SetAutoFilterOn(target_rng as Range, col as Long, crit_arr as Variant)
target_rng.AutoFilter Field:=col , Criteria1:=crit_arr , Operator:=xlFilterValues
End Sub
試してないから、動かんかったらごめんなさい。
でも、イメージ的にはこんな感じで、Criteria1とOperator の設定がポイントということが分かった。
3) 絞り込んだデータの取得(A) 1行ずつ漁る
Dim cnt As Long
Dim rng As Range
Dim target_rng As Range
Set target_rng = Activesheet.Range("A1:E100")
'target_rngの1行目がタイトル行なので、-1 する。
With target_rng
cnt = .Columns(1).SpecialCells(xlCellTypeVisible).Cells.Count -1
If cnt > 0 Then
For Each rng In .Columns(1).SpecialCells(xlCellTypeVisible).Cells
'タイトル行以外で処理する
If rng.Row > 1 Then
'抽出範囲の1列目の情報をダイアログ表示
Msgbox rng.Parent.Cells(rng.row,1).Value
End If
Next
Else
Msgbox "データなし"
End If
End With
ForEach文が1行ずつ見ているところ。
抽出範囲の1列目ってのが、Columns(1).SpecialCells(xlCellTypeVisible).Cells。
4) 絞り込んだデータの取得(B) ワークシート関数でドバッと集計
Dim cnt As Long
Dim target_rng As Range
Set target_rng = Activesheet.Range("A1:E100")
'target_rngの1行目がタイトル行なので、-1 する。
With target_rng
cnt = .Columns(1).SpecialCells(xlCellTypeVisible).Cells.Count -1
If cnt > 0 Then
'抽出範囲の2列目の合計を取得(タイトル行は数値でないこと)
Msgbox "合計:" & Cstr(Application.WorksheetFunction.Sum(.Columns(2).SpecialCells(xlCellTypeVisible).Cells))
Else
Msgbox "データなし"
End If
End With
他の内容は割と簡単に調べられるので省略。
改めてExcelVBAって奥深いなぁ・・・って思った。
ってか、マクロの記録でこういうロジックを残してくれたら、悩まずに済むのに!といつも思う。