Condetional break inside the For loop and continue execution - vb.net

How can i break the loop and continue execution from the next line comes after the loop, if condition inside the loop is/are true. i tried labels and GoTo but it will executed all time will not depend on the condition inside the loop.
i have the following code :
Dim i As Integer
For i = 1 To 50
If i > 35 Then
' break the loop
End If
Next
I had tried with GoTo it works properly, some times it execute by default doese not depend on the condition given inside the loop
If i > 35 Then
GoTo lbl
End If
lbl: ' code comes here
Thank you......

If i > 35 Then
Exit For
End If
However your code with Goto would work too - provided the lbl: is outside the loop.

You can use the Exit command for this kind of break ; Exit Sub is used to comes out from a particular Sub, Exit Function will help you to comes out from a function, here you can use Exit For hence your code will be like the following
Dim i As Integer
For i = 1 To 50
If i > 35 Then
Exit For
End If
Next

Related

How does On Error Resume Next handle errors in If statements and loops

When handling errors within VBA code, there are a few methods commonly utilized. One of these methods is to use in-line error handling with On Error Resume Next. However, I found it unclear after reading the existing question "VBA: How long does On Error Resume Next work?" if the program continued execute on the very next line or if the program would continue executing at the next logical point.
MSDN has the following description for the functionality of On Error Resume Next:
Specifies that when a run-time error occurs, control goes to the
statement immediately following the statement where the error occurred
where execution continues. Use this form rather than On Error GoTo
when accessing objects.
Additionally, there was (now retired) StackOverflow Documentation on the Resume keyword which states something similar for On Error Resume Next:
Resume Next continues execution on the statement immediately following
the statement that caused the error. If the error isn't actually
handled before doing that, then execution is permitted to continue
with potentially invalid data, which may result in logical errors and
unexpected behavior.
This does not clearly state how the error handling line handles errors in the initial line of control flow statements. Specifically, if the error occurs in the first line of an If .. Then .. Else .. End If statement, will the program run starting on the first line inside the If statement or will the program run starting on the first line after the End If statement?
On Error Resume Next will cause a program to proceed into an If .. Then statement or a [While/Do/For/For Each] loop when the qualifying statement results in an error.
To solve this question I created a pair of test functions in an empty Excel (2007) workbook. I then used the spreadsheet of Excel to evaluate the functions for known error cases and known successful cases.
Test1 - If Statements
Public Function Test1(intN As Integer) As String
On Error Resume Next
Test1 = ""
If 1 / intN > 0 Then
Test1 = Test1 + "A"
Else
Test1 = Test1 + "B"
End If
Test1 = Test1 + "C"
End Function
This function will throw an error at the line If 1 / intN > 0 Then when the input number is 0, and will evaluate for other numbers such as 1 and -1.
Results:
Test1(-1) -> BC
Test1(0) -> AC
Test1(1) -> AC
As seen in the results, the error in Test1(0) caused the program to skip the line If 1 / intN > 0 Then. A was added to the string, and then the program skipped from Else to End If. The character C was added to the string and the function ended.
Test2 - [Do] Loops
Public Function Test2(intN As Integer) As String
On Error Resume Next
Test2 = ""
Do While 1 / intN > 0
Test2 = Test2 + "A"
intN = intN - 1
Loop
Test2 = Test2 + "C"
End Function
This function will throw an error at the line Do While 1 / intN > 0 when the input number is 0, will return a string of AA..AC for positive integers, and return C for negative integers.
Results:
Test1(-1) -> C
Test1(0) -> AC
Test1(1) -> AAC
When entering a loop, On Error Resume Next will cause the program to skip from Do While 1 / intN > 0 directly to Test2 = Test2 + "A", regardless of which iteration of the loop it is in.
Whenever intN = 0, the program ran through the code contained in the loop and hit intN = intN - 1, causing intN = -1 and not going through the loop code again.
From this, it can be interpreted that in the case of a For or While loop, the loop would operate in a similar manner, taking the literal next line and going back when hitting the bottom of a loop.

LOOP and nested if statements not working

the code is intended to seek out the "Yes" in "OverExtensions" and will create a new range and determine the maximum value of the new range. For some reason the logic of the code seems alright but I'm getting an empty result and would love the community's input as to where I've went wrong.
Private Sub CommandButton1_Click()
Dim maximum As Double, OverExtension As Range, x As Range
Cells.Interior.ColorIndex = 0
Set OverExtension = Range("D2:D12")
maximum = WorksheetFunction.Max(Range("c2:c12"))
For Each x In OverExtension
If x.Value = Yes Then
If x.Offset(0, -1).Value = maximum Then
x.Cells.Interior.ColorIndex = 22
End If
End If
Next x
End Sub
You nested the if and for blocks in a wrong way.
You have to put the second End If between Next PriceNo and Next OEResult.
Update:
You need just one End If. The first one is wrong because If and Then are in one line.
Besides you have problem with your OEYes and OEResult variables as they are defined but not initialized but as I don't know your intention I also don't know how to solve it.

Insert Template with Loop x Amount of Times

I'm back with another question that probably has a simple answer. I really fall down when it comes to loops, so this is what I am trying to build.
I am building a form where user will type in a number between 1 and 156 (named range "GenNo") and click a Generate button.
I need a loop that will copy a template built in the "Template" tab of the spreadsheet with the named range also being "Template", and then insert it into the main form page the specified amount of times. This way the rest of the content and other named ranges should be pushed down accordingly.
Probably a very simple answer but I am terrible when it comes to loops and would not know where to start.
Thanks for your help.
EDIT: This attempt only generates one template in the form:
Sub Generate()
' Check if payslips are already generated
If Sheets("Data").Range("GenLogic").Value = 1 Then
MsgBox ("Already Generated! Please clear the form and regenerate.")
Else
Sheets("Data").Range("GenLogic").Value = 1
End If
' Loop code
Do Until Sheets("Data").Range("LoopLogic").Value = Range("GenNo").Value
Sheets("Template").Range("Template").Copy
Sheets("Overpayment Form").Range("Start").Insert
Range("LoopLogic") = Cell.Value + 1
Loop
End Sub
i would give this a shot; note that i removed your updating of your loop variables. Also, i've rewritten your loop to use a for, and shift down on insert.
Sub Generate()
' Check if payslips are already generated
If Sheets("Data").Range("GenLogic").Value = 1 Then
MsgBox ("Already Generated! Please clear the form and regenerate.")
Else
Sheets("Data").Range("GenLogic").Value = 1
End If
' Loop code
Dim iFrom As Long, iTo As Long, i As Long
iFrom = Sheets("Data").Range("LoopLogic").Value
iTo = Range("GenNo").Value
For i = iFrom To iTo
Sheets("Template").Range("Template").Copy
Sheets("Overpayment Form").Range("Start").Insert Shift:=xlDown
Next
End Sub

Are if statements considered as an Iteration

Hello I'm just wondering whether an 'if' statement can be considered as an Iteration. Because Iteration is used until a certain criteria is meet to allow the code to continue.
An iteration is one cycle (one time through) a loop. If blocks are not loops.
For blocks or While blocks are loops, and executing one cycle of the contents of one of those blocks — what's inside the For block or the While block — is one iteration of the loop. If the entirety of a For block or While block is a conditional If block, then the If block could be one iteration... but not because it's an If block, but because it's what's inside the loop.
No, an iteration is a repetition of some code. Once doesn't count as a repetition, else all code would be considered an iteration.
The If statement by itself cannot be considered iteration. You can run a code block containing an if statement as many times as you wish, but this doesn't make the if statement an iterator by itself. It's what calls that code block which could stand for iteration.
If statement has some similarities with those other conditional statements :
Select Case
Try Catch
Explicit iterators are the followings :
For/Next - For Each/Next
Do/Loop
While/End While
However, you have some logic that could turn the usage of an if statement as the trigger to resume or stop conditions of a loop, without the usage of direct loop statements like For or While. But that doesn't turn that if statement an iterator by itself, because the iteration is the combination of the if statement and a specific logic allowed by the programming language.
Recursion :
Private Function ResumeIncrement(ByRef Number As Int32) As Boolean
Number = Number + 1
If Number < 10 Then
Return ResumeIncrement(Number)
Else
Return False
End If
End Function
GoTo statement :
Private Sub TestGoTo()
Dim Number As Int32 = 0
IncrementMore:
Number = Number + 1
If Number < 10 Then
GoTo IncrementMore
End If
End Sub
And as stated by Joel Coehoorn above, the If block can contain anything, including iterator blocks triggered by For, While or Do. If you remove the contained block, that doesn't change anything in what the if part is supposed to do : a conditional check !
You can also do the inverse, and use an If block to control the way an iteration behaves. Like :
If SomeCondition Then
Exit For
' Or Exit While, etc. ie, using the 'Exit' statement
End If
or
i = 0
Do
i = i + 1
' ^^ capture i in Debug or Console
' Control the value of i...
If i Mod 2 = 0 Then
i = i - 2
Else
i = i * 3
End If
Loop While i < 30
' i = 1, 4, 3, 10, 9, 28, 27, [Exit Do with i = 81]
In the two examples above, the If statement is either there to break the iteration, or try again, that said, to "control the iteration", but in no means, to stand for iterator by itself.
Here is also another answer to clear out one uncertainty. You asked
Are if statements considered as an Iteration ?
(You made "if statements" plural) Then you said
Hello I'm just wondering whether an 'if' statement can be considered
as an Iteration. Because Iteration is used until a certain
criteria is meet to allow the code to continue.
(then you made it singular.. ???) That "...Iteration is used until..." should self answer your question alone, assuming you're iterating code blocks (which is the way it is understood here)
But what if you're talking about iterating some possible values until one meets your requirements..?
If MyValue = "" Then
' ...
ElseIf MyValue.StartsWith("A") Then
' ...
ElseIf MyValue.ToUpper = "TEST" Then
' ...
Else
' ...
End If
is similar to :
Select Case True
Case MyValue = "":
' ...
Case MyValue.StartsWith("A")
' blah blah blah
End Select
or
If MyValue = "" Then GoTo EmptyString
If MyValue.StartsWith("A") Then GoTo StartsWithA
If MyValue.ToUpper() = "TEST" Then GoTo IsTEST Else GoTo DoNothing
EmptyString:
' ...
GoTo DoNothing
StartsWithA:
' ...
GoTo DoNothing
IsTEST:
' ...
GoTo DoNothing
DoNothing:
' Resume...
Etc.
That's not an iteration ! That's a list of evaluation that are processed in order. When a condition evaluates to True, the related code is executed. Unlike iteration, this is just a matter of selecting the right path and resume, not walking the very same path several times (loops)
Yes, you're iterating through a collection of possible values (condition states) but NO, you're not iterating the If statement. You're only checking the result of each single If test once.

