Withブロック使用上の注意
Withでまとめるときの注意
実験1
たとえば、ワークシート上に、
こんな表を作ったとする。知性のかけらもないのは許してほしい。
んで、この表に対して、
リスト1
Public Sub test01() Dim sh As Worksheet Set sh = ActiveSheet sh.Range("A1").CurrentRegion.Sort _ key1:=sh.Range("A1"), _ order1:=xlAscending, _ Header:=xlNo '……(1)' sh.Range("A7").Value = "デコスケ" '……(2)' sh.Range("A1").CurrentRegion _ .Borders.LineStyle = xlContinuous '……(3)' End Sub
こんなコードを実行したとする。
(1)の
sh.Range("A1").CurrentRegion.Sort _ key1:=sh.Range("A1"), _ order1:=xlAscending, _ Header:=xlNo
でA1セルを含むアクティブセル領域を昇順に並べ替えて、
(2)の
sh.Range("A7").Value = "デコスケ"
でA7セルに「デコスケ」と書き込み、
(3)の
sh.Range("A1").CurrentRegion _ .Borders.LineStyle = xlContinuous
でA1セルを含むアクティブセル領域に格子罫線を施しているので、
当然こうなる。
実験2
で、リスト1を次のように書き換えてみる。
リスト2
Public Sub test02() Dim sh As Worksheet Set sh = ActiveSheet With sh.Range("A1").CurrentRegion '……(1)' .Sort key1:=sh.Range("A1"), _ order1:=xlAscending, _ Header:=xlNo sh.Range("A7").Value = "デコスケ" '……(2)' .Borders.LineStyle = xlContinuous '……(3)' End With End Sub
要するに、
sh.Range("A1").CurrentRegion
を2回も書くのがうっとうしいので、Withでまとめたわけだ。ちょうど、共通因数を括り出したような感じだな。
んで、こいつを実行すると、
こうなる。オーマイガ━━(゚Д゚;)━━ン!
原因
リスト2の(1)、
With sh.Range("A1").CurrentRegion
の時点で、CurrentRegionプロパティには、A1~A6セルの範囲がセットされている。
んで、(2)の
sh.Range("A7").Value = "デコスケ"
で、A7セルに値が入るので、CurrentRegionプロパティがA1~A7セルになりそうなもんなんだが、(3)の
.Borders.LineStyle = xlContinuous
の実行結果
からすると、CurrentRegionプロパティはA1~A6セルのまんま。
つまり、オブジェクトの取得はWithでまとめたそのときだけ、ということなんだな。
まあ、だからこそ計算(=プロパティの取得)回数が減らせるわけで、ごくごく当たり前のことなんだが、この程度のことでちょっと(ほんのちょびっとですけど)ハマったので、覚書として残しておく。
おわりに
With~End Wtihは共通因数でくくるみたいなもん
と思っていましたけど、そういう雑な理解だと失敗するよ、というお話でした。