HERBERS Excel-Forum - das Archiv
Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
rgill
Moin liebes Forum,

folgendes Problem/Phänomen:

Ich habe in einem .xlsm-Dokument (nenne es weiterhin Dok1) Schrittweise Subs implementiert. Während des Aufbaus/Tests habe ich die Subs ganz einfach einzeln, nacheinander über Buttons aufgerufen. Nachdem alles lief wie gewünscht, wollte ich nun die Subs über Workbook_Open und Call automatisch beim Öffnen des Dokuments aufrufen. Nun erhalte ich den Fehler:

"Laufzeitfehler '1004': Die Methode 'ExportAsFixedFormat' für das Objekt '_Workbook' ist fehlgeschlagen."

Das ist der betroffene Sub, fettgedruckt die Zeile die den Fehler auslöst:

Sub export()
Dim strPath, strFilename As String
strPath = ThisWorkbook.Path & "\reports\"
strFilename = strPath & "e2n_Report_" & ThisWorkbook.Sheets(1).Cells(2, 2) & ".pdf"

ThisWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:=strFilename _
, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _
:=False, From:=2, To:=7, OpenAfterPublish:=False


Call mail
End Sub

Auch wenn ich den Sub "export" über einen anderen Sub calle, wird der Fehler ausgelöst. Ich habe ein anderes Dokument (Dok2) mit einer ähnlichen Auswertung und genau diesem pdf-Export-sub, dort läuft er fehlerfrei, auch über den workbook_open-Aufruf. Ich habe das Dokument auch an anderen Speicherorten (direkt auf C:/ etc.) ausprobiert: es macht keinen Unterschied.

Der einzige Unterschied den ich zwischen Dok1 und Dok2 sehe ist: Dok2 sammelt einfach nur Daten aus anderen Exceldokumenten ein (workbook.open, einlesen, workbook.close) und in Dok1 ist eine aktive Datenverbindung ("Daten aus dem Web", Connectorabfrage mit Token) vorhanden. Aber, wie gesagt, wenn ich die einzelnen Subs manuell aufrufe, läuft alles:
1. ChangeParameterValue: Daten werden abgerufen, dauert ca. 30 sec.
2. export: pdf-Dokument wird erzeug
3. mail: pdf-Dokument wird in den Anhang einer Mailnachricht gepackt.

Allein schon wenn ich "export" im ersten Sub "ChangeParameterValue" > via call export aufrufe, kommt der Fehler.

Bin für jeden Tipp dankbar! Das Dok1 soll, wie schon erfolgreich Dok2, automatisch morgens über die Windows Aufgabenplanung aufgerufen werden und einen Bericht verschicken.
AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
Oberschlumpf
Hi,

ich glaube, hier: "...dauert ca. 30 sec. ..." könnte dein Problem sein.
Der Datenabruf ist noch gar nicht fertig, aber schon wird der Export-Code aufgerufen.

Call mal dein Export-Makro im Makro des Datenabrufs ganz als letzte Zeile.
Wenn das auch nix hilft, bau eine "Wartepause" ein, die zwar den DAtenabruf bis zum Schluss abarbeitet, aber mind. 30 Sec bis zum Export wartet - dazu gibt es viele Vsp im Inet.

Hilft auch das nicht, dann zeig uns bitte genügend Bsp-Dateien mit genügend Bsp-Daten per Upload.

Ciao
Thorsten
AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
rgill
Moin Thorsten,

danke für deinen Input. Hier die Ergebnisse meiner Tests:

1. wait: es hat keinen Unterschied gemacht. Anmerkung hierzu: Es gibt bei den Datenverbindungs-Eigenschaften die Option: "Aktualisierung im Hintergrund zulassen". Die hatte ich früher, nach einer Internetrecherche, bereits deaktiviert, weil sie bewirkt, dass während der Aktualisierung alles nachfolgende warten muss, wohl auch vba-Code. Wenn ein nachgeschalteter Sub eine msgbox ausgibt, erscheint sie auch erst dann, wenn die Aktualisierungen abgeschlossen sind.

