Выдает ошибку «Loop without Do» хотя Do есть |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
I’m trying to implement a simple Newton’s method iterative solver using Excel VB (I have never used VB.)
I keep getting the error loop without a Do
and I can’t figure out what I’m doing wrong here.
I’m trying to find the roots of the function z^3 - z^2 - (B^2 + B - A)z - A*B
called the compressibility factor.
My source MSN
Function zCalculation(ByVal temp As Double, ByVal press As Double) As Double
Dim tempCr As Double
Dim pressCr As Double
Dim A As Double
Dim B As Double
tempCr = temp / 238.5
pressCr = press / 547.424092
A = pressCr / tempCr
A = A / (9 * (2 ^ (1 / 3) - 1))
B = pressCr / tempCr
B = B * (2 ^ (1 / 3) - 1) / 3
Dim zNot As Double
Dim counter As Integer
counter = 0
zNot = 1#
Do
counter = counter + 1
zNot = zNot - (zNot ^ 3 - zNot ^ 2 - (B ^ 2 + B - A) * zNot - A * B) / (3 * zNot ^ 2 - 2 * zNot - (B ^ 2 + B - A))
If counter > 1000 Then
Exit Do
Loop Until eval(zNot, A, B) < 0.000001
zCalculation = zNot
End Function
break
Function eval(ByVal z As Double, ByVal A As Double, ByVal B As Double) As Double
eval = z ^ 3 - z ^ 2 - (B ^ 2 + B - A) * z - A * B
End Function
asked Dec 9, 2013 at 16:58
Felix CastorFelix Castor
1,6001 gold badge18 silver badges39 bronze badges
You need an:
End If
in your code.
answered Dec 9, 2013 at 17:04
Gary’s StudentGary’s Student
95.8k10 gold badges59 silver badges99 bronze badges
2
You can try:
Function zCalculation(ByVal temp As Double, ByVal press As Double) As Double
Dim tempCr As Double
Dim pressCr As Double
Dim A As Double
Dim B As Double
tempCr = temp / 238.5
pressCr = press / 0.546789
A = pressCr / tempCr
A = A / (9 * (2 ^ (1 / 3) - 1))
B = pressCr / tempCr
B = B * (2 ^ (1 / 3) - 1) / 3
Dim zNot As Double
Dim counter As Integer
counter = 0
zNot = 1#
Do
counter = counter + 1
zNot = zNot - (zNot ^ 3 + zNot ^ 2 - (B ^ 2 + B - A) * zNot - A * B) / (3 * zNot ^ 2 + 2 * zNot - (B ^ 2 + B - A))
If counter > 1000 Then
Exit Do
End if ' <--- Here
Loop Until eval(zNot, A, B) < 0.000001
zCalculation = zNot
End Function
answered Dec 9, 2013 at 17:06
1
Sub datacalculationsandformat()
Dim row As Integer
row = 2
Do While Cells(row, 2) <> ""
Cells(row, 3).Value = Cells(row, 2).Value * 0.3
Cells(row, 4).Value = Cells(row, 2) * 0.1
Cells(row, 5).Value = Cells(row, 2).Value + Cells(row, 3).Value + Cells(row, 4).Value
If Cells(row, 5).Value >= 8000 Then
Worksheets("Sheet1").Cells(row, 5).Font.Bold = True
row = row + 1
Loop
slavoo
5,81864 gold badges37 silver badges39 bronze badges
answered Sep 21, 2017 at 5:11
Доброго времени суток.
Задумка такова:
1. Установить счётчик строк на 38.
2. Если ячейка в столбце А (строка — по счётчику) не пустая, выполнить п.3-5. Если пустая, остановить программу.
3. Если ячейка в определённом столбце той же строки имеет значение «Оплачено», изменить цвет шрифта в ячейке столбца А той же строки. Если нет, перейти к п.4.
4. Увеличить счётчик строк на единицу.
5. Перейти к п.2
Код:
Sub Hilight ()
Dim taskcell as Integer
taskcell = 38
Do Until Range(«A» & taskcell).Value = «»
If Range(«A» & taskcell).Offset(0, 2 + User) = («Оплачено») Then
Range(«A» & taskcell).Font.ColorIndex = 16
Else
taskcell = taskcell + 1
Loop
End Sub
При запуске выдаётся сообщение «Compile error: Loop without Do». Помогите понять ошибку.
-
#1
hi experts….
Can anyone tell me why I get an error message «loop without do»? for this code
Code:
Do While Not rs2.EOF
For j = LBound(MYarray) To UBound(MYarray)
If rs2.Fields("ISSUE").Value = MYarray(j) Then
store = store & "," & rs2.Fields("ENGINEER").Value
Else
End If
rs2.MoveNext
Loop
-
#2
hi experts….
Can anyone tell me why I get an error message «loop without do»? for this codeCode:
Do While Not rs2.EOF For j = LBound(MYarray) To UBound(MYarray) If rs2.Fields("ISSUE").Value = MYarray(j) Then store = store & "," & rs2.Fields("ENGINEER").Value Else End If rs2.MoveNext Loop
Try using a Next statement instead of MoveNext. Is this all the code? Are you opening a recordset first and then executing these lines? Just asking.
Code:
Do While Not rs2.EOF
For j = LBound(MYarray) To UBound(MYarray)
If rs2.Fields("ISSUE").Value = MYarray(j) Then
store = store & "," & rs2.Fields("ENGINEER").Value
Else
End If
Next
Loop
-
#3
you still need the movenext otherwise rs2 will never reach EOF. And you need the next for the j
Code:
Do While Not rs2.EOF
For j = LBound(MYarray) To UBound(MYarray)
If rs2.Fields("ISSUE").Value = MYarray(j) Then
store = store & "," & rs2.Fields("ENGINEER").Value
Else
End If
rs2.movenext
Next j
Loop
MajP
You’ve got your good things, and you’ve got mine.
-
#4
Can anyone tell me why I get an error message «loop without do»? for this code
If you have a broken construct (IF without END IF, Do without Loop, For without Next) and they are nested the error always seems to be the outer nest and not the construct with the actual problem. So the message always seems wrong.
In this case it is broken because you have a FOR without a Next inside the DO Loop. You would expect the error to be FOR WITHOUT NEXT, not LOOP Without DO. Only after seeing this a few times do you know what to look for.
-
#5
the error always seems to be the outer nest
I’ve always wondered why vba shows the wrong message. I think this clarifies my doubt.
-
#6
I’ve always wondered why vba shows the wrong message. I think this clarifies my doubt.
On the other hand, I think it’s actually giving you the correct message. Of course, I am only guessing, but I believe the VBA interpreter/compiler is reading your code from top to bottom and probably went like this:
Code:
Do While Not ... (compiler: Ah, we're starting a Do loop, need to keep an eye out for the closing Loop keyword)
For j = ... (compiler: Ah, now we're starting a For/Next loop, need to keep an eye out for the closing Next keyword)
If rs2.Fields ... (compiler: Ah, this time we're starting an If/Then block, need to keep an eye out for the closing End If statement)
store = store & ... (compiler: nothing wrong here, just move on)
Else (compiler: I haven't seen the End If yet, so this Else statement is okay)
End If (compiler: Ah, here's the end of the If/Then block)
rs2.MoveNext (compiler: This should be legal within the For/Next loop, proceed)
Loop (compiler: Wait a minute, I didn't see a beginning Do statement inside the For/Next loop, this must be a mistake. Show error message)
[here's the rest of the code that's missing from the original post]
Next
Loop
See how the indentation helps see the problem? I certainly hope so. Cheers!
-
#7
On the other hand, I think it’s actually giving you the correct message. Of course, I am only guessing, but I believe the VBA interpreter/compiler is reading your code from top to bottom and probably went like this:
Code:
Do While Not ... (compiler: Ah, we're starting a Do loop, need to keep an eye out for the closing Loop keyword) For j = ... (compiler: Ah, now we're starting a For/Next loop, need to keep an eye out for the closing Next keyword) If rs2.Fields ... (compiler: Ah, this time we're starting an If/Then block, need to keep an eye out for the closing End If statement) store = store & ... (compiler: nothing wrong here, just move on) Else (compiler: I haven't seen the End If yet, so this Else statement is okay) End If (compiler: Ah, here's the end of the If/Then block) rs2.MoveNext (compiler: This should be legal within the For/Next loop, proceed) Loop (compiler: Wait a minute, I didn't see a beginning Do statement inside the For/Next loop, this must be a mistake. Show error message) [here's the rest of the code that's missing from the original post] Next Loop
See how the indentation helps see the problem? I certainly hope so. Cheers!
I’m sorry but I can’t understand your point. Here’s a simplified version of your code used above:
Code:
Sub test()
Do While Not f = 0
For j = 1 To 10
Loop
Next
Loop
End Sub
Vba gives me Loop without DO error and the error message makes sense. Because I don’t have a matching Do/loop.
But in case of OP’s question or similar problems I’ve had before, the message says there’s a problem with loop. While actually loop is OK and the problem is For without Next.
-
#8
@FahadTiger — I will explain your error message. In that explanation, I SHOULD use code tags but I can’t colorize them so I’ll do something else.
Do While Not rs2.EOF
For j = LBound(MYarray) To UBound(MYarray)
If rs2.Fields(«ISSUE»).Value = MYarray(j) Then
store = store & «,» & rs2.Fields(«ENGINEER»).Value
Else
End If
rs2.MoveNext
Loop
The DO WHILE … LOOP construct is almost OK — except that the FOR loop construct is incomplete. More specifically, the FOR J=… loop is unterminated. The correct termination would be to put a NEXT J just below the rs2.MoveNext instruction. You would NOT use a simple NEXT statement because that is not the correct termination. The syntax of VBA FOR «stepping» loops requires that you not only have the stepping variable in the FOR statement but ALSO in the NEXT statement.
This error is due to the «code block» concept. I colorized to show the different blocks. The IF/THEN/ELSE/END IF block in PURPLE is perfectly legal and properly terminated (though you could omit the ELSE and it wouldn’t change anything.) This is not the cause of the problem.
The GREEN block is unterminated because of not having the NEXT J in place. Therefore, the LOOP statement doesn’t have a corresponding DO statement
in the same code block
. My colors show what you probably intended, but using the code block concept, that LOOP statement appears (to VBA) to be in the GREEN block even though the corresponding DO WHILE was in the RED block. Thus, in the block where it appears, you have a LOOP without a DO. Adding the NEXT J before the LOOP statement would close out the GREEN block and leave you back in the RED block where the LOOP would properly terminate the DO.
Just one more side note: rs2.Fields(«ISSUE»).Value is a bit torturous. You could have used rs2![ISSUE] just as easily. Ditto for the [Engineer] field. Turns out that for anything that HAS a .Value property, it is the default property and thus does not need to be expressed. AND if that recordset has a field named ISSUE or one called ENGINEER, then the rs2![fieldname] syntax gets you there without quite as much typing. Again, you can omit the FIELDS() element because the default property for a recordset IS the FIELDS collection.
-
#9
Can anyone tell me why I get an error message «loop without do»? for this code
Code:
Do While Not rs2.EOF
For j = LBound(MYarray) To UBound(MYarray)
If rs2.Fields("ISSUE").Value = MYarray(j) Then
store = store & "," & rs2.Fields("ENGINEER").Value
Else
End If
next j
rs2.MoveNext
Loop
''some actions with a variable
debug.print store
-
#10
I love the way the DBGuy’s compiler gives a satisfied «ah» every time it encounters an understandable piece of code. I hope my compiler is enjoying itself even half as much.
-
#11
you still need the movenext otherwise rs2 will never reach EOF. And you need the next for the j
Code:
Do While Not rs2.EOF For j = LBound(MYarray) To UBound(MYarray) If rs2.Fields("ISSUE").Value = MYarray(j) Then store = store & "," & rs2.Fields("ENGINEER").Value Else End If rs2.movenext Next j Loop
thanks,its solve it
-
#12
more simplistically the way I think of it is — from the original code
Code:
Sub test()
Do While Not f = 0---compiler says OK starting a loop
For j = 1 To 10---compiler says OK starting a loop
code
Loop---compiler looks back as far as the last 'loop start' and can't see a Do
End Sub
-
#13
Code:
Sub test() Loop---compiler looks back as far as the last 'loop start' and can't see a Do End Sub
Sorry but I can’t understand this. You have a Do on line 2. Why compiler can’t see it?
If I was the compiler I would think this way:
Code:
Sub test()
Do While Not f = 0---compiler says OK starting a loop
For j = 1 To 10---compiler says OK starting a loop
code
Loop---compiler says I reached the loop for Do on line 2 but there's no next.
Do and For are overlapping. Send a message For without Next
End Sub--
Last edited:
MajP
You’ve got your good things, and you’ve got mine.
-
#14
The correct termination would be to put a NEXT J just below the rs2.MoveNext instruction. You would NOT use a simple NEXT statement because that is not the correct termination. The syntax of VBA FOR «stepping» loops requires that you not only have the stepping variable in the FOR statement but ALSO in the NEXT statement
This is not correct. VBA is very loose on this construct. No variable is needed in the NEXT. The below runs fine.
SQL:
Public Sub TestLoop()
Dim rs As DAO.Recordset
Dim i As Integer
Dim j As Integer
Dim fld As DAO.Field
Set rs = CurrentDb.OpenRecordset("01Schools", dbOpenDynaset)
For Each fld In rs.Fields
For i = 1 To 3
For j = 1 To 4
Debug.Print fld.Name & " I: " & i & " J:" & j
Next
Next
Next
End Sub
-
#15
You have a Do on line 2. Why compiler can’t see it?
My thinking is based on how the compiler actually works, not how you think it should work. whether you use for-next, while-loop, etc, they are all loops — the compiler just looks for the start of a loop, not the one that ‘matches’.
If it could, then the error would be on the previous line (where next is missing) but when it reaches that point it doesn’t know that is where the ‘next’ should be so cannot generate an error.
If it compiled in a different way accounting for the different loop types you might have —
started a ‘do’ loop so keep an eye out for the ‘loop’ terminator
now started a ‘for’ loop so keep an eye out for the ‘next’ terminator
now started another ‘for’ loop so keep an eye out for another ‘next’ loop
found the ‘loop’ terminator but hey, haven’t seen a ‘next’ terminator so which ‘for’ is missing a ‘next’?
and now you have the problem — there are two for/next loops and the developer has missed the first next. So when the compiler reaches a next — which for is it applied to?
-
#16
and now you have the problem — there are two for/next loops and the developer has missed the first next. So when the compiler reaches a next — which for is it applied to?
I think I understand your logic now.
But think it this way : In the following line,
Debug.Print Left(myvar, Len(Replace(var2, «_», «») — Len(var2))) & Mid(var2, Len(var2) — Len(var1))
the compiler has an eye on all opening and closing parentheses and quotation marks.
Not only it counts the number of closing and opening parentheses, but also checks for matching pairs and weather they are in the right position.
Why the compiler can not do the same for loops?
If my memory serves me well (which recently doesn’t) long long time ago, when I wrote php, the compiler was able to spot which inner loop has not a matching pair and highlighted the block. Then I was using Zend editor. I wonder why VBA behaves the way you explained.
Last edited:
-
#17
This is not correct. VBA is very loose on this construct. No variable is needed in the NEXT. The below runs fine.
Doc is reminiscing about his BASIC days…
-
#18
I wonder why VBA behaves the way you explained.
More correctly: «I wonder why VBA (mis)behaves the way you explained.»
Last edited:
-
#19
the compiler has an eye on all opening and closing parentheses and quotation marks.
Not only it counts the number of closing and opening parentheses, but also checks for matching pairs and weather they are in the right position.
I would suggest because that is all one line of code so will be compiled in one go.
Thinking ‘out loud’ they belong to functions with parameters separated by commas so the compiler knows how many parameters the function has so it knows where to expect to find the closing parentheses.
And before you mention optional and paramarray parameters I would say it knows the minimum number of commas so expects a closing parentheses after that. With nested functions, it still remains a relatively simple algorithm to keep track.
When you get a compile error — does it actually tell you which closing parentheses is missing?
Within a loop it is anyone’s guess as to where the loop ends until the code says so.
Edit: FYI I have developed a sql editor/management app (being demoed tomorrow at Devcon) and I use a similar method to the above to track what is between single and double quotes and other pairings for the purposes of formatting
-
#20
MajP said: This is not correct. VBA is very loose on this construct. No variable is needed in the NEXT. The below runs fine.
From the Microsoft VBA Language Specification published 04-30-2014, top of page 77 (in the PDF version thereof), and in section 5.4.2.3 For Statement I offer a couple of excerpts.
Code:
for-statement = simple-for-statement / explicit-for-statement
simple-for-statement = for-clause EOS statement-block "Next"
explicit-for-statement = for-clause EOS statement-block ("Next" / (nested-for-statement ",")) bound-variable-expression
nested-for-statement = explicit-for-statement / explicit-for-each-statement
for-clause = "For" bound-variable-expression "=" start-value "To" end-value [stepclause]
start-value = expression
end-value = expression
step-clause = Step" step-increment
step-increment = expression
The <bound-variable-expression> within the <for-clause> of an <explicit-for-statement> must resolve to the same variable as the <bound-variable-expression> following the <statement-block>. The declared type of <bound-variable-expression> must be a numeric value type or Variant.
I didn’t pluck my comment out of thin air. The presence of code tags means I cannot colorize or change much else, so I must simply refer you to the definition for the explicit-for-statement and the for-clause. According to the strict definition of a FOR statement, you have the «FOR variable = …» part followed by the statement block followed by Next and, if there is no intervening loop, the bound variable expression as in «NEXT variable» — and further, the variable with NEXT must resolve to the same variable as was used in the FOR statement.
I think we must at least agree that the FOR loop lacked proper termination. Whether by NEXT or NEXT J, it needed something it didn’t have, and the rest of my explanation (about implied language blocks) was correct. @MajP, you may indeed be correct that newer versions of VBA are looser than used to be the case. However, if the OP is using Access before 2016, this standard should apply.
NG said: Doc is reminiscing about his BASIC days…
Actually, no. As it happens, I am quoting the strict statement that describes VBA syntax, and I have named the reference. It is too big for me to upload in its entirety and besides, you can look it up yourself if you have an urgent need to do so. The following link gives you a page to download PDF or WORD versions from 2014 through 2021.
[MS-VBAL]: VBA Language Specification
Specifies the VBA Language, which defines the implementation-independent and operating system-independent programming language that is required
docs.microsoft.com
I looked at the 2021 version for the FOR statement and the language definition has not changed. It does not indicate that the bound variable of the NEXT is optional. More precisely, the syntax of the language definition doesn’t include a «leave it blank» option.
Search code, repositories, users, issues, pull requests…
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up