For Each ... Next läuft in Schleife, soll aber nur einmal ausgeführt werden!

  • Excel

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

    For Each ... Next läuft in Schleife, soll aber nur einmal ausgeführt werden!

    Hallo Zusammen,

    mal wider habe ich eine Herausforderung zu meistern. Ich habe also eine Zeitreihe - viertelstunden Interval und möchte diese nur überprüfen lassen auf Somme/Winterzeit. Leider habe ich noch keine, reibungslos funktionierende Lösung gefunden.

    Hier mein aktueller Code:

    Quellcode

    1. Sub ZeitU_SW2014()
    2. For Each c In Worksheets("Vorlage").Range("A17:A65536")
    3. If InStr(LCase(c.Value), "26.10.2014 02:00") Then
    4. Range(c, c.Offset(3, 0)).Select
    5. Selection.Copy
    6. Selection.Insert Shift:=xlDown
    7. End If
    8. Next
    9. End Sub


    Mein Problem ist, dass die For Each Schleife sich unzählige Male wiederholt und somit mehr als einmal der Vorgang des kopierens durchlaufen wird - Endlosschleife.

    Ich hoffe Ihr habt eine Lösung. Es soll einmal der Zeitstempel gefunden werden, dann die 4 Einträge, aus 4 Zellen kopiert werden, darunter direkt wieder, als neue Zellen eingefügt werden und Ende.

    Vielen Dank schon im Voraus!
    Schau mal nach als was "c" deffiniert ist.
    Ich gehe davon aus das es keine Endlosschleife ist sondern das er jede Celle in der Range absucht.

    Wenn es nur einmal ausgeführt werden soll warum machst du dann überhaupt ein For Each
    There is no CLOUD - just other people's computers

    Q: Why do JAVA developers wear glasses?
    A: Because they can't C#

    Daily prayer:
    "Dear Lord, grand me the strength not to kill any stupid people today and please grant me the ability to punch them in the face over standard TCP/IP."

    Danny schrieb:

    Es soll einmal der Zeitstempel gefunden werden

    Wie soll der Zeitstempel gefunden werden, wenn keine Zellen durchlaufen werden (du willst ja keine Schleife)?

    Danny schrieb:

    mehr als einmal der Vorgang des kopierens durchlaufen wird

    Dann gibt es wohl mehrere Zellen, die diesen Zeitstempel tragen. Wenn nur eins kopiert werden soll, dann mach nach dem Kopieren Exit For.

    Danny schrieb:

    For Each Schleife sich unzählige Male wiederholt

    Natürlich, das hast du doch selbst gesagt:

    Danny schrieb:

    Range("A17:A65536")

    Und zwar genau 65536-17=65519 Mal wiederholt.
    Oh mein Gott...da habe ich wirklich geschlafen. Der Hinweise mit dem "Exit For" war des Rätsels Lösung.

    Jetzt habe ich noch das Problem, der Selektion. Den Bereich, den er nun einmal eingefügt hat, bleibt selektiert. Habe es versucht durch eine Selektion einer anderen Zelle aber es bleibt. Habt Ihr dazu noch eine Lösung?

    Quellcode

    1. Sub ZeitU_SW2014()
    2. Dim c As Range
    3. For Each c In Worksheets("Vorlage").Range("A17:A65536")
    4. If InStr(LCase(c.Value), "26.10.2014 02:00") Then
    5. Range(c, c.Offset(3, 0)).Select
    6. Selection.Copy
    7. Selection.Insert Shift:=xlDown
    8. Cells(2, 2).Select
    9. Exit For
    10. End If
    11. Next
    12. End Sub


    Danke!
    Direkte Lösung: Mach vor dem End If ein Exit For
    Besser, vor allem schneller:

    Visual Basic-Quellcode

    1. Set c = ​Worksheets("Vorlage").Range("A:A").Find(CDate("26.10.2014 02:00"), LookIn:=xlFormulas)
    2. If Not c Is Nothing Then
    3. Set c = Range(c, c.Offset(3))
    4. Rows(c.Row & ":" & c.Row + 3).Insert xlDown
    5. c.Copy c.Offset(-4)
    6. End If
    Vielleicht solltest du die doppelten Zellen noch mit A und B markieren, damit du die Stunden auseinanderhalten kannst.

    P.S.: Wenn man intern mit UTC rechnet, gibt es weniger Probleme beim DST-Switch ;)
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hallo Petaod,

    leider klappt es mit deinem Code nicht. Er findet den Zeitstempel führt dann aber keinerlei Aktionen aus.

    Danke für deinen Tipp. Werde ich mir ansehen.

    Was mir noch aufgefallen ist, ich muss eine Prüfung machen. Die Möglichkeit besteht, dass der Anwender das Makro zweimal ausführt. Somit mache ich mir gerade gedanken, wie ich es sinnvoll anstelle. Da in diesem Fall der Zeitstempel dann 2 mal vorhanden sein muss, aber kein 3. mal vorkommen darf, scheint mir das eine Lösung zu sein. Wie seht ihr das?

    Danny schrieb:

    Er findet den Zeitstempel führt dann aber keinerlei Aktionen aus
    Wenn er den Zeitstempel findet, ist c <> Nothing und er läuft in die If-Bedingung rein, macht also auf jeden Fall was.
    Da ich dein Sheet und seine Formatierung nicht kenne, kann es schon sein, dass du den Find-Befehl noch etwas modifizieren musst.

    Danny schrieb:

    aber kein 3. mal vorkommen darf,
    dann prüfe ab ob c.Value<>c.Offset(4).Value ist.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hallo Zusammen,

    vielen Dank noch einmal für die gestrige Unterstützung. Ich habe soweit alles umgesetzt und es funktioniert. Eine kleine Problemstellung habe ich noch. Wenn ich das folgende Makro ausführe, erhalte ich für das SUB eine Fehlermeldung

    Objetvariable oder With-Blockvariable nicht festgelegt


    Hier der aktuelle Code, der diesen Fehler verursacht:

    Visual Basic-Quellcode

    1. Sub ZeitU_SW2014()
    2. Set c = Worksheets("Vorlage").Range("A:A").Find(CDate("26.10.2014 02:00"))
    3. If Not c Is Nothing And c.Value <> c.Offset(4, 0) Then
    4. Set c = Range(c, c.Offset(3, 0))
    5. Rows(c.Row & ":" & c.Row + 3).Insert xlDown
    6. c.Copy c.Offset(-4)
    7. End If
    8. End Sub


    Vielen Dank schon im Voraus für eure Hilfe.
    Du solltest dir angewöhnen, den Code im Debugger auszuführen, damit du genauere Angaben machen kannst, wo der Fehler auftritt.

    Falls sich dein Code in einem Modul befindet, kannst du nicht einfach Rows verwenden, sondern musst du die Rows-Collection noch auf das entsprechende Sheet mappen.

    Quellcode

    1. c.Worksheet.Rows(c.Row & ":" & c.Row + 3).Insert xlDown


    Deswegen verwende ich grundsätzlich den objektorientierten Ansatz und schreibe die Methoden in das Objekt, auf die sie sich beziehen.
    Im konkreten Fall gehört der Code in den Worksheet-Bereich von "Vorlage".
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --