- ベストアンサー
ExcelVBA With~End With構文でまとめられない??
すみませんがご教示いただければ幸いです。 セル範囲を選択させ、情報を得てから作業するのですが、コードにたくさん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
- みんなの回答 (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
その他の回答 (3)
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 で、良いかも。
お礼
NNAQさま、ありがとうございます。 If Intersect(Selection, Range("D4:G50")).Address <> Selection.Address Then これはいいですね! さっそく利用させていただきます。
- imogasi
- ベストアンサー率27% (4737/17069)
コードの最初から最後までの処理を考えたとき、特に繰り返しルーチン(ブロック)でSelectionの範囲が変わらないなら Set myRng=右辺の右辺を変数を含んで表し myRngを徹底して使うように出来るのでは無いですか。 http://www.officepro.jp/excelvba/cell_select/index2.html いろいろ繰り返しブロックの中でも範囲が変わるようだと、難しいですが、エクセルは座標的なセルが有るからそれで表せる場合が多い。ワードのVBAではSelectionが多いように思うが、ユーザーが選択した箇所をワードでは、エクセルのセル番地のようには表せないからだと思う。 エクセルのマクロのSelrction多用はその操作(行で)とりあえずコードを締めくくるためで、エクセルにおいて、Selectionの多用の必要理由にはならない。むしろ初心者が、マクロの記録の色に染まり、Selectionを多用している場合が、質問でも多い。本質問はそういうことの反省かとも思うが、余り神経質になって、間違ったり、コードが長くなったり、わかりにくくなるのも問題と思う。 本件のように操作者が行動した後から、コード処理を始める場合は 本質問ぐらいの使用はやむをえないのでは。
お礼
ありがとうございます。 勉強になりました。
- end-u
- ベストアンサー率79% (496/625)
私も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
お礼
ありがとうございます。 とても参考になりました。
お礼
> 結論からすると、With Selection ~ End With の必要性は、あまり出てきませんね。 おっしゃる通りですね。 いつもありがとうございます。