Advance to Next Item from Within a For-Next Loop

I have a For-Next loop. Within the loop I test several different criteria and if any test fails, then I am ready at that point to skip the remainder of the code in the loop and advance to the "next" item. The way I currently handle this is with a GoTo statement that takes me to the line right before "Next". I'd prefer not to use a GoTo statement, is there another way to advance to the "next" item from within a For-Next loop? TIA!
For x = 1 to 10
Test 1
If Test 1 fails then
GoTo Line1
End if
Test 2
If Test 2 fails then
GoTo Line1
End if
.
.
.
If all tests pass then
add item to array
End if
Line1:
Next
Unfortunately there is no continue-like statement in a for loop in vba. (The related control structure Exit For does exist but that's of no help here).
And it's good that you have reservations on using a GoTo: they do make code hard to follow.
Your best bet is to put the code in the loop in a separate function and use Exit Function within that function at appropriate points. You can even then relay error codes back to the caller so helping the code to scale.
Here's a workaround for the lack of a continue keyword:
For x = 1 to 10
Do
Test 1
If Test 1 fails then
Exit Do
End if
Test 2
If Test 2 fails then
Exit Do
End if
.
.
.
If all tests pass then
add item to array
End if
Loop While False
Next
You can use if else ladder :
For x = 1 to 10
if test 1
else if test 2
else if test 3
.
.
.
.
else
add item to array
end if
Next
Besides GoTo there is not any direct way to jump in between your code,
Hope this might help.
If you don't have too many tests, you could you use the Not condition and build a nested If statement. This should have almost the same effect as what you're asking for, since any failed test would end that If statement and move the code to the next X in your loop without executing the following tests.
Here's an example of what I mean -- a two test loop that builds an array containing the numbers 5 through 10:
Sub TestConditionalPass()
Dim intX As Integer
Dim intArray() As Integer
ReDim intArray(1)
For intX = 1 To 10
If Not intX -2 < 1 Then
If Not intX * 2 < 10 Then
ReDim Preserve intArray(UBound(intArray) + 1)
intArray(UBound(intArray)) = intX
End If
End If
Next intX
End Sub
Since you are preforming an action only if all tests succeed, then do the if-statement with ands. VBA doesn't short circuit the tests, (i.e. it will evaluate each test case, even if the first one returns false.) I would suggest encapsulating each test in a function that returns a Boolean to keep your code tidy.
If Test1() and _
Test2() and _
testn() THEN
add item to array
End if
Another way is to make use of a Boolean variable in your code, like this
Dim Success as Boolean
Success=True
Test 1
If Test 1 fails then
Success=false
End if
Test 2
If Test 2 fails then
Success=false
End if
.
.
.
If Success then
add item to array
End if
If the tests are expensive, you can add an inner if statement checking to see if we need to evaluate the next test like this
If Success Then
If Test n fails then
Success=false
End If
End if