2012-01-21 2 views
2

私は相対的なVBA初心者で、10秒から10分の間に実行できるかなり複雑なマクロを設計しています。 Dim appDatabaseInstance = New Excel.Applicationによって作成されたExcelの別の不可視のインスタンスでの作業のほとんどを行います。コード実行中に多くの関数とサブルーチンが使用されていますが、半予測可能なものがあればいつでもappDatabaseInstance.Quitが呼び出されるように最善を尽くしていますが、私が制御できないものが1つありますユーザー。予期しない後にポストマクロのガベージコレクションを可能にする名前付きExcel.Applicationオブジェクトの作成方法

具体的には、プログラムがクラッシュしてエスケープすると判断した場合、VBAは実行を中断し、ブレークが発生したためにガベージコレクションルーチン(私は思う)は実行されません。

私は予測可能な方法で作成したインスタンスに何らかの名前を付けて、新しいインスタンスを作成する前に既存のインスタンスを見つけて適切に処理しようとすればもっと幸せです。そうすれば、たとえ不幸なアプリケーションインスタンスが残っていても、ユーザーがプログラムに関わる何かを試みるとすぐに閉じられます(そうでなければ、1つのインスタンスがコンテキスト内で頭痛を引き起こす可能性は低いです)。

誰にも提案はありますか?

+0

ユーザーにプログレスバーを表示していますか?そうでなければ、これは彼らの忍耐を助けるだろうか? – brettdj

+0

当分の間ではありませんが、実際には進捗状況をどのようにして確実に測定するのかは100%もわかりません。それは、私が言うように、初心者を完了させると言った。 – tobriand

+0

スコープが予測できない場合は、確かに報告するのが難しくなります.....私は[Walkenbachのプログレスバー](http://spreadsheetpage.com/index.php/tip/displaying_a_progress_indicator/)を私のaddins(私のプロフィールを参照してください)、Duplicate Masterでは 'EnableCancelKey'に' xlDisable'オプションを使用しましたが、ユーザフォームで 'Cancel'をクリックして制御された終了になったかどうかを定期的に確認します。 – brettdj

答えて

6

は、ユーザーが、私はあなたがディックのブログでthis post on EnableCancelKeyを参照してください示唆してコード

中断したときに何が起こるかを決定するために、ApplicationオブジェクトのEnableCancelKeyプロパティを使用することができます。

  • xlDisable正常動作 - - コード
  • xlInterruptを中断からユーザーを防ぎ:要約として

    EnableCancelKeyは、次の3つの設定があります。デバッガが表示され、コードが中断されたときに発生した行のデバッグモードになります。
  • xlErrorHandler - エラー番号18を発生させ、他のエラーと同様に反応します。エラー処理が設定されている場合は、それが呼び出されます。
+1

+1良い提案!このようなシナリオでは、xlErrorHandlerでEnableCancelKeyを使用しています。コード内で適切なエラー処理が行われていれば、安全で信頼性が高く、無限ループに入るとコードがクラッシュする可能性があります。 –

+0

これは私が探しているキーのように聞こえる。私が知る限りでは、他のエラーはエラーハンドラを経由する必要があります。それはちょうど割り込み1です。 – tobriand

+1

+1何が必要なのか何が求められたのですか? –

3

私はこれまでVBAで同様のことをしなければなりませんでした。以下のメソッドは、現在コードを実行しているプロセス以外のすべてのExcelプロセスを終了します。 このコードを実行する前に、あなたのものを保存してください。

Declare Function GetCurrentProcessId Lib "kernel32"() As Long 

Sub CloseOtherInstances() 

    Dim currentId As Long 
    Dim wmiObj As Object 
    Dim process As Object 
    Dim processes As Object 

    currentId = GetCurrentProcessId 

    Set wmiObj = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 

    Set processes = wmiObj.ExecQuery("select * from win32_process where name ='EXCEL.exe'") 

    For Each process In processes 
    If process.ProcessId <> currentId Then process.Terminate 
    Next process 

End Sub 
+0

WMIは他のインスタンスを閉じたい場合には非常に便利ですが、この場合、ユーザーエラーの防止は治療よりも優れています:) – brettdj

+0

@brettdj私はあなたに同意します。私は彼に尋ねたことを彼に授けた、あなたは彼に必要なものを与えた。少なくとも、このコードは明示的にクローズを目指す他の人にとってはここにあります。 –

+0

うーん...それは実現する価値があるかもしれないように聞こえる。ワークブックを格納しているアプリケーションが終了したときに、それを実行しようとするべきかどうか、私は疑問に思います。 – tobriand

関連する問題