2. msgbox: ich habe direkt vor der Zeile die den Fehler verursacht, eine msgbox eingegeben. Die erscheint ordnungsgemäß. Dann bin ich Kaffee trinken gegangen und habe nach Minuten auf "ok" gedrückt. Sofort in der nächsten Zeile, beim Export erscheint der obige Fehler. Ich habe noch ein thisworkbook.save davor eingebaut, macht auch keinen Unterschied.

3. der erste Sub in der Reihenfolge stößt die Datenverbindung an. Nun habe ich getestet: in workbook_open den ersten sub auslassen. Es wird dann also abgearbeitet:
pdf-exportieren
pdf in Mailanhang packen
Dokument schließen
>Ergebnis: das funktioniert ohne Probleme

Ich poste hier mal den Code vom Sub:



Sub ChangeParameterValue(ParameterName As String, ParameterValue As String, onlyoneday As Boolean, tage As Integer)
Dim n, i As Integer
Dim datumstring As String

Excel.Application.ScreenUpdating = False

For i = 1 To tage
Dim qry As WorkbookQuery
Dim formula As Variant

If onlyoneday = False Then
datumstring = Left(ParameterValue, 7) & "-" & Format(i, "00")
Else
datumstring = ParameterValue
End If

'=== Get the query
Set qry = ThisWorkbook.Queries(ParameterName)

'=== Split the formula into 3 parts and update the second one
formula = Split(qry.formula, Chr(34), 3)
formula(1) = datumstring

'=== Update the parameter value
qry.formula = Join(formula, Chr(34))

ThisWorkbook.RefreshAll

If onlyoneday = True Or i = tage Then
Call stundenchart
Call diagrammformat
End If

Excel.Application.Calculation = xlAutomatic
Call copy_data(datumstring)
Excel.Application.Calculation = xlManual

Next

Excel.Application.ScreenUpdating = True
Excel.Application.Calculation = xlAutomatic

End Sub

AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
Oberschlumpf
Hi,

"Aktualisierung im Hintergrund zulassen" = "...weil sie bewirkt, dass während der Aktualisierung alles nachfolgende warten muss, wohl auch vba-Code..." = ABER DAS ist doch genau das, was du erreichen willst, oder???? Wieso schaltest du das dann ab???

Und meine Bitte, wenn keiner meiner Tipps hilft, per Upload Bsp-Datei(en) mit Bsp-Daten zu zeigen, hast du auch nicht berücksichtigt.
Weiter viel Erfolg.

Ciao
Thorsten
AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
rgill
Moin Thorsten,

"Aktualisierung im Hintergrund zulassen" > das funktioniert genau anders herum als du annimmst. Wenn man die Option aktiviert, laufen die Aktualisierungen im Hintergrund, d.h. Daten werden von irgendwoher geladen und man kann im Dokument weiterarbeiten und auch Code läuft parallel und greift dann z.B. auf alte, noch nicht aktualisierte Daten zu. Wenn man die Option deaktiviert, ist es also keine Aktualisierung im Hintergrund, sondern die aktuelle/einzige Aktion, d.h. die Daten werden aktualisiert und erst wenn alles geladen ist, kann man im Dokument weiterarbeiten bzw. Code läuft weiter.

@Beispiel-Datei: Sorry, ich war zunächst mit Test deiner Inputs beschäftigt. Jetzt, da ich weiß dass der Fehler durch den Sub diagrammformat ausgelöst wird (bzw.: wenn man ihn auslässt, läuft der pdf-Export ohne Probleme), habe ich versucht, die Datei uploadfähig zu frisieren. Ich muss die Datenverbindungen alle löschen, Daten rauswerfen etc. Siehe Anhang: Hier nun folgendes Phänomen: Es tritt ein anderer Fehler auf (in derselben pdf-Export-Zeile)! Aber die Parallele: Der einzeln aufgerufene Sub "export" läuft fehlerfrei. Wird zuvor der Sub "diagrammformat" aufgerufen, kommt es zum Fehler.

https://www.herber.de/bbs/user/176587.xlsm
AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
rgill
Moin Thorsten,

ich direkt noch einmal: Da ich ja nun herausgefunden habe, dass der erste Sub mit dem Fehler zusammenhängt, habe ich dort zeilenweise Anweisungen auskommentiert um zu schauen, ob eine spezielle Anweisung mit dem Fehler in Verbindung steht. Und tatsächlich:

call diagrammformat ist der Übeltäter. Lasse ich das weg, läuft alles fehlerfrei durch. Nun habe ich mir den Sub angesehen und habe nun wirklich keinen blassen Schimmer, was dort zu diesem Fehler führt. Prinzipiell habe ich 30 Diagramme in meinem Exceldokument, und dieser sub passt die Skalierung der Haupt- und Zweitachse an (Min, Max, Unit). Ich kann sie nicht auf Auto lassen, weil Min=0 sein muss und die Zweitachse in Abhängigkeit zur Hauptachse skaliert sein muss.

Hat jemand einen Tipp, warum die Ausführung dieses Subs im nächsten Sub den pdf-Export-Error verursacht!? Bzw: was könnte ich versuchen im Code zu ändern?

Der Sub-Code ist leider langer Spaghetti-Code:



Sub diagrammformat()
Dim i, j, intSheetcount, startsheet As Integer
Dim max, unit As Double
Dim liste(13), liste2(0), liste3(12) As String
liste(0) = "Diagramm 15"
liste(1) = "Diagramm 1"
liste(2) = "Diagramm 2"
liste(3) = "Diagramm 3"
liste(4) = "Diagramm 4"
liste(5) = "Diagramm 5"
liste(6) = "Diagramm 6"
liste(7) = "Diagramm 7"
liste(8) = "Diagramm 8"
liste(9) = "Diagramm 9"
liste(10) = "Diagramm 10"
liste(11) = "Diagramm 11"
liste(12) = "Diagramm 12"
liste(13) = "Diagramm 13"

liste2(0) = "Diagramm M1"

liste3(0) = "Diagramm M2"
liste3(1) = "Diagramm M3"
liste3(2) = "Diagramm M4"
liste3(3) = "Diagramm M5"
liste3(4) = "Diagramm M6"
liste3(5) = "Diagramm M7"
liste3(6) = "Diagramm M8"
liste3(7) = "Diagramm M9"
liste3(8) = "Diagramm M10"
liste3(9) = "Diagramm M11"
liste3(10) = "Diagramm M12"
liste3(11) = "Diagramm M13"
liste3(12) = "Diagramm M14"

intSheetcount = ThisWorkbook.Sheets.Count

For i = 0 To UBound(liste)

max = Worksheets("tableD").Cells(2 + i * 2, 29).Value
If Worksheets("tableD").Cells(2 + i * 2, 29).Value < 700 Then unit = 100 Else unit = (Worksheets("tableD").Cells(2 + i * 2, 29).Value \ 700) * 100

ThisWorkbook.Sheets("graphD").ChartObjects(liste(i)).Activate
With ActiveChart.Axes(xlValue)
.CrossesAt = 0
.MinimumScale = 0
.MaximumScale = max
.MajorUnit = unit
End With
With ActiveChart.Axes(xlValue, xlSecondary)
.CrossesAt = 0
.MinimumScale = 0
.MaximumScale = max / ThisWorkbook.Sheets(1).Cells(3, 2)
If i = 0 Then .MajorUnit = 10 Else .MajorUnit = 2
End With

Next

For i = 0 To UBound(liste2)

max = Worksheets("tableM").Cells(3 + i, 8).Value
If Worksheets("tableM").Cells(3 + i, 8).Value < 700 Then unit = 100 Else unit = (Worksheets("tableM").Cells(3 + i, 8).Value \ 700) * 100

ThisWorkbook.Sheets("graphD").ChartObjects(liste2(i)).Activate
With ActiveChart.Axes(xlValue)
.CrossesAt = 0
.MinimumScale = 0
.MaximumScale = max
.MajorUnit = unit
End With
With ActiveChart.Axes(xlValue, xlSecondary)
.CrossesAt = 0
.MinimumScale = 0
.MaximumScale = max / ThisWorkbook.Sheets(1).Cells(3, 2)
If Worksheets("tableM").Cells(3 + i, 9).Value >= 700 Then .MajorUnit = (Worksheets("tableM").Cells(3 + i, 9).Value \ 700) * 100 Else .MajorUnit = 100
'If i = 0 Then .MajorUnit = 100
End With

