refresh eines QueryTable verursacht manchmal VBA-Fehler 400

24/06/2008 - 14:58 von sven.wuenschmann | Report spam
Hallo zusammen,

MS Excel 2002 quàlt mich seit einiger Zeit mit einem recht seltsamen
Fehler, der zudem leider nicht deterministisch auftritt.

Problembeschreibung:
-

Das Workbook muss einen externen Report aus einer csv-Datei
verarbeiten. Dieser Report wird periodisch von einem externen System
erstellt und jeweils in einer _neuen_ Datei gespeichert. Um eine
Tageshistorie abzubilden, wird die Datei also nicht aktualisiert,
sondern es wird eine neue Datei erstellt.

Wie sich vermuten làsst, wird die csv-Datei von Excel mit einem
QueryTable-Objekt eingelesen. Eine periodisch aufgerufene Funktion
pollt nun nach einer neuen Report-Datei. Liegt eine solche vor, so
wird die "Connection"-Eigenschaft des QueryTable neu gesetzt und
"Refresh" dieses Objekt aufgerufen.

Diese Vorgehen funktioniert in den meisten Fàllen. Manchmal wirft
Excel jedoch zu meinem Leidwesen einen VBA-Fehler aus: "VBA ERROR
400".

Knowledgebase sagt dazu auf http://support.microsoft.com/kb/146864/en-us
:

400 Form already displayed; can't show modally (version 97)

Nachdem dieser Fehler aufgetreten ist, hat es Excel beim nàchsten
Versuch stets geschafft, das QueryTable-Objekt aufzufrischen.

Quellcode:

==
'
*****************************************************************************
' * Import new imagine data if available
' *
' * Polls for new imagine report and loads it if newer than currently
used one.
' *
' * Return:
' * - True if new data was imported, False otherwise
'
*****************************************************************************
Public Function RefreshQueryTable() As Boolean
Dim strDirName As String
Dim strCurFileName As String
Dim strLatestFileName As String
Dim curTimeStamp As Variant
Dim latestTimeStamp As Variant

RefreshQueryTable = False

strDirName GetDirName(ThisWorkbook.Sheets("Positions").QueryTables(1).Connection)
strCurFileName GetFileName(ThisWorkbook.Sheets("Positions").QueryTables(1).Connection)
strLatestFileName = GetLatestFileName(strDirName,
REPORT_NAME_PATTERN)

' nothing to do if no imagine report is available
On Error GoTo ReturnRefreshQueryTable:
latestTimeStamp = FileDateTime(strDirName & strLatestFileName)

' always refresh if currently loaded imagine report is no longer
available (e.g. first run in the morning)
On Error GoTo DoRefreshQueryTable:
curTimeStamp = FileDateTime(strDirName & strCurFileName)

' refresh if
' newest imagine report available is new than the currently
loaded one
' or
' forced to reload latest if imagine data cell in status info is
empty (we assured that it is available)
If ((latestTimeStamp > curTimeStamp) Or
(ThisWorkbook.GetImgReportTime() = "")) Then

DoRefreshQueryTable:
ThisWorkbook.SetImgReportTime ("L O A D I N G")

On Error GoTo CatchRefreshError:
With ThisWorkbook.Sheets("Positions").QueryTables(1)
.Connection = "TEXT;" & strDirName & strLatestFileName
.Destination ThisWorkbook.Sheets("Positions").Range(QUERY_TABLE_DESTINATION)
.TextFilePlatform = 20127 ' US-ASCII
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = True
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 5, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
.Refresh BackgroundQuery:=False
End With

ThisWorkbook.SetImgReportTime (latestTimeStamp)
RefreshQueryTable = True

' force to evaluate our new positions
If (Not Application.Calculation = xlCalculationAutomatic)
Then
ThisWorkbook.Sheets("Positions").Calculate
End If
End If
Exit Function

CatchRefreshError:
ThisWorkbook.SetImgReportTime ("")
MsgBox "Excel could not refresh position data: " & Err.Description
& _
" (" & Err.Number & ")"

ReturnRefreshQueryTable:
End Function

==
Weitere Fehlerbeschreibung:

Merkwürdigerweise zeigt sich der Fehler auch auf zweierlei Arten:

(1) Wird der Fehler wie im Code mit "On Error GoTo CatchRefreshError:"
abgefangen, so zeigt die MsgBox "Excel could not refresh position
data: (0)"

