プロが教える店舗&オフィスのセキュリティ対策術

すみませんがご教示いただければ幸いです。
セル範囲を選択させ、情報を得てから作業するのですが、コードにたくさんSelection(すべて同じ選択範囲)が出てくるのでWith~End Withでまとめようと思いました。
ところが、まとめてもSelectionという表記を省略できたのはほんのわずかです。
ご覧の通り、TypeName(Selection) をはじめIntersect(Selection(1), 等々省略できないのがほとんどです。
Set myRng=Selection でやったとしても、SelectionがmyRngに変わるだけでぜんぜん省略にならないですよね?
こんな場合は何か別の省略した書き方があるのでしょうか?

Sub test()
With Selection
If TypeName(Selection) <> "Range" Then 'セル以外をセレクトしてたら
MsgBox "セル範囲を選択してください。", vbCritical, " Σ( ̄ロ ̄lll)"
Exit Sub
End If
If Intersect(Selection(1), Range("D4:AY65")) Is Nothing _
Or Intersect(Selection(.Count), Range("D4:AY65")) Is Nothing Then '指定のセル範囲をはみ出てたら
ans = MsgBox("はみ出してますがいいんですか?", vbYesNo + vbQuestion, " ( ̄□ ̄; ? ")
If ans = vbNo Then
Exit Sub
End If
End If
For Each Ln In ActiveSheet.Lines '配置された各直線につき
If Not Intersect(Range(Ln.TopLeftCell, Ln.BottomRightCell.Offset(0, -1)), Selection) Is Nothing Then '選択範囲とかぶってたら
MsgBox "重複してます!", vbCritical, " ( ̄□ ̄;)!! "
Exit Sub
End If
Next
End With
'以下、無関係なので略します。
End Sub

A 回答 (4件)

こんばんは。



結論からすると、With Selection ~ End With の必要性は、あまり出てきませんね。
Selection というスタイル自体が特殊ですから、まとめても不恰好になってしまいます。

With Selection というのは、Excel では、あまり品番に出てこないように思います。
こういう書法の原則というのは、文字数を減らすということなのだと私は解釈しています。だから、一応、以下は、その目的自体は達成はしているように思います。

TypeName の部分は除いて、「はみ出してます」に関してのみ、少し考えてみました。まずは、参考まで。


Sub TestSample1()
  Dim r As Range
  Set r = Range("D4:AY65")
  ''--TypeName は省略--
  With Selection
    If .Areas.Count > 1 Then
       MsgBox "複数の範囲を選択しています。ひとつにしてください。"
       Exit Sub
    End If
    If Not Intersect(.Cells, r) Is Nothing Then
      If (.Cells(1).Row >= r(1).Row And .Cells(.Cells.Count).Row <= r.Cells(r.Count).Row) And _
        (.Cells(1).Column >= r(1).Column And .Cells(.Cells.Count).Column <= r.Cells(r.Count).Column) Then
        MsgBox "範囲内に入っています。"
      Else
        MsgBox "範囲からはみ出ています。"
      End If
    Else
      MsgBox "範囲外です。"
    End If
  End With
End Sub
    • good
    • 0
この回答へのお礼

> 結論からすると、With Selection ~ End With の必要性は、あまり出てきませんね。

おっしゃる通りですね。
いつもありがとうございます。

お礼日時:2009/05/12 14:15

If Intersect(Selection(1), Range("D4:AY65")) Is Nothing _


Or Intersect(Selection(.Count), Range("D4:AY65")) Is Nothing Then
↑は、

If Intersect(Selection, Range("D4:AY65")).Address <> Selection.Address Then
で、良いかも。
    • good
    • 0
この回答へのお礼

NNAQさま、ありがとうございます。

If Intersect(Selection, Range("D4:G50")).Address <> Selection.Address Then

これはいいですね!
さっそく利用させていただきます。

お礼日時:2009/05/13 15:18

コードの最初から最後までの処理を考えたとき、特に繰り返しルーチン(ブロック)でSelectionの範囲が変わらないなら


Set myRng=右辺の右辺を変数を含んで表し myRngを徹底して使うように出来るのでは無いですか。
http://www.officepro.jp/excelvba/cell_select/ind …
いろいろ繰り返しブロックの中でも範囲が変わるようだと、難しいですが、エクセルは座標的なセルが有るからそれで表せる場合が多い。ワードのVBAではSelectionが多いように思うが、ユーザーが選択した箇所をワードでは、エクセルのセル番地のようには表せないからだと思う。
エクセルのマクロのSelrction多用はその操作(行で)とりあえずコードを締めくくるためで、エクセルにおいて、Selectionの多用の必要理由にはならない。むしろ初心者が、マクロの記録の色に染まり、Selectionを多用している場合が、質問でも多い。本質問はそういうことの反省かとも思うが、余り神経質になって、間違ったり、コードが長くなったり、わかりにくくなるのも問題と思う。
本件のように操作者が行動した後から、コード処理を始める場合は
本質問ぐらいの使用はやむをえないのでは。
    • good
    • 0
この回答へのお礼

ありがとうございます。
勉強になりました。

お礼日時:2009/05/12 14:13

私もWithでまとめるのは好きですが、ケースバイケースで考えたほうが良いのでは。


最初のTypeName判定は仕方ないですね。それによって以降のコードを分岐させるわけですから。
現在のコードのままムリヤリまとめるなら

With Selection
  If Intersect(.Item(1), Range("D4:AY65")) Is Nothing _
    Or Intersect(.Item(.Count), Range("D4:AY65")) Is Nothing Then

    If Not Intersect(Range(Ln.TopLeftCell, Ln.BottomRightCell.Offset(0, -1)), .Cells) Is Nothing Then

と、できなくもないでしょうけど
#そもそもObjectへのアクセスをまとめるためのWithなので、
#http://www.officetanaka.net/excel/vba/speed/s4.htm
#逆にプロパティの呼び出しが増えてしまうような気がしないでもないです。
#プロではないのでこの辺りあやふやです、すみません。

あとは余談ですが、ハミ出し判定で、隔選択を考慮する場合、Range.Countで判定するのもありかも。

Dim r  As Range
Dim chk As Range

If TypeName(Selection) <> "Range" Then
  MsgBox "!"
  Exit Sub
End If
Set r = Selection
'同一セルをCtrlで複数選択した場合を考慮してみたりして
'Set r = Union(r, r)
Set chk = Intersect(r, Range("D4:AY65"))
If chk Is Nothing Then
  MsgBox "!!"
Else
  If chk.Count <> r.Count Then
    MsgBox "!!!"
  End If
End If

Set chk = Nothing
Set r = Nothing
    • good
    • 0
この回答へのお礼

ありがとうございます。
とても参考になりました。

お礼日時:2009/05/12 14:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!