Next

For j = 1 To intSheetcount
If Right(ThisWorkbook.Sheets(j).Name, 2) = "HM" Then
startsheet = j
Exit For
End If
Next

For i = 0 To UBound(liste3)

max = Worksheets(startsheet + 3 * i).Cells(2, 11).Value
If Worksheets(startsheet + 3 * i).Cells(2, 11).Value < 700 Then unit = 100 Else unit = (Worksheets(startsheet + 3 * i).Cells(2, 11).Value \ 700) * 100

ThisWorkbook.Sheets("graphM").ChartObjects(liste3(i)).Activate
With ActiveChart.Axes(xlValue)
.CrossesAt = 0
.MinimumScale = 0
.MaximumScale = max
.MajorUnit = unit
End With
With ActiveChart.Axes(xlValue, xlSecondary)
.CrossesAt = 0
.MinimumScale = 0
.MaximumScale = max / ThisWorkbook.Sheets(1).Cells(3, 2)
If Worksheets(startsheet + 3 * i).Cells(2, 12).Value >= 700 Then .MajorUnit = (Worksheets(startsheet + 3 * i).Cells(2, 12).Value \ 700) * 100 Else .MajorUnit = 25
'If i = 0 Then .MajorUnit = 100
End With

Next

End Sub

AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
daniel
Hi
so direkt schwer zu sagen.
kritisch ist immer das selektieren und aktivieren von Objekten auf Tabellenblättern, da das nur funktioniert, wenn auch das übergeordnete Tabellenblatt ebenfalls aktiv ist. Beim Testen der Einzelmakros fällt es nicht auf, weil man dann immer das passende Blatt vorher aktiviert. Bei Makros, die sich gegenseitig aufrufen, ist das nicht immer gewährleistet.

also hier:
ThisWorkbook.Sheets("graphD").ChartObjects(liste2(i)).Activate

With ActiveChart.Axes(xlValue)

sollte ein anderes Blatt als "graphD" aktiv sein, funktioniert dieser code nicht.
vielleicht kannst du aber daruf verzichten und vollständig referenzieren:
With  ThisWorkbook.Sheets("graphD").ChartObjects(liste2(i)).Axes(xlValue)


Gruß Daniel
AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
rgill
Moin Daniel,

auch dir vielen Dank für dein Feedback. Ich bin mir nicht sicher, ob ich dich richtig verstanden habe.

Du meinst, das eher "schlechte" Handling über Selections führt am Ende dazu, dass der Sub, indem dann der Fehler (pdf-Export) auftritt, nicht richtig funktioniert?

Nur Sicherheitshalber die Klarstellung:
> Sub diagrammformat: macht mir keine Probleme. Alle Diagramme werden gemäß des Codes formatiert und skaliert
> Sub export: macht AUSSCHLIESSLICH Probleme, wenn zuvor diagrammformat ausgeführt wird.

Oder:
Call UpdateParameter
Call diagrammformat
Call export
> Fehler tritt in export auf ("Laufzeitfehler 1004")

Call UpdateParameter
Call export
> Fehler tritt NICHT auf
AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
daniel
dann müsstest du mal schauen, ob es einen Unterschied gibt im Zustand der Excel, je nachdem ob Chart-Makro läuft oder nicht.
bspw ist denn das Chart noch aktiv, wenn du den Export durchführst? vielleicht ist das ja das Problem.

Gruß Daniel
AW: Laufzeitfehler '1004' - Aber nur bei INDIREKTEM Aufruf!
rgill
Lieber Daniel,

vielen Dank, das war es! Direkt nach dem Diagramm-Formatierungscode, der die Charts activated/selected, habe ich einfach noch eingefügt:

Application.Goto reference:=ThisWorkbook.Sheets(1).Range("A1")

> nun läuft der nachfolgende pdf-Export fehlerfrei.

Danke für euren Input!