2016-08-02 3 views
2

Kann nicht herausfinden, warum der folgende Code nicht beendet wird, wenn es "angenommen" wird. Jede Hilfe wird geschätzt. Das Problem ist die Eltern Do While Schleife endet nicht die Schleife, sobald der Wert RF 0 erreicht.Nest Do While-Schleife in VBA endet nicht

Habe ich das komplett falsch eingerichtet? Nicht vertraut mit VBA, und habe in ein paar Jahren kein Programm in irgendeiner Sprache geschrieben, also bin ich sehr eingerostet.

Vielen Dank im Voraus für jede Einsicht!


Private Sub CalculateButton_Click() 
'Assigning Variables 
Dim cid As Currency 
Dim tip As Currency 
Dim cha As Currency 
Dim A1 As Currency 
Dim R1 As Currency 
Dim B1 As Boolean 
Dim A5 As Currency 
Dim R5 As Currency 
Dim B5 As Boolean 
Dim A10 As Currency 
Dim R10 As Currency 
Dim B10 As Boolean 
Dim A20 As Currency 
Dim R20 As Currency 
Dim B20 As Boolean 
Dim A50 As Currency 
Dim R50 As Currency 
Dim A100 As Currency 
Dim R100 As Currency 
Dim B100 As Boolean 
Dim tipCalc As Double 
Dim RF As Currency  

'Setting Boolean as false 
B1 = False 
B5 = False 
B10 = False 
B20 = False 
B100 = False 

'Setting Variables values 
cid = 587.87 
tip = 16 
cha = 13 
A1 = 36 
R1 = 0 
A5 = 85 
R5 = 0 
A10 = 50 
R10 = 0 
A20 = 420 
R20 = 0 
A50 = 0 
R50 = 0 
A100 = 0 
R100 = 0 
RF = 175 
If A1 + A5 + A10 + A20 + A50 + A100 < RF Then 
    MsgBox "Not Enough Money In Register" 
    Exit Sub 
End If 


'Grabbing decimal from CID to calculate tip rounding next 
tipCalc = cid - Int(cid) 

'Calculating tip and entering into the excel sheet 
'Removed for simplification 

RF = RF - cha 

Do While RF > 0 
    Do While B1 = False 'This is for the 1 dollar bills 
     If CheckWhole(RF, 5) And A1 < 5 Then 
      B1 = True 
      MsgBox "1 dollar done " & RF 

     Else 
      RF = RF - 1 
      A1 = A1 - 1 
      R1 = R1 + 1 
     End If 
    Loop 
    MsgBox RF > 0 
    Do While B5 = False '5 dollar bills 
     If CheckWhole(RF, 10) And A5 < 10 Then 
      B5 = True 
      MsgBox "5 dollar done " & RF 
     Else 
      RF = RF - 5 
      A5 = A5 - 5 
      R5 = R5 + 5 
     End If 
    Loop 
    MsgBox RF > 0 
    Do While B10 = False '10 dollar bills 
     If CheckWhole(RF, 20) And A10 < 20 Then 
      B10 = True 
      MsgBox "10 dollar done " & RF 
     Else 
      RF = RF - 10 
      A10 = A10 - 10 
      R10 = R10 + 10 
     End If 
    Loop 
    MsgBox RF > 0 
    Do While B20 = False '20 dollar bills 
     If CheckWhole(RF, 100) And A20 < 100 Then 
      B20 = True 
      MsgBox "20 dollar done " & RF 
     Else 
      RF = RF - 20 
      A20 = A20 - 20 
      R20 = R20 + 20 
      MsgBox "20 dollar working " & RF 
     End If 
    Loop 
    MsgBox "a20 " & RF > 0 

Loop 
'Output goes here, inputs data into cells on spreadsheet. 



End Sub 

Function CheckWhole(x As Currency, y As Currency) As Boolean 
    If Int(x/y) = (x/y) Then 
     CheckWhole = True 
    Else 
     CheckWhole = False 
    End If 
End Function 

Bitte beachte, dass ich einige Code herausgeschnitten, die Arbeit wurde/gehört nicht zur Hand zu diesem Thema.

Und ja, ich habe eine Tonne Variablen. Ich weiß, dass es wahrscheinlich einen viel einfacheren Weg gibt, zu programmieren, was ich versuche zu tun.

+0

Sie sollten Ihre inneren Schleifen einchecken, wenn die Bedingung der äußeren Schleife übereinstimmt, da Sie ihre Beendigungsbedingung bearbeiten – lokusking

+0

Es gibt eine logische Lücke in Ihrem Code. Wenn alle if-Bedingungen innerhalb der inneren Schleifen erfüllt sind, dekrementiert RF nicht, so dass die äußere Schleife unendlich weiterläuft. –

+0