(2) Verzichtet man auf das Abfangen des Fehlers, so erscheint die
genannte Fehlermeldung "VBA Error 400"

Hilfegesuch:
-

Kennt jemand diesen Fehler? Gibt es ein von MS definiertes Vorgehen,
um die "refresh"-Methode des QueryTable-Objekts mit einer abgeànderten
"Connection"-Eigenschaft aufzurufen? Gibt es eine zuverlàssige
Alternative, um die Problemstellung sauber zu lösen? Das QueryTable-
Objekt zunàchst mit der "Delete"-Methode zu löschen führt nicht direkt
zu der gewünschten Lösung, da in mehreren Spalten rechts des
QueryTable-Objekts mit den Spalten des eingelesenen Reports gerechnet
werden muss.

Vielen Dank für die Hilfestellung im voraus!

Grüße,
Sven
 

Lesen sie die antworten

#1 Susanne Wenzel
26/06/2008 - 09:31 | Warnen spam
Hallo Sven,
da hier bisher keine(r) geantwortet hat, versuche ich es mal.

Am Tue, 24 Jun 2008 05:58:33 -0700 (PDT) schrieb sven.wuenschmann:

[...]

Nachdem dieser Fehler aufgetreten ist, hat es Excel beim nàchsten
Versuch stets geschafft, das QueryTable-Objekt aufzufrischen.



Was heißt bei Dir "nàchster Versuch"?
Makro beenden und neu aufrufen oder mit F5 nach dem Fehler das Makro
weiterlaufen lassen (als Versuch)?

[Code gesnipt]

Merkwürdigerweise zeigt sich der Fehler auch auf zweierlei Arten:

(1) Wird der Fehler wie im Code mit "On Error GoTo CatchRefreshError:"
abgefangen, so zeigt die MsgBox "Excel could not refresh position
data: (0)"

(2) Verzichtet man auf das Abfangen des Fehlers, so erscheint die
genannte Fehlermeldung "VBA Error 400"



Kennst Du die Codezeile, welche den Fehler auslöst?

Hilfegesuch:
-

Kennt jemand diesen Fehler?



Ich zumindest nicht. Die Fehlernummer 400 tauchte hier in dieser NG aber
auch in einem anderen Posting auf, dort ging es wohl um Excel2007 und wurde
ausgelöst durch eine nicht geöffnete Mappe (wenn ich das noch richtig
erinnere), also etwas ganz anderes.

Falls die Fehlerbeschreibung der KB bei Dir richtig ist: Hast Du denn
überhaupt ein Formular im Einsatz?

Gibt es ein von MS definiertes Vorgehen, um die "refresh"-Methode des
QueryTable-Objekts mit einer abgeànderten "Connection"-Eigenschaft
aufzurufen?



Keine Ahnung, ich habe bisher nicht mit QueryTables zu tun gehabt.

Gibt es eine zuverlàssige Alternative, um die Problemstellung sauber zu
lösen?



Ich habe zumindest eine Idee, weiß aber nicht ob die Rahmenbedingungen bei
Dir zutreffen. Ich meine folgende:

1. Das Problem tritt unregelmàßig auf
2. Nachdem das Makro in den Fehler gelaufen ist, kann man direkt mit F5
weitermachen, es kommt fehlerlos zum Ende. Alternativ "funktioniert" auch
ein stop vor der fehlerauslösenden Zeile und daran anschließend ein F5.
3. Ein Abfragen der Werte aller zur Zeit benutzten Variablen zeigt, dass
alle ordnungsgemàß gefüllt sind.

Deshalb fragte ich oben, ob Du die Zeile kennst.

Wenn also diese Situation (das làuft bei mir persönlich unter der Rubrik
sich selbst überholende Prozesse) auch bei Dir zu finden ist:
Ich habe mir in den meisten Fàllen mit einem (ggf. auch mehreren) richtig
platzierten DoEvents helfen können.

Vielen Dank für die Hilfestellung im voraus!



Ich habe es versucht, vielleicht hilfts ja.

Viele Grüße aus dem hohen flachen Norden Deutschlands
Susanne
Office XP, SP3, aktueller Patchstand
Windows 2000, SP4, aktueller Patchstand
KI-TRIPLE 2007

Ähnliche fragen