Office: Manipulation des Schleifenzählers - gefährlich oder nicht?

Helfe beim Thema Manipulation des Schleifenzählers - gefährlich oder nicht? in Microsoft Excel Hilfe um das Problem gemeinsam zu lösen; Hallo, in einem anderen Thread bin ich darauf hingewiesen worden, dass es gefährlich wäre den Schleifenzähler während der Laufzeit der Schleife zu... Dieses Thema im Forum "Microsoft Excel Hilfe" wurde erstellt von fette Elfe, 16. Juni 2011.

  1. fette Elfe Erfahrener User

    Manipulation des Schleifenzählers - gefährlich oder nicht?


    Hallo,

    in einem anderen Thread bin ich darauf hingewiesen worden, dass es gefährlich wäre den Schleifenzähler während der Laufzeit der Schleife zu manipulieren.
    Wobei im dortigen Beispiel eigentlich nicht der Schleifenzähler sondern die Schleifenobergrenze vorgebende Variable manipuliert wurde.

    zu finden hier:
    http://www.office-hilfe.com/support/topic,16496,-daten-ordnen.html

    Im Prinzip genau das gleiche wie folgende Schleife:

    Code:
    Option Explicit
    
    Dim i As Integer
    Dim dingsbums As Integer
    
    Public Sub SchleifenTest()
        
        With ThisWorkbook.Worksheets(1)
            dingsbums = 10
            
            For i = 1 To dingsbums
                .Cells(i, 1) = "X"
                dingsbums = dingsbums - 1
            Next i
            
        End With
        
    End Sub

    Im ersten Moment hörte sich die Argumentation für mich logisch an.
    Inzwischen habe ich so meine Zweifel.

    Zum einen, weil ich obige Schleife mehrfach getestet habe und sie sauber bis 10 durchläuft und dann aussteigt.
    Egal was ich zwischenzeitlich mit der Variablen "dingsbums" anstelle.

    Zum anderen, weil auf unten aufgeführter Webseite auch explizit steht (etwa in der Mitte), dass diese Obergrenze nur einmal (am Anfang) initialisiert wird.
    http://www.online-excel.de/excel/singsel_vba.php?f=92



    Ob es guter Stil oder unüblich ist, interessiert mich hier erstmal nicht.
    Natürlich kann man es immer auch anders machen.

    Mich interessieren Eure Meinung, Tipps und vor allem Euer Wissen und Fakten:
    Ist es nun gefährlich oder nicht?
    Kann ich mir damit Probleme einhandeln?

    Beispiele und/oder Erklärungen wären natürlich klasse.


    Habt dank für Eure Zeit.
     
    fette Elfe, 16. Juni 2011
    #1
  2. Exl121150 Erfahrener User
    Hallo Achim!

    Code:
            Dim i As Integer 
            Dim dingsbums As Integer 
    
            dingsbums = 10 
            
            For i = 1 To dingsbums 
                .Cells(i, 1) = "X" 
                dingsbums = dingsbums - 1 
            Next i
    In den BASIC-Dialekten, die ich bisher kennenlernte (zB. BASICA, Q-BASIC, Quick-BASIC, Turbo-BASIC, VBA ) ist es tatsächlich so, dass der Schleifenkopf
    Code:
    For i = 1 To dingsbums
    nur 1x durchlaufen wird und zwar zu anfangs, bevor der Schleifenkörper
    Code:
    .Cells(i, 1) = "X" 
    dingsbums = dingsbums - 1 
    betreten wird. Daher läuft die Schleifenvariable "i" prinzipiell vom Startwert (hier 1) bis zum Endwert (hier: dingsbums=10) und zwar hier in Einser-Schritten (wegen Default: STEP 1).
    Das tut BASIC so, egal was man mit der Endwert-Variablen im Schleifenkörper anstellt. Das muss auch so sein, denn statt der Endwert-Variablen kann eine Konstante (hier zB. 10) stehen oder überhaupt ein komplizierterer arithmatischer Ausdruck (zB. 2*dingsbums-10). Beide können sich bei der Ausführung des Schleifenkörpers nicht mehr ändern. Das ist die harmlose Variante.

    Die etwas gefährlichere Variante ist, wenn man die Schleifenvariable (hier: i) im Schleifenkörper zu manipulieren versucht. Wenn ich hier zB. in den Schleifenkörper folgende Anweisung einfüge:
    Code:
    I = I-1
    ist unschwer zu erkennen, dass ich stolzer Besitzer einer Endlosschleife bin.

    Die ganz gefährliche Variante ist, wenn man aus dem Schleifenkörper, noch bevor die Schleifenvariable ihren Endwert erreicht hat, aus der Schleife (zB. mit einem GOTO-Statement) herausspringt, dann irgendwas ausführt und danach wieder in die Schleife hineinspringt (mit einem GOTO-Statement) ohne den Weg über den Schleifenkopf. Hier muss man schon ganz genau wissen, was man tut - ganz abgesehen davon, dass dies von allen (insbesondere Theoretikern) abgelehnt wird.

    Nachtrag zur letzten Variante:
    Man sollte eine FOR-Schleife prinzipiell nur über die von BASIC vorgesehenen Wege verlassen: entweder über das NEXT-Statement oder über ein EXIT-FOR-Statement. Der Grund ist ganz simpel. Sobald der Schleifenkopf zu anfangs durchlaufen wird, baut sich die Programmiersprache intern einen Datenstapel auf. Dieser wird wieder abgetragen, wenn man die Schleife über NEXT bzw. EXIT-FOR verlässt.
    Steigt man sonst wie aus - und tut man dies sehr häufig - kann es plötzlich aus heiterem Himmel meist an einer ganz anderen Stelle zu Speicherüberläufen kommen.
     
    Exl121150, 16. Juni 2011
    #2
  3. Kallewirsch Erfahrener User
    Hallo Achim,

    hier ein paar einfach Codes, an denen Du sehen kannst, was passiert.
    For-Next stört sich nicht an der Veränderung des Schleifenzählers, sondern läuft stur durch bis zum Ende. Der Rest hat da schon seine Probleme:

    Code:
    Option Explicit
    
    Sub test1()
    Dim loA As Long
    Dim loB As Long
    loB = 19
    For loA = 1 To loB
    loB = loB - 10
    Cells(loA, 1) = loA & "+" & loB
    Next
    
    
    End Sub
    Sub test2()
    Dim loA As Long
    Dim loB As Long
    loB = 19
    For loA = 1 To loB
    loB = loB + 10
    Cells(loA, 1) = loA & "+" & loB
    Next
    
    
    End Sub
    
    Sub test3()
    Dim loA As Long
    Dim loB As Long
    loB = 19
    loA = 1
    Do Until loA = loB
    loB = loB + 10
    Cells(loA, 1) = loA & "+" & loB
    loA = loA + 1
    Loop
    End Sub
    
    Sub test4()
    Dim loA As Long
    Dim loB As Long
    loB = 119
    loA = 1
    Do Until loA = loB
    loB = loB - 10
    Cells(loA, 1) = loA & "+" & loB
    loA = loA + 1
    Loop
    End Sub
    
    Sub test5()
    Dim loA As Long
    Dim loB As Long
    loB = 19
    loA = 1
    Do While loA < loB
    loB = loB + 10
    Cells(loA, 1) = loA & "+" & loB
    loA = loA + 3
    Loop
    End Sub
    
    Sub test6()
    Dim loA As Long
    Dim loB As Long
    loB = 119
    loA = 1
    Do While loA < loB
    loB = loB - 10
    Cells(loA, 1) = loA & "+" & loB
    loA = loA + 1
    Loop
    End Sub
    
    
    In der angehängten Datei ist auch Dein Makro hinter Tabelle2, dann siehst Du auch was es macht. In Spalte D sind Zahlen bis Zeile 200+


    Gruß

    Edgar
     
    Kallewirsch, 16. Juni 2011
    #3
  4. fette Elfe Erfahrener User

    Manipulation des Schleifenzählers - gefährlich oder nicht?

    Hallo Anton und Edgar,

    danke für die ausführliche und anschauliche Erklärung.

    Also bei "For Each" und "For Next" wird der Schleifenkopf nur am Anfang durchlaufen, der Endwert ist also festgesetzt und ändert sich nicht mehr.

    Bei "Do Loop" und "Do While" wird der Schleifenkopf bei jedem Durchgang wieder durchlaufen.
    Bei eine Manipulation muss man dann noch unterscheiden ob die Bedingung im Schleifenkopf, oder am Ende (nennt man das dann Schleifenfuß?) angegeben wird.


    Soweit richtig?

    D.H. meine Schleife die Edgar mir vorgeführt hat, erzielt zwar auf der einen Seite das gewünschte Ergebnis, macht obendrein aber auch noch unsinnige Sachen... ist also im Endeffekt falsch.

    Generell ist aber nichts gegen solche Manipulationen zu sagen, solange man genau aufpasst was man tut.


    soweit auch richtig?


    In angehängter Mappe habe ich einen kurzen Code um Doppelte in einer Liste zu finden und zu löschen.
    So wie ich das verstanden habe ist dagegen dann also nichts zu sagen...
    (Habe eine Austrittsbedingung eingefügt um nicht ins Leere zu laufen)
     
    fette Elfe, 17. Juni 2011
    #4
  5. Beverly
    Beverly Erfahrener User
    Hi Achim,

    beim Löschen von Zeilen macht es sich einfacher, wenn man die Schleife rückwärst laufen lässt - dann muss man die Schleifenvariablen nicht manipulieren:
    Code:
    Public Sub DoppelteEntfernen()
        
        With ThisWorkbook.Worksheets(1)
            
            ' letzte belegte Zelle in Spalte A
            loLetzte = IIf(IsEmpty(.Cells(.Rows.Count, 1)), .Cells(.Rows.Count, 1) _
                        .End(xlUp).Row, .Rows.Count)
            ' Vergleich beginnt ab Zeile 3
            For loZeile = loLetzte To 3 Step -1
                ' Vergleich ob Werte aus Spalte A & B in beiden Zeilen identisch sind
                If .Cells(loZeile - 1, 1) = .Cells(loZeile, 1) And _
                    .Cells(loZeile - 1, 2) = .Cells(loZeile, 2) Then
                    ' doppelter Eintrag wird gelöscht
                    .Range(.Cells(loZeile, 1), .Cells(loZeile, 2)).Delete Shift:=xlUp
                End If
            Next loZeile
            
        End With
    End Sub
    
    Bis später,
    Karin
     
    Beverly, 17. Juni 2011
    #5
  6. fette Elfe Erfahrener User
    Hallo Beverly,

    wenn ich meinen Code so mit Deinem vergleiche kommt mir nur eins in den Sinn:

    Warum einfach wenns auch kompliziert geht?
    :roll: Manipulation des Schleifenzählers - gefährlich oder nicht? :oops:

    Danke für den Tipp.
     
    fette Elfe, 17. Juni 2011
    #6
Thema:

Manipulation des Schleifenzählers - gefährlich oder nicht?

Die Seite wird geladen...
  1. Manipulation des Schleifenzählers - gefährlich oder nicht? - Similar Threads - Manipulation Schleifenzählers gefährlich

  2. Manipulation des Datums mit DateAdd-Funktion ?

    in Microsoft Word Hilfe
    Manipulation des Datums mit DateAdd-Funktion ?: Hallo, Ich würde gerne in mein Word-Dokument ein Datum einfügen, das dem aktuellen Datum 7 Tage voraus ist. In einigen Forumsbeiträgen habe ich dafür leider nur Hinweise gefunden und versucht...
  3. Frachtpreis Berechnung nach gefahrenen Kilometern

    in Microsoft Excel Hilfe
    Frachtpreis Berechnung nach gefahrenen Kilometern: Hallo zusammen, könnte mir bitte jemand helfen. Welche Formel muss ich einfügen um einen Frachtpreis X aus Postleitzahlengebiet 1 oder 2 oder 3 in Deutschland nach Postzahlengebiet 00 in...
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Auf dieser Website werden Cookies für die Zugriffsanalyse und Anzeigenmessung verwendet.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden