none
Öffnen Excel in SSIS bring folgende Fehlermeldung: "Durch den Messagefilter wurde angezeigt, dass die Anwendung ausgelastet ist. (Ausnahme von HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))"

    Frage

  • Hallo,

    ich öffne in einem SSIS-VB-Script eine Excel-Datei mit mehreren Pivot-Tabellen, um diese zu aktualisieren.

    Bei einer Datei bekomme ich jedes mal die folgende Fehlermeldung:

    "Durch den Messagefilter wurde angezeigt, dass die Anwendung ausgelastet ist. (Ausnahme von HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))"

    Hat jemand eine Idee, wie ich dieses Problem in den Griff bekommen kann?

    Dim oExcel As New Microsoft.Office.Interop.Excel.Application Dim oBook As Microsoft.Office.Interop.Excel.Workbook = Nothing Dim oBooks As Microsoft.Office.Interop.Excel.Workbooks = Nothing Dim numFiles As Integer Dim i As Integer Dim fileList As String Dim fileName As String = "" Dim filePath As String Dim fileIsWriteProtect As Boolean Try oExcel = CreateObject("Excel.Application") oExcel.Visible = False oExcel.Interactive = False oExcel.ScreenUpdating = False oExcel.DisplayAlerts = False oExcel.EnableEvents = False oExcel.UserControl = False oBooks = oExcel.Workbooks filePath = Trim(Dts.Variables("StrFilePath").Value.ToString()) If Right(filePath, 1) <> "\" Then filePath = filePath & "\" End If fileList = Trim(Dts.Variables("StrFileList").Value.ToString()) fileList = RTrim(fileList) If Right(fileList, 1) <> ";" Then fileList = fileList & ";" End If fileList = Replace(fileList, ";;", ";") numFiles = Len(fileList) - Len(Replace(fileList, ";", "")) For i = 1 To numFiles If InStr(fileList, ";") > 0 Then fileName = Left(fileList, InStr(fileList, ";") - 1) fileList = Trim(Mid(fileList, InStr(fileList, ";") + 1)) 'Debug.Print("Bearbeite Datei " & fileName) 'Start Excel and open workbook If CheckFile(filePath & fileName) = True Then oExcel.DisplayAlerts = False oExcel.EnableEvents = False fileIsWriteProtect = GetAttribute(filePath & fileName, FileAttribute.ReadOnly) If fileIsWriteProtect = True Then RemoveAttribute(filePath & fileName, FileAttribute.ReadOnly) End If oBook = oBooks.Open(filePath & fileName)

    ' Der Fehler tritt bei dieser Open-Anweisung auf oBook.RefreshAll() oExcel.DisplayAlerts = False oExcel.EnableEvents = False oBook.Save() oBook.Close() If fileIsWriteProtect = True Then SetAttribute(filePath & fileName, FileAttribute.ReadOnly) End If End If End If ' Clean-up: Close workbook and quit Excel. 'End If Next oExcel.Quit() Dts.TaskResult = ScriptResults.Success Catch ex As Exception Trace.TraceError(ex.Message) Debug.Print("Fehler beim Bearbeiten der Datei " & fileName) Dts.TaskResult = ScriptResults.Failure Finally If oBook IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook) If oBooks IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks) If oExcel IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel) oBook = Nothing oBooks = Nothing oExcel = Nothing End Try End Sub


    Hat jemand eine Idee, wie ich dieses Problem in den griff bekommen kann?
    Dieser Fehler tritt übrigens bisher nur bei einer Excel-Datei auf, die relativ viele Pivot-Tabellen enthält.

    Gruß

    cheapy

    Dienstag, 26. März 2013 07:37

Antworten

  • Nochmals hallo,

    ich habe noch ein wenig weiter getestet und muss mich ein wenig revidieren.

    Der Fehler tritt nicht beim Öffnen der Excel-Datei auf sondern bei dem Statement

    oBook.RefreshAll()

    Ich habe nun das Statement durch die folgenden Anweisungen ersetzt:

    For Each oSheet In oBook.Worksheets
       For Each oPivot In oSheet.PivotTables
          oPivot.RefreshTable()
          oPivot.Update()
       Next
    Next
    

    Zumindest konnte ich damit den Fehler umgehen.

    Klar, jetzt dauert alles viel länger und im Taskmanager konnte ich beobachten, dass der Abeitsspeicherverbrauch nun zwischenzeitlich viel größer ist.

    Stellt sich die Frage wie lange das mit dieser Umgehung klappt.

    Gruß

    cheapy

    • Als Antwort markiert Cheaptrick_la Donnerstag, 28. März 2013 11:42
    Mittwoch, 27. März 2013 07:57

