1. Liebe Forumsgemeinde,

    aufgrund der Bestimmungen, die sich aus der DSGVO ergeben, müssten umfangreiche Anpassungen am Forum vorgenommen werden, die sich für uns nicht wirtschaftlich abbilden lassen. Daher haben wir uns entschlossen, das Forum in seiner aktuellen Form zu archivieren und online bereit zu stellen, jedoch keine Neuanmeldungen oder neuen Kommentare mehr zuzulassen. So ist sichergestellt, dass das gesammelte Wissen nicht verloren geht, und wir die Seite dennoch DSGVO-konform zur Verfügung stellen können.
    Dies wird in den nächsten Tagen umgesetzt.

    Ich danke allen, die sich in den letzten Jahren für Hilfesuchende und auch für das Forum selbst engagiert haben. Ich bin weiterhin für euch erreichbar unter tti(bei)pcwelt.de.
    Dismiss Notice

[VBA] Schleife beenden

Discussion in 'Office-Programme' started by Tiffiklotz, Apr 26, 2013.

Thread Status:
Not open for further replies.
  1. Tiffiklotz

    Tiffiklotz Byte

    Hallo,

    ich versuche seit langem mal wieder ein kleines VBA Skript zu schreiben. Mein Ziel ist folgendes:

    Es gibt eine Variable "x"
    Von dieser Variable sind zwei Werte "A" und "B" abhängig (A und B berechne ich in Excel über eine Formel in der Zelle).
    Über ein Sub soll "x" so lange variiert werden, bis "A" ungefähr gleich "B"
    (Eine Abweichung von 1 lasse ich zu)
    Über die Zielwertsuche habe ich es nicht hinbekommen, da A und B beide von "x" abhängig sind.

    Meine VBA-Versuche sehen wie folgt aus:

    Ja, die Iterationsschritte sollen so klein sein, da die Formeln für A und B sehr sensibel sind :)
    Wenn ich die Schleife starte, dann hört er nicht mehr auf - auch wenn offensichtlich zwischenzeitlich A = B
    (ich habe auch schon eine größere Differenz zugelassen, gleiches Problem)

    Wenn mir jemand helfen könnte, wäre ich sehr dankbar! :)
     
    Last edited: Apr 26, 2013
  2. Eric March

    Eric March CD-R 80

    Ich würde mal so gaaanz auf die schnelle sagen, dass das «Differenz = Abs(A - B)» sich innerhalb der Do-Loop-Schleife recht wohl fühlen würde :)
    Die Schleife reagiert ja so immer auf den vorher einmal ermittelten Wert der sich ja nie mehr ändert.

    Eric March
     
  3. Hascheff

    Hascheff Moderator

    Die Differenz muss in der Schleife auch mal neu berechnet werden!
     
  4. Tiffiklotz

    Tiffiklotz Byte

    Hört sich für mich logisch an, führt aber zum selbsen Ergebnis --> Endlosschleife
    Ich habe selbst eine ganze Weile nachgeforscht und bin zu keinem brauchbaren Erbenis gekommen.

    Die bisher einfachste Möglichkeit für mich ist, das "x" zu raten.
    Aber das muss im 21. Jahrhundert anders gehen behaupte ich! :D
     
  5. Urs2

    Urs2 Megabyte

    Hallo Matthias

    Immer noch am Studieren?

    Code:
    Do
        Differenz = Abs(A - B)
        x = x + 0.000001
        Cells(88, 3).Value = x
    Loop Until Differenz < 1
    
    So berechnest Du die Differenz in jedem Durchgang... immer wieder gleich !
    A und B wurden ja vor der Schleife definitiv festgelegt...

    Ich würde es so machen >>>
    Code:
    Do
        x = x + 0.000001
        Cells(88, 3).Value = x
        Differenz = Abs(Cells(89, 3) - Cells(90, 3))
    Loop Until Differenz < 1
    
    VBA ist schnell, Excel ist auch schnell - zusammen sind sie mit der Hin- und Herschreiberei aber ziemlich langsam.
    Wobei sogar passieren könnte, dass VBA die Werte A und B zurückholen will, bevor Excel sie berechnet hat...

    Kannst Du nicht den Wert x aus dem Blatt holen...
    ... und dann in der Schleife mit den beiden Formeln (die jetzt im Blatt sind) A und B immer neu berechnen.
    >>> Erst nach Beendigung der Schleife die finalen x, A und B ins Blatt schreiben.

    Auch bei sehr vielen Iterationen wäre das sehr schnell.

    Gruss Urs
     
  6. Eric March

    Eric March CD-R 80

    :aua:
    Gott, kann die Leitung lang sein. Da habe ich, flott-flott, glatt &#8250;die Hälfte&#8249; übersehen&#8230; :bet:

    Eric March
     
  7. Hascheff

    Hascheff Moderator

    Nein, nein, du hast ja eigentlich den gleichen Hinweis gegeben. Der Fehler lag bei mir, der Thread wird wohl eine Stunde in der Warteschleife gelegen haben und ich habe nach dem Antworten wohl nicht mehr kontrolliert, was dazwischen gelaufen ist.

    Ich denke, der TO wird mit Urs' Antwort zufrieden gewesen sein. Aber falls er noch mal reinschaut:

    @ TO:
    Beim nächsten Mal probiere doch mal den Debug-Modus aus. Da kannst du die (Nicht-)änderung von Werten überwachen und so der Ursache selbst auf die Spur kommen.

    Am linken Rand des Editorfensters ist eine Leiste, in die du klicken musst. So erzeugst du einen Haltepunkt. Wenn die Prozedur aufgerufen wird, kommst du ins Editorfenster, wenn der Haltepunkt erreicht wird. Sitzt der Haltepunkt in der Schleife, kannst du nach jedem Durchlauf die Werte kontrollieren. Du kannst in Excel-Zellen schauen oder im Editorfenster mit der Maus über eine Variable gehen.
    Man kann auch für die Überwachung der Variablen ein eigenes Fenster anzeigen lassen.
    Über das Menü "Ansicht" lässt sich auch die Debug-Symbolleiste anzeigen. Die hilft dir, die Prozedur Zeile für Zeile in Einzelschritten laufen zu lassen.
     
  8. Tiffiklotz

    Tiffiklotz Byte

    Hallo Urs,

    ja, ich bin immernoch am Studieren. Bei unserem letzten "Zusammentreffen" musste ich eine Hausarbeit mit VBA erstellen, du erinnerst dich sicherlich gut ...
    Inzwischen bin ich kurz vor meinem zweiten Abschluss (Master) und programmiere mir eine umfangreichere Hausarbeit in Excel. Da ich dort sehr viele Eingangswerte immer wieder ändern muss, versuche ich mir das leben mit automatisierten Interpolationen und VBA etwas einfacher zu machen ;)
    Bei der DO-Schleife hörte dann mein eingerostetes Grundlagenwissen auch wieder auf. Deine Erklärung ist aber idiotensicher und deine Lösung funktioniert perfekt!

    Vielen Dank!
     
  9. Urs2

    Urs2 Megabyte

    Hallo Matthias

    Also weiterhin viel Vergnügen beim Studieren, nachher wird es wohl weniger vergnüglich werden.

    Idiotensicher? So kurz ist diese Iteration, nun doch nicht... wenn sie immer funktionieren soll.
    Ich wollte Dich nur nicht verschrecken, bevor das Ding wenigstens manchmal läuft >>>

    1. Der Ausgangswert x kann schon der richtige Wert für Differenz <1 sein >>>
    >>> durch puren Zufall, aber immer wenn das Makro vorher schon einmal oder allenfalls mehrmals darüber gelaufen ist.
    Bei der ersten Iteration könnte das x dann überschiessen zu Diff >1 ... und in eine Endlosschleife gehen.
    Deshalb solltest Du, mit dem jetzigen Code, nach dem Auslesen von x aus dem Blatt, aber vor dem Do/Loop, diese Zeile einfügen >>>
    x = x - 0.000001
    ... so wird Differenz im ersten Durchgang dann sicher <1 und die Schleife wird sofort beendet.


    2. Bei solchen Dingern sollte man immer eine maximale Anzahl der Iterationen festlegen, man weiss/bedenkt vorher nicht immer alles.
    Innerhalb der Schleife diese Zeilen einfügen >>>
    Code:
    numIter = numIter + 1
    If numIter >100 Then				'oder >50, >500... was auch immer vernünftig ist			
    	Cells(88, 3) = "Mist"			'oder sonst eine Bemerkung irgendwo im Blatt
    	Exit Do
    End If
    ... das soll Dir nur anzeigen, dass wohl ein Fehler in Deiner Iteration ist...


    3. Ist es gottgegeben, dass das ursprüngliche x immer kleiner und nie grösser als das ideale x ist ?
    Wenn Du nicht absolut sicher bist, musst Du das zuerst prüfen, direkt nach dem Auslesen der Werte x, A und B
    - vielleicht reicht dazu schon das Abklären, ob Differnz ohne Abs(Differenz) im Minus oder im Plus ist.
    - dann muss in der Iteration x entweder vergrössert ODER verkleinert werden.


    Nur keine Angst, mit den heutigen Prozessoren sind solche Zusatzzeilen belanglos...

    Gruss Urs
     
  10. Tiffiklotz

    Tiffiklotz Byte

    Hallo Urs,

    ich werde es mir merken, aber momentan funktioniert alles super für meine Zwecke und daher werde ich es so lassen! ;)
    Das makro funktioniert nun so:
    "Setze x zu null und erhöhe es dann schrittweise, biss die Differenz kleiner 1 ist"

    Dadurch, dass im ersten Schritt x zu null gesetzt wird, muss ich nur "aufwärts iterieren" :)

    Nochmals vielen Dank.
    VBA ist doch komfortabler als x durch Raten herauszufinden ;)
     
  11. Urs2

    Urs2 Megabyte

    Hallo Matthias

    Gut so, das Abwärtsproblem ist erschlagen... wenn das ideale x nie 0 sein kann.
    Sonst müsstest Du das Start-x auf -0.000001 setzen.

    Es ist Dein Code, aber für mich würde ich, nur für die Test-Phase, den KO-Zähler trotzdem einbauen...

    Gruss Urs
     
  12. Hascheff

    Hascheff Moderator

    Ich hätte mir eine kurze Rückmeldung gewünscht, ob du #7 gelesen hast.
     
  13. Tiffiklotz

    Tiffiklotz Byte

    Habe #7 gelesen und mal getestet. Bei meinem nächsten VBA Problem versuche ich es so zu lösen. In diesem Zusammenhang ist es dank der Hilfe von Urs nicht mehr notwendig.
    @Urs: Ja, x ist definitiv immer größer als Null. :)
     
  14. chipchap

    chipchap Ganzes Gigabyte

    Auch wenn es schon etwas her ist:
    Erste Regel der VB(A)-Programmierung:
    Um eine Endlosschleife in VB(A) zu vermeiden gehört in JEDE DO-WHILE-Routine ein DO EVENTS.
     
Thread Status:
Not open for further replies.

Share This Page