Nein, das ist nicht wahr, die äußere Schleife ist nicht unendlich. – Mono

Antwort

2

Eric, wenn ich Sie richtig verstehe, Sie nur Ausführung Wunsch in die inneren Schleifen zu bekommen, wenn RF-positiv ist. Eine einfache Möglichkeit besteht darin, diese Anforderung explizit allen inneren Schleifen hinzuzufügen. Die erste innere Schleife würde z.B. aussehen beginnt wie diese dann:

Do While RF > 0 And B1 = False'This is for the 1 dollar bills 

Wenn Sie zu den drei anderen inneren Schleifen ähnliche Bearbeitungen tun könnte es funktionieren, wie ich glaube, Sie beabsichtigen, es zu. Grüsse, Mats

+0

Ich werde das versuchen danke! Ich ging ins Bett und stellte fest, dass eine verschachtelte Schleife nicht wirklich die beste Route war – Eric

0

vor allem. Der äußere Loop wird beendet. Aber nur wenn es den jeweiligen "Loop" -Punkt im Code erreicht. RF wird also negativ und die inneren Schleifen werden alle enden, bevor die äußere Schleife die Bedingung für die nächste "Runde" prüft.

Mit Ausnahme dieser Linie:

MsgBox "a20 " & RF > 0 

Ihr Code wird kompiliert und ausgeführt werden, aber vielleicht nicht wie erwartet. Anstatt zu fragen, warum Ihr Code nicht funktioniert, sollten Sie wahrscheinlich auch erklären, was Sie genau erreichen wollen.

+0

Hat versucht, dies im Halbschlaf zu tun, habe heute Morgen einen klareren Zugang, danke trotzdem. – Eric

4

Wenn Sie die Schleife stoppen, während die Verarbeitung Sie in einer Kontrolle vor jeder neuen Do While setzen müssen, um zu überprüfen, ob RF gleich oder weniger als 0:

if RF <= 0 then exit Do 
+0

Danke, das würde funktionieren, aber ich erkannte, dass eine verschachtelte Schleife nicht wirklich die beste Lösung für dieses Problem ist. – Eric

2

DragonSamu korrekt ist; Sie sollten if RF <= 0 then exit Do vor jeder inneren Schleife hinzufügen.

  • Do While: die Schleife beginnen, wenn eine Bedingung
  • Loop trifft Bis: wird die Schleife, bis eine Bedingung neu starten wird treffen

Hier hat ich ein Function TransferFunds die zu handhaben innere Schleifen. Die Parameter in TransferFunds verwenden ByRef, um die ursprüngliche Variable aus dem Hauptcode zu ändern.

enter image description here

Sub CheckRegister() 
    Dim A1 As Currency, A5 As Currency, A10 As Currency, A20 As Currency, A50 As Currency, A100 As Currency 
    Dim R1 As Currency, R5 As Currency, R10 As Currency, R20 As Currency, R50 As Currency, R100 As Currency 
    Dim rf As Currency 

    A1 = 36 
    A5 = 85 
    A10 = 50 
    A20 = 420 
    A100 = 0 
    rf = 175 

    TransferFunds rf, R1, A1, 1 
    TransferFunds rf, R5, A5, 5 
    TransferFunds rf, R10, A10, 10 
    TransferFunds rf, R20, A20, 20 
    TransferFunds rf, R50, A50, 50 
    TransferFunds rf, R100, A100, 100 

    RefundMessage "Refund Due", R1, "Ones", R5, "Fives", R10, "Tens", R20, "Twenties", R50, "Fifties", R100, "Hundreds" 
    RefundMessage "Remaining Register", A1, "Ones", A5, "Fives", A10, "Tens", A20, "Twenties", A50, "Fifties", A100, "Hundreds" 

End Sub 

Sub TransferFunds(ByRef rf As Currency, ByRef RValue, ByRef AValue As Currency, Denomination As Integer) 
    Dim RefundAmount As Currency 

    If rf > AValue Then 
     RValue = AValue 
    Else 
     RValue = RValue Mod Denomination 
    End If 

    AValue = AValue - RValue 
    rf = rf - RValue 

End Sub 

Sub RefundMessage(Title As String, ParamArray arValuePairs() As Variant) 
    Dim msg As String, Denomination As String 
    Dim i As Integer, cValue As Currency 

    For i = 0 To UBound(arValuePairs) Step 2 
     cValue = arValuePairs(i) 
     Denomination = arValuePairs(i + 1) 
     If cValue > 0 Then 
      msg = msg & FormatCurrency(cValue, 2) & " in " & Denomination & vbCrLf 
     End If 

    Next 

    MsgBox msg, vbInformation, "Refund Due" 
End Sub 
+0

Danke! Ich überprüfe deinen Code, wenn ich eine Chance bekomme. – Eric