VBAはたいして知りませんが…
「そんなバカな」と思って、試してみたらご質問の通りですね。
どうやら、Rangeは矩形の範囲を最低単位として(Areas)構成しているみたいで、同じセルを「ctl」+「左クリック」した場合、その回数だけAreaができていくのでダブってカウントされるようです。
うっかり For Each などで処理をすると、処理の内容によってはご質問のようなことになるみたい。
(どうせ、MSさんの『仕様』なんでしょうけれど… 普通はこんな動作期待しませんよね。)
解決法を2つ考えてみました。
1)自分で重複をチェックして範囲を作り直す (←ご質問文にすでにありますが)
一旦、For Eachでハッシュなどにセルを吐き出すことで、重複を除くことができる
ので、改めて、そのハッシュを元にループ処理を行なう方法。
<処理のイメージ>
Set d = CreateObject("Scripting.Dictionary")
For Each c In Selection
d(c.Address) = 1
Next c
counter = d.count
key = d.keys
For i = 0 To counter - 1
' 目的の処理
Next i
2)対象範囲が限定できているのなら、その範囲内で舐めてゆく
操作の対象があらかじめわかっていればその範囲で、そうでなければUsedRange
などを利用して、その範囲内のセルについてループを廻す。(For EachでもOK)
セルが、セレクション内だったら処理、そうでなければスキップ という方法。
<処理のイメージ>
counter = 0
For Each c In ActiveSheet.UsedRange
If Not (Intersect(c, Selection) Is Nothing) Then
' 目的の処理
coounter = counter + 1
End If
Next c
2)ではあらかじめセル数を知ることはできませんが、「1回ずつの処理」は可能ですし、ループ時にカウントすればセル数も求められます。
ただし、選択される可能性のある範囲に対して、大きすぎる範囲で走査するようだと効率が悪くなりかねません。
1)は一旦ハッシュに置き換えるので、ご質問文の『記憶させる方法』に該当しますが、多分、効率は良さそう。
2)は記憶はしないものの、範囲を広くしているために場合によっては効率が悪くなる可能性があるといったところでしょうか。
お礼
やはりそうなのですね、覚えておきます。 どうもありがとうございました!