Alle Antworten

  • Nochmals hallo,

    ich habe noch ein wenig weiter getestet und muss mich ein wenig revidieren.

    Der Fehler tritt nicht beim Öffnen der Excel-Datei auf sondern bei dem Statement

    oBook.RefreshAll()

    Ich habe nun das Statement durch die folgenden Anweisungen ersetzt:

    For Each oSheet In oBook.Worksheets
       For Each oPivot In oSheet.PivotTables
          oPivot.RefreshTable()
          oPivot.Update()
       Next
    Next
    

    Zumindest konnte ich damit den Fehler umgehen.

    Klar, jetzt dauert alles viel länger und im Taskmanager konnte ich beobachten, dass der Abeitsspeicherverbrauch nun zwischenzeitlich viel größer ist.

    Stellt sich die Frage wie lange das mit dieser Umgehung klappt.

    Gruß

    cheapy

    • Als Antwort markiert Cheaptrick_la Donnerstag, 28. März 2013 11:42
    Mittwoch, 27. März 2013 07:57
  • Hallo Cheapy,

    Kurzfassung:
    Excel ist nicht wirklich für SSIS geeignet.
    Es es ist als Desktop-Anwendung ausgelegt, und nicht für die Multi-Threading-Anforderung in SSIS.

    Der RPC Fehlercode führt zum COM IMessageFilter[1].
    Von der Funktionalität ist das identisch zu dem, was man vom Windows-Desktop mit "Die Anwendung reagiert nicht..." kennt,
    wenn eine Anwendung die Windows Meldungsschleife nicht bedient, weil sie zu sehr mit sich beschäftigt ist.

    Auch wenn ich keine Pivot Tabellen in Excel zu Testen habe:
    Ähnliches könntest Du zu sehen bekommen, wenn Du ein VBA-Makro mit RefreshAll durchlaufen lässt.

    Was das Langfristige angeht:
    Sollten einige Pivot-Tabellen vom Volumen zu groß werden, dürfte der Fehler auch bei RefreshTable auftreten.
    Zum anderen könnte Excel als Prozess der Speicher ausgehen.

    Zum Code:
    Etwas robuster mag das Skript werden, wenn Du die Verweise (wie oBook, oBooks) je Datei freigibst.

    Gruß Elmar

    [1] Man kann so etwas zwar auch selber implementieren:
    http://blogs.msdn.com/b/andreww/archive/2008/11/19/implementing-imessagefilter-in-an-office-add-in.aspx
    nur würde ich unter SSIS davon abraten - zumal es nur die Fehlermeldung verhindern würde.

    Mittwoch, 27. März 2013 08:51
  • Hallo,

    ja, wie beschrieben hatte ich es ja schon so umgestellt, dass ich die Pivot-Tabellen einzeln refreshe.

    Das treibt zwar den Arbeitsspeicherverbrauch (etwa Faktor 2) drastisch in die Höhe und dauert deutlich länger aber es funktioniert wenigstens.

    Gut, als Lösung würde ich das jetzt nicht bezeichnen, eher als eine Umgehung.

    Dem Hinweis von Elmar zufolge dürfte es da ja leider auch keine richtige Lösung geben.

    Da hier niemand einen besseren Tipp hat, sollten wir das Thema als "gelöst" bezeichnen auch wenn es das ja nicht wirklich ist.

    Gruß

    cheapy


    Donnerstag, 28. März 2013 11:42
  • Noch etwas:

    In diesem Zusammenhang ergab sich gerade bei größeren Excel-Dateien das Problem, dass sich die genutzte Excel-Instanz nicht schießen lies.

    Die Anweisung

    oExcel.Quit()

    blieb ohne Folgen und brachte auch keinen Fehler.

    Nach einigem suchen habe ich folgendes gefunden:

    ''Zugang zur API ''user32'' 
        Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Integer, ByRef lpdwProcessId As IntPtr) As IntPtr
    
        ''Beenden eines speziellen Excel Prozesses, anhand seiner Id
        Private Shared Sub killExcelInstanceById(ByRef xlsApp As Microsoft.Office.Interop.Excel.Application)
    
            Dim processId As IntPtr
    
            ''API Funktion, out val: processId
            GetWindowThreadProcessId(xlsApp.Hwnd, processId)
    
            ''Prozess erstellen
            Dim excelProcess As Process = Process.GetProcessById(processId.ToInt32())
    
            Debug.WriteLine(processId)
            excelProcess.Kill()
    
        End Sub

    Gut, das mag jetzt eine etwas rustikale Lösung sein aber dafür gibt es anschließend keine Excel-Leichen.

    Donnerstag, 28. März 2013 11:49