Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


6407 / 13644 ツリー ←次へ | 前へ→

【45342】Withステートメントの正しい使い方 tomo 06/12/20(水) 8:51 質問[未読]
【45368】Re:Withステートメントの正しい使い方 ichinose 06/12/20(水) 21:35 発言[未読]
【45378】Re:Withステートメントの正しい使い方 tomo 06/12/21(木) 9:07 お礼[未読]

【45342】Withステートメントの正しい使い方
質問  tomo  - 06/12/20(水) 8:51 -

引用なし
パスワード
   スキルアップと見易いコード化を目指しています。
そこでお願いがあります。
Withステートメントの適切な使用方法を教えて下さい。

<その1>
Sub test1()
With Application
   :
   :
   :
End With
End Sub

<その2>
Sub test2()
With Application
   :
End With
   :
With Application
   :
End With
   :
End Sub

その1は,長文コードの中で何度もWithを使用するため,最初から最後までを一気にくくってしまうやり方です。
その2は,必要に応じてWithを使用する方法です。

どちらを使う方が良いのでしょうか?
やはり,Withステートメントの中に別のWithステートメントがあったりする可能性もあるため,その2の方が見やすいのでしょうか?
例としてはApplicationを挙げましたが,With Applicationの形のみの使用の場合はその1でも問題ないのでしょうか?
宜しくお願いします。

【45368】Re:Withステートメントの正しい使い方
発言  ichinose  - 06/12/20(水) 21:35 -

引用なし
パスワード
   ▼tomo さん:
こんばんは。
>Withステートメントの適切な使用方法を教えて下さい。
>
><その1>
>Sub test1()
>With Application
>   :
>   :
>   :
>End With
>End Sub
>
><その2>
>Sub test2()
>With Application
>   :
>End With
>   :
>With Application
>   :
>End With
>   :
>End Sub
>
>どちらを使う方が良いのでしょうか?
>やはり,Withステートメントの中に別のWithステートメントがあったりする可能性もあるため,その2の方が見やすいのでしょうか?

With Application と記述すれば、
それ以降(End Withまでは)のApplicationオブジェクトの
プロパティやメソッドの記述時に
「.」で済むので入力は簡単になりますけどね!!

見やすいからという理由なら、記述にインデントを付けても足りますよね!!

With ステートメントというのは、この記述により、例えば、

With Application とすると、Applicationオブジェクトがアドレッシングされ、
End Withまで保持されます。
よって、その間のプロパティの取得等がこれをしない時と比べると速いとされています。

Withステートメントって、これによる入力の簡素化も魅力ですが、
処理速度を少しでも上げるという観点からも有効な手法です。

私がWithステートメントを記述する時は、この処理速度のことをかなり
意識して記述しています。

例えば、新規ブックを3つ用意してください。

Book1.Xls Book2.Xls Book3.Xls とします。

Book1.XlsのThisworkbookのモジュールに
'================================
Sub test1() 'アドレッシングなし
  Dim idx As Long
  For idx = 1 To 20000
    Worksheets("sheet1").Range("a1").Value = Worksheets("sheet1").Range("a1").Value + 1
    Next idx
End Sub

Book2.XlsのThisworkbookのモジュールに
'===========================
Sub test1() 'withによるアドレッシング
  Dim idx As Long
  With Worksheets("sheet1").Range("a1")
    For idx = 1 To 20000
     .Value = .Value + 1
     Next idx
    End With
End Sub

Book3.XlsのThisworkbookのモジュールに
'===========================
Sub test1() '変数を使ったアドレッシング
  Dim rng As Range
  Dim idx As Long
  Set rng = Worksheets("sheet1").Range("a1")
  For idx = 1 To 20000
    rng.Value = rng.Value + 1
    Next idx
  Set rng = Nothing
End Sub

として、全て同じフォルダに保存してください。

さらにもうひとつ新規ブックを作成し、標準モジュールに
'============================================================
Sub main()
  Dim idx As Long
  Dim jdx As Long
  Dim bk As Workbook
  Dim st As Double
  Dim bknmarray As Variant
  bknmarray = Array("book1.xls", "book2.xls", "book3.xls")
  ThisWorkbook.Worksheets("sheet1").Range("a1:c1").Value = bknmarray
  For idx = LBound(bknmarray) To UBound(bknmarray)
    Set bk = Workbooks.Open(ThisWorkbook.Path & "\" & bknmarray(idx))
    For jdx = 1 To 10
     ActiveSheet.Cells.ClearContents
     st = Timer
     bk.test1
     ThisWorkbook.Worksheets("sheet1").Cells(jdx + 1, idx + 1).Value = Timer - st
     Next
    bk.Close False
    DoEvents
    Next
End Sub


このブックも先の三つのブックと同じフォルダに保存してみてください。
(仮に速度テスト.xlsとしましょう)


一度、Excelを終了し、再度、速度テスト.xlsだけを開いてください。
ここで、main実行してみてください。
これは、それぞれのブックに記述した同じ動作を行うtest1
(セルA1に20000回 1を足す)を10回実行し、
その処理時間を測るプログラムです。


私の環境では

 book1.xls  book2.xls  book3.xls
  27.73    20.339   20.018
  27.519    20.289   20.029
  27.38    20.329   19.989
  27.349    20.259   20.049
  27.339    20.46    19.978
  27.37    20.309   20.059
  27.329    20.299   19.979
  27.329    20.5    20.069
  27.53    20.339   20.029
  27.309    20.319   20.019

上記の結果が得られました(単位は秒です)。
アドレッシングした時としない時の時間差は明らかになっています。

Withはこの処理速度の短縮を意識して使うものだと思いますよ!!

【45378】Re:Withステートメントの正しい使い方
お礼  tomo  - 06/12/21(木) 9:07 -

引用なし
パスワード
   ▼ichinose さん:
mainを実行して確認してみました。
確かに随分と処理速度に影響がでるのですね。

今まではエラーのないコードを作成することだけを意識しており,ステップアップとして見易いコード化を目指していました。
処理速度のことは全く頭にありませんでした。確かにマクロによっては随分と時間がかかるものもあったため,今後は処理速度も意識したマクロ作りに励みます。

また,普段はDimステートメントの重要性が分からず,省略する癖がありましたが,少なくても処理速度を左右する上では重要なのですね。
変数を使ったアドレッシングについても,もっと学ばなければいけませんね。

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

6407 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free