2016-08-02 19 views
2

次のコードが「想定されている」ときに終了しない理由を理解できません。どんな助けもありがたい。問題は、親Do Whileの値がRFになるとループが終了しないことです。VBA内のNest Do Whileループが終了しない

これを完全に間違って設定しましたか?あまりにもVBAに精通していない、と私は非常に錆びているので、数年後に任意の言語でプログラムを書いていない。

ありがとうございました!


私が働いていたいくつかのコードを編集した
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 

注意/手元の問題に関係しません。

はい、私には1トンの変数があります。おそらく私がやろうとしていることをコード化する方がはるかに簡単な方法があることを知っています。

+0

終了条件を操作しているので外部ループの条件が一致する場合は、内部ループをチェックインする必要があります – lokusking

+0

コードにロジックホールがあります。内側ループ内のすべてのif条件が満たされると、RFは減少しないので、外側ループは無限にループします。 –

+0

これは当てはまりませんが、外側のループは無限ではありません。 – Mono

答えて

2

エリック私は右のあなたを理解していれば、あなたはRFが陽性であれば内側のループに入るためにのみ願いの実行を行います。これを行う簡単な方法の1つは、その要件をすべての内部ループに明示的に追加することです。第1の内側ループは、例えば、

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

あなたは他の三つの内側のループと同様の編集を行う場合、私はあなたがそれを意図し考えると、それはうまくいくかもしれない。そして、このように起動に見えます。 よろしく、 Mats

+0

私はその感謝を試みます!私はベッドに行き、ネストされたループが実際には最善のルートではないことに気づいた – Eric

0

まずは、外側ループが終了します。ただし、コード内のそれぞれの「ループ」ポイントに到達する場合に限ります。したがって、RFは負になり、内側のループはすべて外側のループが次の「ラウンド」の条件をチェックする前に終了します。そのラインを除き

MsgBox "a20 " & RF > 0 

あなたのコードをコンパイルして実行が、そうでないかもしれない、あなたが期待するようになります。だからあなたのコードがうまくいかない理由を尋ねるのではなく、あなたが正確に達成したいことを説明するべきでしょう。

+0

これを半分眠らせようとしていましたが、今朝より明確なアプローチをとっていますが、ありがとうございます。 – Eric

4

あなたはRFに等しいか0少ないしているかどうかを確認するために、それぞれの新しいDo While前にチェックして置く必要があり、その処理しながら、ループを停止する場合:

if RF <= 0 then exit Do 
+0

これはうまくいきましたが、ネストされたループは実際にはこの問題に対する最良のアプローチではなく、より目を覚ました後に別のルートに進んでいることに気付きました! – Eric

2

DragonSamuが正しいです。各内部ループの前にif RF <= 0 then exit Doを追加する必要があります。

  • ながら行います。条件はまで
  • ループを満たしている場合は、ループを開始します:条件になるまでループを再起動します
ここ

を満たしている私が処理するためにFunction TransferFundsを作成内部ループ。 TransferFundsのパラメータは、ByRefを使用して元の変数をメインコードから変更します。

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

ありがとう!私はチャンスを得るときにあなたのコードをチェックアウトします。 – Eric

関連する問題