Withブロック使用上の注意

Withでまとめるときの注意

実験1

たとえば、ワークシート上に、

f:id:akashi_keirin:20170415072003j:plain

こんな表を作ったとする。知性のかけらもないのは許してほしい。

んで、この表に対して、

リスト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セルを含むアクティブセル領域に格子罫線を施しているので、

f:id:akashi_keirin:20170415072010j:plain

当然こうなる。

実験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でまとめたわけだ。ちょうど、共通因数を括り出したような感じだな。

んで、こいつを実行すると、

f:id:akashi_keirin:20170415072021j:plain

こうなる。オーマイガ━━(゚Д゚;)━━ン!

原因

リスト2の(1)、

With sh.Range("A1").CurrentRegion

の時点で、CurrentRegionプロパティには、A1~A6セルの範囲がセットされている。

んで、(2)の

sh.Range("A7").Value = "デコスケ"

で、A7セルに値が入るので、CurrentRegionプロパティがA1~A7セルになりそうなもんなんだが、(3)の

.Borders.LineStyle = xlContinuous

の実行結果
f:id:akashi_keirin:20170415072021j:plain
からすると、CurrentRegionプロパティはA1~A6セルのまんま。

つまり、オブジェクトの取得はWithでまとめたそのときだけ、ということなんだな。

まあ、だからこそ計算(=プロパティの取得)回数が減らせるわけで、ごくごく当たり前のことなんだが、この程度のことでちょっと(ほんのちょびっとですけど)ハマったので、覚書として残しておく。

おわりに

With~End Wtihは共通因数でくくるみたいなもん

と思っていましたけど、そういう雑な理解だと失敗するよ、というお話でした。

@akashi_keirin on Twitter