Laufzeitfehler 1004 Anwendungs- oder objektdefinierter Fehler bei Diagramm Erstellung

  • Excel

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    Laufzeitfehler 1004 Anwendungs- oder objektdefinierter Fehler bei Diagramm Erstellung

    Hallo,
    ich bin neu in der VBA Programmierung und möchte mit Makros Daten auswerten welche per Labview in ein Excel File geschrieben werden. Diese Excel Files sehen dann immer gleich aus, haben jedoch unterschiedliche Zeilenlängen da die Tests nie gleich lang dauern. Um die Daten nun in ein Diagramm zu plotten habe ich mir aus verschiedenen Anleitungen Online einen Code zusammengebaut welcher zunächst ermittelt wie viele Zeilen vorliegen, diese Information in eine Variable speichert und anschließend das Diagramm über den Zeilenbereich füllt. Dies sieht wie folgt aus:

    Spoiler anzeigen

    Visual Basic-Quellcode

    1. Sub EingebundenerGraph()
    2. Dim sh As Worksheet
    3. Set sh = ThisWorkbook.Sheets(6)
    4. Dim k As Long
    5. Dim k2 As Long
    6. k = sh.Range("A1048576").End(xlUp).Row
    7. k2 = k - 1
    8. 'Dieser Teil zählt die Zellenzahl von unten nach oben und berücksichtigt das die erste Zelle nur eine Überschrift ist
    9. Dim Diagramm1 As Chart
    10. Dim SeriesName1 As String
    11. Dim SeriesName2 As String
    12. Dim SeriesName3 As String
    13. Set Diagramm1 = Tabelle8.Shapes.AddChart.Chart
    14. With Diagramm1
    15. .ChartType = xlLine
    16. .SeriesCollection.NewSeries 'Schub
    17. .SeriesCollection(1).XValues = Sheets(6).Range(Cells(2, 1), Cells(k, 1)) 'x-Werte
    18. .SeriesCollection(1).Values = Sheets(6).Range(Cells(2, 3), Cells(k, 3)) 'y-Werte
    19. SeriesName1 = Sheets(6).Cells(1, 3)
    20. .SeriesCollection(1).Name = SeriesName1
    21. .SeriesCollection.NewSeries 'Ethanol Fluss
    22. .SeriesCollection(2).XValues = Sheets(6).Range(Cells(2, 1), Cells(k, 1)) 'x-Werte
    23. .SeriesCollection(2).Values = Sheets(4).Range(Cells(2, 3), Cells(k, 3)) 'y-Werte
    24. SeriesName2 = Sheets(4).Cells(1, 3)
    25. .SeriesCollection(2).Name = SeriesName2
    26. .SeriesCollection.NewSeries 'LOX Fluss
    27. .SeriesCollection(3).XValues = Sheets(6).Range(Cells(2, 1), Cells(k, 1)) 'x-Werte
    28. .SeriesCollection(3).Values = Sheets(3).Range(Cells(2, 4), Cells(k, 4)) 'y-Werte
    29. SeriesName3 = Sheets(4).Cells(1, 4)
    30. .SeriesCollection(3).Name = SeriesName3
    31. End With
    32. End Sub



    Besonders Problematisch scheint dabei folgender Teil zu sein:

    Visual Basic-Quellcode

    1. .ChartType = xlLine
    2. .SeriesCollection.NewSeries 'Schub
    3. .SeriesCollection(1).XValues = Sheets(6).Range(Cells(2, 1), Cells(k, 1)) 'x-Werte
    4. .SeriesCollection(1).Values = Sheets(6).Range(Cells(2, 3), Cells(k, 3)) 'y-Werte
    5. SeriesName1 = Sheets(6).Cells(1, 3)
    6. .SeriesCollection(1).Name = SeriesName1

    Sobald ich den Code laufen lasse erhalte ich einen "Laufzeitfehler 1004: Anwendungs- oder objektdefinierter Fehler". Dabei ist es egal ob ich mit oder ohne with arbeite. Wenn ich ohne .SeriesCollection(1) vor den .Values arbeite ist dies wohl nicht korrekt und wird von VBA beim Kompilieren mit einem Fehler gewürdigt. Ebenso wird mir im Debugger angezeigt das die Variable k korrekte Werte beinhaltet. Desweiteren macht es keinen unterschied ob die die Sheets direkt anspreche oder per Name.
    Ich bin mir nicht sicher ob mein Code optimal geschrieben ist, jedoch erschien mir dies als die "logischste" Lösung um mehrere Datenreihen passend einzubinden.
    Anzumerken ist wahrscheinlich auch noch das im Tabellenblatt bei jedem ausführen ein Diagramm erzeugt wird, dieses aber wie im Anhang dargestellt aussieht.

    Eine zusätzliche Ergänzung noch:
    Ich habe auch einen alternativen Weg getestet über

    Visual Basic-Quellcode

    1. .SeriesCollection.Add Source:=Sheets(6).Range(Cells(2, 3), Cells(k, 3))

    jedoch wird auch hier ein entsprechender Laufzeitfehler 1004 angezeigt.

    Mit besten Grüßen,
    Trayo
    Bilder
    • Unbenannt3.PNG

      3,57 kB, 483×288, 223 mal angesehen

    Trayo schrieb:

    Sobald ich den Code laufen lasse erhalte ich einen "Laufzeitfehler 1004: Anwendungs- oder objektdefinierter Fehler".
    In welcher Zeile bleibt der Debugger stehen?
    Hast du dir an der Stelle die Objektvariablen und deren Inhalt mal angeschaut?

    Beim Debuggen ist With meist etwas lästig, weshalb ich zumindest in der Phase gerne darauf verzichte.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    petaod schrieb:

    In welcher Zeile bleibt der Debugger stehen?
    Hast du dir an der Stelle die Objektvariablen und deren Inhalt mal angeschaut?

    Beim Debuggen ist With meist etwas lästig, weshalb ich zumindest in der Phase gerne darauf verzichte.


    Er bleibt in dieser Zeile stecken:

    Visual Basic-Quellcode

    1. ​ .SeriesCollection(1).XValues = Sheets(6).Range(Cells(2, 1), Cells(k, 1)) 'x-Werte

    Ich kann aber auch durch die nächste Zeile austauschen, dann bleibt er dort stecken. Also generell bei den Value Zeilen.
    Ich habe es wie gesagt ohne das With getestet. Eben nochmal probiert. Laufzeitfehler an der selben Stelle.
    Ebenfalls habe ich die einzige Variable (k) im Debugger überprüft, diese gibt den richtigen Wert zurück.

    VB.NET-Quellcode

    1. .SeriesCollection(1).XValues = Range(Sheets(6).Cells(2, 1), Sheets(6).Cells(k, 1))

    Du arbeitest vermutlich in einem Modul.
    Bei konsequent objektorientertem Programmierstil wären solche Klimmzüge vermutlich nicht notwendig.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    petaod schrieb:


    Du arbeitest vermutlich in einem Modul.
    Bei konsequent objektorientertem Programmierstil wären solche Klimmzüge vermutlich nicht notwendig.


    Wow, daran lag es jetzt? Gefühlt das einzige was ich nicht versucht habe. Vielen Dank petaod!
    Wie kann ich solche Fehler den in Zukunft vermeiden? Mein Programm wird noch umfangreicher und soll vermutlich auch noch Eingabemöglichkeiten erhalten. Wie sollte ich da meine Programmier Art ändern um sowas zu vermeiden?

    Trayo schrieb:

    Wie sollte ich da meine Programmier Art ändern um sowas zu vermeiden?
    Das ist wohl nicht in zwei Minuten abgehandelt.
    Aber es beginnt schon damit, dass du ein Arbeitsblatt über Sheets(6) adressierst.
    Ich hätte dem Sheet einen sauberen Objektnamen verpasst (z.B. SourceData) und darüber angesprochen.
    Dann hätte ich in diesem Sheet die Properties XValueRange und ValueRange implementiert.

    Und dann würde dein Aufruf so aussehen
    ​.SeriesCollection(1).XValues = SourceData.XValueRange

    Auch die SeriesCollection(1) hätte einen vernünftigen Namen verdient.

    Das sind nur ein paar Beispiele.
    Die objektorientierte Denkweise drauf zu kriegen ist aber nicht von jetzt auf nachher möglich.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Noch einmal vielen dank. Ich habe wie gesagt erst mit VBA angefangen und kenne somit noch keine Tücken in der Sprache. Gerade das Adressieren über die Sheet Nummer fand ich eigentlich recht schön weil man so genau sieht von wo etwas kommt wenn man eher in den Tabellen im Vordergrund denkt. Ich werde mal schauen wie ich die Sachen richtig benennen kann und versuchen meinen Programmierstil dahingehend anzupassen.
    Spricht auch nichts dagegen.
    Du kannst ja den Objektnamen des Sheets sinnvoll umbenennen, dann sieht man auch, was dahinter steckt.
    Das Gefährliche bei Sheetnamen ist, dass der Benutzer sie umbenennen kann und dann der Code nicht mehr läuft.
    Und die Indexnummer Sheets(6) kann sich sehr schnell verändern.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --