2012-01-21 2 views
2

저는 상대적인 VBA 초보자이며 10 초에서 10 분 사이의 아무 것도 실행할 수있는 상당히 복잡한 매크로를 디자인합니다. 보이지 않는 다른 Excel 인스턴스에서 대부분의 작업이 Dim appDatabaseInstance = New Excel.Application에 의해 생성됩니다. 코드 실행 과정에서 사용되는 많은 함수와 서브 루틴이 있습니다. 반 예측 가능한 것이 잘못 될 때마다 appDatabaseInstance.Quit이 호출되도록 최선을 다했으나, 제어 할 수없는 한 가지가 있습니다. 사용자.예기치 않은 포스트 매크로 가비지 수집을 허용하는 명명 된 Excel.Application 객체를 구현하는 방법

특히 사용자가 프로그램이 충돌하여 이탈을 결정하면 VBA가 실행을 중단하고 중단이 발생하여 내 가비지 수집 루틴 (내가 생각하는)이 발생하지 않습니다.

예를 들어 예측 가능한 방식으로 인스턴스 이름을 지정하고 새 인스턴스를 만들기 전에 기존 인스턴스를 찾고 적절히 처리하려고하면 훨씬 행복해집니다. 그렇게하면 불행한 응용 프로그램 인스턴스가 열려 있어도 사용자가 프로그램과 관련된 다른 작업을 시도하자마자 닫히게됩니다 (그렇지 않으면 인스턴스가 너무 많아 문맥에서 너무 많은 두통을 일으키지 않습니다).

누구에게 의견이 있습니까?

+0

사용자에게 진행률 표시 줄을 표시합니까? 그렇지 않다면 인내를 도울 것입니다. – brettdj

+0

당분간은 아니지만 실제로 진행률을 얼마나 신뢰할 수 있는지를 100 % 확신 할 수는 없습니다. 작업의 대부분이 완료 될 때까지는 수행 할 수 없기 때문에 수행해야 할 작업의 수를 알 수 있습니다. 그건 내가 말했듯이, 초보자를 완료했다. – tobriand

+0

범위를 예측할 수 없다면 분명히보고하기가 더 어렵습니다. ..... [Walkenbach의 진행률 표시 줄] (http://spreadsheetpage.com/index.php/tip/displaying_a_progress_indicator/)을 두 가지 모두에 사용했습니다. 내 addins (내 프로필 참조), 복제 마스터에서'EnableCancelKey'에 대해'xlDisable' 옵션을 사용했지만 사용자가 내 사용자 폼에서'Cancel'을 클릭하여 제어 된 종료에 도달했는지 정기적으로 확인합니다. – brettdj

답변

6

당신은 사용자가 당신이 딕의 블로그에 this post on EnableCancelKey를 참조 제안 코드

중단 할 때 무슨 일이 일어날 지 결정하기 위해 Application 개체의 EnableCancelKey 속성을 사용할 수 있습니다.

  • xlDisable 정상 작동 - - 코드
  • xlInterrupt을 방해에서 사용자를 방지 : 요약으로

    , EnableCancelKey은 세 가지 설정이 있습니다. 디버거가 표시되고 코드가 인터럽트 된 시점의 디버그 모드에 있습니다.
  • xlErrorHandler - 오류 번호 18을 발생시키고 다른 오류와 마찬가지로 반응합니다. 오류 처리가 설정되어 있으면 호출됩니다.
+1

+1 좋은 의견입니다. 심지어 이러한 시나리오에서는 EnableCancelKey를 xlErrorHandler와 함께 사용합니다. 무한 루프에 들어가면 코드가 충돌 할 수있는 코드에서 적절한 오류 처리가 수행되면 안전하고 신뢰할 수 있습니다. –

+0

내가 찾는 열쇠처럼 들린다. 내가 말할 수있는 것만 큼 근처에서 다른 오류는 내 오류 처리기를 통과해야합니다. 그것은 단지 방해물입니다. – tobriand

+1

+1 무엇이 필요한지 묻습니다. –

3

나는 VBA에서 비슷한 것을해야만했습니다. Follow 메서드는 현재 코드를 실행중인 다른 모든 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 동의합니다. 나는 그가 요구 한 것을 그에게 주었고, 당신은 그가 필요한 것을주었습니다. 적어도이 코드는 명시 적으로 닫는 Excel을 찾는 다른 사용자를위한 것입니다. –

+0

음 ... 구현할만한 가치가있는 것 같습니다. 나는 통합 문서를 보관하는 응용 프로그램이 닫힐 때이를 시도하고 실행해야하는지 궁금합니다. 물론 사용자에게 적절한 promp ...? – tobriand