2016-12-17 3 views
0

オブジェクト変数の宣言、設定、呼び出し、および関連するクリーンアップの面倒な、おそらくは混乱を招くプロセスを実行するコード例が頻繁に見られます。それはその機能にプライベートです。MS Access VBA:オブジェクト変数は使用されていないときに宣言されているスコープを超えていますか?

これは本当に必要なのですか?完全なリファレンスを書くときにも同様ですか?

私は議論を聞いたことがあります。コードは読みやすく、速く動作します。前者は非常に主観的であり、後者は本当に気づいていない。

例;

Public Sub TransactionExample() 

    On Error GoTo trans_Err 
    DAO.DBEngine.BeginTrans 

    CurrentDb.Execute "SomeActionQuery", dbFailOnError 
    CurrentDb.Execute "SomeOtherActionQuery", dbFailOnError 

    DAO.DBEngine.CommitTrans 

Exit Sub 

trans_Err: 
    DAO.DBEngine.Rollback 
    MsgBox "Transaction failed. Error: " & Err.Description 
End Sub 

Public Sub TransactionExample() 

    Dim wrkSpaceVar As DAO.Workspace 
    Dim dbVar As DAO.Database 

    Set wrkSpaceVar = DBEngine(0) 
    Set dbVar = CurrentDb 

    On Error GoTo trans_Err 
    wrkSpaceVar.BeginTrans 

    dbVar.Execute "SomeActionQuery", dbFailOnError 
    dbVar.Execute "SomeOtherActionQuery", dbFailOnError 

    wrkSpaceVar.CommitTrans 

    trans_Exit: 
    wrkSpaceVar.Close 
    Set dbVar = Nothing 
    Set wrkSpaceVar = Nothing 

Exit Sub 

trans_Err: 
    wrkSpaceVar.Rollback 
    MsgBox "Transaction failed. Error: " & Err.Description 
    Resume trans_Exit 
End Sub 

私は "何も" への変数の設定についての質問ではないのです。彼らが必要なのかどうか尋ねています。そしてそれが価値があるものについては、必要な、提供された例の範囲内。

+0

本当に必要なときがあります。特に、「CurrentDb」関数に関しては特にそうです。以下のコメントの関連する質問を参照してください。 –

+0

可能な複製[set dbs = currentdb()とcurrentDB()を直接使用するのに重要な違いはありますか?](http://stackoverflow.com/q/21416876/2144390) –

+0

リンクされた質問/回答は行っていませんあなたがここでやるよりも詳細な説明は、意見に基づくものであり、支持的な例はありません。 – tahwos

答えて

2

要するに、参照は両方のコードサンプルで同じになるため、ローカル変数に格納する必要はありません。 にローカル変数に設定するのは、必要なオブジェクト逆参照呼び出しを避けるためです。あなたの例では、DAO.DBEngineが3回呼び出されます。それぞれは本質的に、処理しているオブジェクト参照を取得するための処理オーバーヘッドを伴う関数呼び出しです。あなたの上の例では、その関数呼び出しはに一度だけとされ、結果はローカル変数参照にキャッシュされます。あなたはローカル変数を宣言したくない場合は

、あなたはWithブロックにおいて同一の参照を使用するコードをラップすることにより、同じことを行うことができます:あなたがのトンをやっている場合を除き

Public Sub TransactionExample() 
    With DBEngine(0) 
     On Error GoTo trans_Err 
     .BeginTrans 
     With CurrentDb 
      .Execute "SomeActionQuery", dbFailOnError 
      .Execute "SomeOtherActionQuery", dbFailOnError 
     End With 
     .CommitTrans 
trans_Exit: 
     .Close 
     Exit Sub 

trans_Err: 
     .Rollback 
     MsgBox "Transaction failed. Error: " & Err.Description 
     Resume trans_Exit 
    End With 
End Sub 

(それを広範囲にわたってループする)場合、パフォーマンスの差はごくわずかなものにすぎません。

注 - 変数をNothingに設定する必要はありません。ランタイムはスコープを離れるときにそれを処理します。

+0

申し訳ありません。 'CurrentDb'はDatabaseオブジェクトのコピーを返す*関数*であり、正しいオブジェクト参照と同じ振る舞いをしない場合*です。また、オブジェクト変数を 'Nothing' *に設定する必要はありません。しかし、長時間のVBA/VB6コーダーは、かなり不明確なアプリケーションの失敗は失敗する可能性があります。 –

+0

@GordThompson - 上記のコードでは、 'With'ブロックが評価されたときに* once *と呼ばれることに注意してください。 – Comintern

+0

あなたの1つの例がうまくいく(私は仮定している)が、それ以外の場合はたくさんある。 (また、入れ子にされた 'With'ブロックは、あいまいである可能性があるため、推奨される方法ではありません)。 –

関連する問題