Do ループと Do...While ループ

繰り返しブロックステートメント Do は、指定された条件が true の間、または条件が true になるまで、ステートメントのブロックを繰り返し実行します。ステートメントのブロックは、終了条件が満たされない場合にのみ無限に実行されます。

条件があるかどうか、条件がステートメント内のどこにあるかによって、3 種類の異なる Do ステートメントがあります。条件がまったくない場合も、While 句または Until 句を使用して、最初または最後で指定される場合もあります。

構文は次のとおりです。

次の例は、最初の形式の Do ステートメントを示します。Do ループは、If ステートメントが満たされるまで繰り返されます。While 句や Until 句のないこのような Do ステートメントには、Exit ステートメントか End ステートメント、または Do ステートメントの外に制御を出すその他のステートメント (GoTo など) が含まれている必要があります。含まれていない場合、ループは無限に実行されます。

doCount% = 0
Do
   doCount% = doCount% + 1
   If doCount% >= 1000 Then Exit Do
Loop

次の例では、各 Do ステートメントは前の例の Do ステートメントと同等です。

Dim doCount As Integer
' A Do While statement (condition at the beginning)
doCount% = 0
Do While doCount% < 1000
   doCount% = doCount% + 1
Loop
' A Do Until statement (condition at the beginning)
doCount% = 0
Do Until doCount% >= 1000
   doCount% = doCount% + 1
Loop
' A Do...Loop While statement (condition at the end)
doCount% = 0
Do
   doCount% = doCount% + 1
Loop While doCount% < 1000
' A Do...Loop Until statement (condition at the end)
doCount% = 0
Do
   doCount% = doCount% + 1
Loop Until doCount% > 1000

条件がループの最初の繰り返しの前で検査されるか、後で検査されるかという点で、Do ステートメントの形式が異なります。Do While または Do Until 条件ステートメントにある条件は最初の繰り返しの前に検査されますが、Do...Loop While または Do...Loop Until 条件ステートメントにある条件は、最初の繰り返しの後まで検査されません。この結果次のようになります。

次の例は、この違いを示します。

Dim doCount As Integer
doCount% = 1
Do While doCount% < 1
   doCount% = doCount% + 1
Loop
Print "Do While...Loop counter reached" doCount%
doCount% = 1
Do
    doCount% = doCount% + 1
Loop While doCount% < 1
Print "Do...Loop While counter reached" doCount%
' Output:
' Do While...Loop counter reached  1
' Do...Loop While counter reached  2

Do ステートメントは、ステートメント内の変数ごとに別のスコープを設定しません。While condition 句または Until condition 句で使用される変数は、スクリプトの他の変数と同様です。前に変数が使用されていない場合、condition に現れた時点で暗黙的に宣言され、初期化されます。

以下に例を示します。

' Suppose that the variable named doCount%
' has not appeared in a script prior to its appearance here.
Do While doCount% < 1
   doCount% = doCount% + 1
Loop
Print "Do While...Loop counter reached" doCount%
' Output:
' Do While...Loop counter reached  1

LotusScript® は、doCount% を暗黙のうちに宣言し、ゼロに初期化します。このため、ループの本体は 1 回実行されます。しかし、この初期化に頼るのは危険なプログラミング手法です。実行時において以前に doCount% が現れていないこと、または doCount% の現在値がゼロであることを確認することなく、この動作に頼ることはできません。

次の例では Do ステートメントは、極限値に収束する数列の連続する項を計算します。

' This sub computes the quotient of each successive pair of
' terms of the Fibonacci sequence 1, 1, 2, 3, 5, 8, 13, ...
' The sequence of quotients 2, 3/2, 5/3, ... is known to
' converge to the golden mean (1 + Sqr(5))/2.
' The sub argument deltaLim! is the tolerance.
' This example illustrates the Do...Loop Until form of the
' Do statement, with a condition that is recomputed on each
' iteration.
Sub FibiLim (deltaLim As Single)
   Dim r1 As Single, r2 As Single, r3 As Single
   Dim limTrue As Single      
   Dim i As Integer
   ' Initialize the Fibonacci numbers and a counter.
   r1! = 1
   r2! = 1
   r3! = 1
   i% = 2
   Do
   NexTerm:
      i% = i% + 1
      r1! = r2!
      r2! = r3!
      ' r3! is the next Fibonacci number.
      r3! = r2! + r1!
      Print i%, "f(" & Str(i%) & "):" r3!, "quotient: " _
         r3!/ r2!
      ' On the first iteration, disable the standard exit 
      ' condition.
      If i% = 3 GoTo NexTerm
      ' Iterate until successive quotients are close.
      ' The sequence is known to converge, so the iteration
      ' will end. 
   Loop Until Abs(r3! / r2! - r2! / r1!) < deltaLim!
   limTrue! = (1 + Sqr (5)) / 2
   ' When done, show the closeness obtained and the actual
   ' limit.
   Print "Tolerance:" deltaLim!
   Print "Difference:" CSng(Abs(r3! / r2! - limTrue!)), _
      "(Actual limit:" limTrue!")"
End Sub
' Call FibiLim with a tolerance argument.
Call FibiLim(.005)
' Output:
' 3           f(3): 2       quotient:  2
' 4           f(4): 3       quotient:  1.5
' 5           f(5): 5       quotient:  1.66666666666667
' 6           f(6): 8       quotient:  1.6
' 7           f(7): 13      quotient:  1.625
' 8           f(8): 21      quotient:  1.61538461538462
' 9           f(9): 34      quotient:  1.61904761904762
' Tolerance: .005   Difference: 1.013614E-03  
' (Actual limit: 1.618034)