2014-01-13 3 views
1

여기에서 나를 도울 수 있기를 바랍니다. 과거에는 모두 훌륭했습니다. vb.net에서 죽이는 스크립트에 대한 모든 변형을 시도했지만 아무런 소용이 없습니다.Excel에서 오류가 발생하면

먼저 내 회사의 독점 소프트웨어이기 때문에 여기에 명시적인 코드를 게시 할 수는 없지만 몇 가지 사항을 알려 드릴 수 있습니다. 또한 28,000 개가 넘는 코드가 있습니다.

  1. 나는 때문에 우리는 클라이언트 소프트웨어의 다양한 변화를 수용해야한다는 사실에

    Imports Excel = Microsoft.Office.Interop.Excel 
    

    를 사용하고 있지 않다. 나는이 여러 다른 사이트에 사용되지만 저장 한 다음 내가 안하고있는 닫을 때 사용하는 킬 (kill) 기능이 본 같은

    Dim XLObj As Object = CreateObject("Excel.Application") 
    

    으로 대상으로 새로운 엑셀을 만드는 오전.

  2. "기본 RCW에서 분리 된 Com 개체를 사용할 수 없습니다."라는 오류 메시지가 나타납니다. 시트, 통합 문서 및 응용 프로그램을 릴리스했기 때문에이 com 개체가 어디에 있는지 잘 모르겠습니다.

  3. 오, 나는 클라이언트가 이미 엑셀을 열었 으면 저장하지 않고 그것을 죽이고 싶지 않기 때문에 excel.kill()을 사용하고 싶지 않습니다. 나는 창문이 열려 있지 않은 새로 생성 된 엑셀 프로세스 만 죽이고 싶다. 나는 오픈이 실패 할 경우시/Excel 응용 프로그램을 종료 할 수 있어야

    1. 을 다음과 같이

    내 질문이 있습니다. 그래서 내가 링크를 클릭하고로드 할 수있는 Excel 템플릿을 선택하려면 대화 상자가 열리지 만 데이터베이스에서 데이터가 손상되었거나 SQL 문이 손상되었습니다. 프로그램이 throw되고 오류가 발생하면 Excel이 작업 관리자에서 닫혀 야합니다. 불행히도 그것은 문제를 닫지 않습니다.

  4. 새로 만든 프로세스 ID를 닫는 방법이 있습니까? 나는 here 지시를 사용하려고 노력했으나 그것도 작동하지 않습니다. 내가 할 때 그것은 나에게 다른 오류 "값은 null 일 수 없습니다 매개 변수 이름 : O"를 제공합니다. 오류가 발생하는 줄은 켜져 있습니다 (링크에서)

    Marshal.FinalReleaseComObject(tempVar) 
    

    우리는 XLObj에서 With를 사용하기 때문에이 작업을 시도했습니다. With는 통합 문서 자체를 참조하므로 통합 문서를 닫을 때 해제되지 않아야합니까? 그리고 내가 현재 의도적으로 오류를 일으키고 있기 때문에, 어쨌든 With 문에 도달해서는 안됩니다.

  5. 어떤 COM 개체가 닫히지 않았는지 알 수있는 방법이 있습니까?

상황은 내가 시도 :

  1. 내가 인터넷에서 발견이 releaseObject합니다.

    Private Sub releaseObject(ByRef obj As Object) 
    Try 
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj) 
        If obj Is Nothing Then 
    
        Else 
         obj = Nothing 
        End If 
    
    
    Catch ex As Exception 
        If obj Is Nothing Then 
    
        Else 
         obj = Nothing 
        End If 
    
    Finally 
        GC.Collect() 
        GC.WaitForPendingFinalizers() 
    End Try 
    End Sub 
    

(나는에왔다 많은 사이트에서 함께 재현 된)이 기능과 함께 사용됩니다 (저를 요구하지 않습니다 나는 약 75 페이지를 어디 있었는지)
Public Sub CloseExcel(ByRef WorkBook As Object, ByRef Application As Object) 
    Dim xLSheet As Object = WorkBook.Sheets 

    For Each xLSheet In WorkBook.Sheets 
     If xLSheet IsNot Nothing Then 
      releaseObject(xLSheet) 
     End If 
     If xLSheet IsNot Nothing Then 
      Kill(xLSheet) 
     End If 
    Next 

    If WorkBook IsNot Nothing Then 
     WorkBook.Close(False) 
    End If 

    If WorkBook IsNot Nothing Then 
     Kill(WorkBook) 
    End If 
    releaseObject(WorkBook) 

    If Application IsNot Nothing Then 
     Application.Quit() 
    End If 
    If Application IsNot Nothing Then 
     Kill(Application) 
    End If 


    releaseObject(Application) 

    GC.Collect() 
    GC.WaitForPendingFinalizers() 

    Application.Quit() 
End Sub 

그리고 그것은 또한 어떤 도움을 크게 감상 할 수

Public Sub Kill(ByRef obj As Object) 
    Try 
     System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj) 
    Catch ex As Exception 
     MessageBox.Show("moduleExcel.Kill " & ex.Message) 
    Finally 
     obj = Nothing 


    End Try 
End Sub 

강제 종료 기능을 참조하기 때문이다.

+0

당신은 나를 "Kill Excel ..."로 데려갔습니다. ;-) – ja72

+0

좋아, 그럼 내가 내 문제를 해결했을 수도 있습니다. 일단 내가 20 또는 그 지점 (한숨 .....)에 붙이면 나는 다른 기계에서 시험 할 필요가있다. 그것이 작동하면 수정 사항을 게시합니다. – puddleJumper

답변

1

그래, 똑같은 문제가있는 분들께. 나는 당신을위한 해결책을 가지고있다. 위의 코드는 작동하지만 약간의 조정 만 가능합니다.

  1. CloseExcel 하위의 모든 코드를 꺼내서 닫으려는 위치에 정확하게 놓아야합니다. 따라서 프로그램 오류가 발생하면 닫으려면 catch 문을 입력하십시오. Sub를 호출하여 객체를 전달할 수 없으며 프로세스를 죽일 것으로 예상 할 수 없습니다.

  2. 새 Excel 프로세스가 열리기 전에 약간의 비트가 필요합니다. 그것들은 다음과 같다.

    'declare process for excel 
    Dim XLProc As Process 
    
    'loads the financials excel bookmarks 
    'this will be where you declare your new excel opbject 
    Dim XLObj As Object = CreateObject("Excel.Application") 
    
    
    'get window handle 
    Dim xlHWND As Integer = XLObj.hwnd 
    
    Dim ProcIDXL As Integer = 0 
    'get the process ID 
    GetWindowThreadProcessId(xlHWND, ProcIDXL) 
    XLProc = Process.GetProcessById(ProcIDXL) 
    

물론 당신은 내가 원래의 질문에 포함 된 링크에서받은 GetWindowThreadProcessId가 필요합니다. 나는 당신이 그것을 찾을 필요가 없도록 여기에 게시하고 있습니다.

<System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _ 
Private Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer 
End Function 

이 코드는 연결된 단일 프로세스 만 종료하며 열려있는 다른 Excel 파일은 닫지 않습니다. 우리의 고객은 때때로 여러 파일을 열어서 알려주지 않고 닫고 싶지 않습니다. 이렇게하면 런타임에 시스템 오류가 발생할 때 생성 된 Excel 프로세스가 죽습니다.

+0

+1 자신의 질문에 대답 해주세요. – Brian

관련 문제