I have a problem with the do until loop. The first test code below (code1) works well. However, if I put the part following the "Then" in a new row, as shown in the second code (as I plan to add more commands after the "Then" later), it returns the error message "Loop without do". The working code (code1) is:
Sub CopyValues()
Dim s As Integer
Dim r As Integer
Cells(2, 4).Value = "Before"
Cells(2, 5).Value = "After"
For r = 1 To 3
s = 0
Do
s = s + 1
If InStr(Cells(s, 2).Value, "ROI_" & r & "A") > 0 Then Cells(Rows.Count, 4).End(xlUp).Offset(1, 0) = Cells(s, 2).Value
Loop Until InStr(Cells(s, 2).Value, "ROI_" & r & "A") > 0
Next r
End Sub
The not working code (code2) is this:
Sub CopyValues()
Dim s As Integer
Dim r As Integer
Cells(2, 4).Value = "Before"
Cells(2, 5).Value = "After"
For r = 1 To 3
s = 0
Do
s = s + 1
If InStr(Cells(s, 2).Value, "ROI_" & r & "A") > 0 Then
Cells(Rows.Count, 4).End(xlUp).Offset(1, 0) = Cells(s, 2).Value
Loop Until InStr(Cells(s, 2).Value, "ROI_" & r & "A") > 0
Next r
End Sub
Kind Regards Ferenc
Even if the error message you get is "loop without do", the error is actually about your If-statement that requires a separate line with End If
after the command(s) you want to be executed within your If-statement.
When markers like this are missing, you'll often get an error message that does not represent what is the actual error, so keep an eye open for those missing ending elements (End If
, Next
, Loop
, etc.) when debugging!
As a complement, here's a discussion about the one-line version vs multiple-line version of the If-statement:
End If
at the end:If Condition Then Do_Something End If
End If
at the end: If Condition Then Do_Something
Which one to choose is a matter of preferences. In a case with only one statement to execute, it can seem appropriate to use the one-line version because it makes it neater.
However, the muliple-line version remains more flexible. For example, imagine that, down the road, you realize that you need your If-Statement to execute more statements, you'll have to switch back to the multiple-line version*. Furthermore, to incorporate Else
or ElseIf
in your code to execute something when the condition returns false, you'll also need the multiple line version** (More details here).
If Condition Then Do_Something Do_Another_Thing End If
If Condition Then Do_Something: Do_Another_Thing
In this case, the reason why I'm saying you should probably avoid using the one-line version is because it becomes quite hard to read and not everyone is familiar with the use of the colon(:) to put more than one statement on the same line (More details here)
Footnotes:
*: As explained in Part 2, you wouldn't have to switch absolutely, but that would be highly recommended.
**: You actually could write the Else
on the same line using
If Condition Then Do_Something Else Do_Something_Else
, but I would not encourage it for readability reasons.