「ダブルクリックしたときに「レ点」を入れる(イヴェント・マクロ)」で重複を防ぐマクロを作りました、でもダブルクリックせずとも直接「レ」を入力してしまうこともあるだろうと今度はそのチェックをするマクロも作りました。
Sub レ点チェック()
Dim Rng_1 As Range, Rng_2 As Range, Rng_3 As Range, Rng_4 As Range
Dim chk_1 As Long, chk_2 As Long, chk_3 As Long, chk_4 As Long, all_chk As Long
Dim c As Variant
Set Rng_1 = Union(Range("登録済"), Range("新規登録"))
Set Rng_2 = Range("着払い:IDEC元払い")
Set Rng_3 = Union(Range("必要"), Range("不要"))
Set Rng_4 = Union(Range("同封"), Range("貴社送り"))
all_chk = 0
chk_1 = 0
chk_2 = 0
chk_3 = 0
chk_4 = 0
For Each c In Rng_1
If c.Value = "レ" Then chk_1 = chk_1 + 1
Next
If chk_1 = 1 Then all_chk = all_chk + 1
For Each c In Rng_2
If c.Value = "レ" Then chk_2 = chk_2 + 1
Next
If chk_2 = 1 Then all_chk = all_chk + 1
For Each c In Rng_3
If c.Value = "レ" Then chk_3 = chk_3 + 1
Next
If chk_3 = 1 Then all_chk = all_chk + 1
For Each c In Rng_4
If c.Value = "レ" Then chk_4 = chk_4 + 1
Next
If chk_4 = 1 Then all_chk = all_chk + 1
If all_chk < 4 Then MsgBox "重複チェックまたはチェックされていません。"
If all_chk = 4 Then MsgBox "OK!"
End Sub
だけど実に冗長でみっともないのでもっときれいにならないかと先週末から考えてやっと出来たのがこれです。
Sub レ点チェック2()
Dim Rng(1 To 4) As Range
Dim chk(1 To 4) As Long
Dim c As Variant
Dim i As Long
Set Rng(1) = Union(Range("登録済"), Range("新規登録"))
Set Rng(2) = Range("着払い:IDEC元払い")
Set Rng(3) = Union(Range("必要"), Range("不要"))
Set Rng(4) = Union(Range("同封"), Range("貴社送り"))
all_chk = 0
For i = LBound(Rng) To UBound(Rng)
chk(i) = 0
For Each c In Rng(i)
If c.Value = "レ" Then
chk(i) = chk(i) + 1
all_chk = all_chk + 1
End If
Next c
Next i
If all_chk < 4 Then MsgBox "重複チェックまたはチェックされていません。"
If all_chk = 4 Then MsgBox "OK!"
End Sub
われながら実にスマートに出来たと自画自賛、ここでとても悩んだのは変数「chk」は変数「Rng」の数に等しいけど変数「Rng」の中身は必ずしも決まっていないこと、例えばRng1の内容が(A1,B1)Rng2の内容が(A3,B4,D5,E6)だったりした場合どのように処理をしたらよいか分からず初めのマクロのように範囲ごとに記述していたのです。
結果、変数の数が決まっている「Rng」には「For ...Next」を使いその入れ子として変数の数が不定のときに使える「For Each...Next」を使ったらうまく行きました。