Getting vbScript do something only on a whole number division - vba

I am trying to get VBA to click F11 for me, if a process has occurred 8x
Do While y<Entries
InitialCopy
If y/8 Then <---- **PROBLEM AREA**
autECLSession.autECLOIA.WaitForInputReady
autECLSession.autECLPS.SendKeys "[pf11]"
End If
y=y+1
Loop
So I need to tell it to only hit the Then portion if y/8 generates a whole number in the arithmetic, not in the way vba sees it (ie. only integer portion). Any ideas are welcomed.
Then should only execute on the variable equaling 1,2,3,4,5,6,7,8,9,10 in an underlying division arithmetic output. NOT in a VBA / operator output

I think the solution is
Do While y<Entries
InitialCopy
If y Mod 8 = 0 Then
autECLSession.autECLOIA.WaitForInputReady
autECLSession.autECLPS.SendKeys "[pf11]"
End If
y=y+1
Loop

Related

datatype in for .. next structure

I ran in a problem with an inadequate type declaration for the counter variable of a for-next loop.
What´s wrong with this code snippet?
For n As Byte = 16 to 2 Step -1
Debug.Print(n)
Next
-> The loop is never entered,
while the code
For n As SByte = 16 to 2 Step -1
Debug.Print(n)
Next
works as expected.
I´ve been using VB since 1994, currently Visual Studio Community 2019, V16.8.2, but never ran into this problem.
If n needs to be of a "signed" datatype when Step is of type SByte, Integer ..., to handle neg. numbers, why do I not get an Error, Alert ... from the VS-Compiler?
There is also not hint within the MS doc.
Sure this "problem" can be avoided by using (signed)Byte, Integer, double or decimal as datatypes, but I´d like to understand why VS doesn´t give any alert.
Did I miss something?
Regards
Werner

VBA - Leave Do Until when specific row is reached

In my VBA Code i go from the last row in my table to the top of my table. But i want that the Do Until Loop ends when it reached Row 10.
Right now I am using this Do Until Loop:
Do
' Do Something
Loop Until ActiveCell.Address = "$N$10:$BI$10"
How do i have to change my code that it will stop when it reached row 10?
Assuming rest of code is correct use:
Loop Until ActiveCell.Row = 10
If that fails you problem is logic in other parts of your code ie. ActiveCell never reaches row 10.
To answer your question in more theoretical fashion. There are multiple ways of exiting Do loops in VBA.
The proper way
1.1. While or Until at the begining
This checks the condition first, if the condition is met, it enters the loop and repeat with the condition being met at the start of every loop.
Do While i <= 5
'#code here
Loop
These two are equivalent.
Do Until i > 5
'#code here
Loop
1.2. While or until at the end
This is almost the same as what is described above. The only difference being, with sole Do statement at the beginning, your code-block always gets executed at least once! This can be particularly useful, when you want to execute something at least once, but don't want it to repeat unless a condition is met.
Do
'#code here
Loop While i <= 5
or
Do
'#code here
Loop Until i > 5
The enforced way
You can exit out of any loop, including Do with the so called Exit statement. This escapes the currently ongoing Do loop upon reaching the statement no questions asked. While you usually should try to avoid using the Exit statement, as in majority of cases it is possible to avoid using it with a proper condition at the While or Until portion of your code, it can come in handy in some cases.
Additionally, keep in mind, inside nested Do loops, Exit always exits only the innermost loop. This means, this would exit only the loop inside and let the others run, acting as a weird form of Continue
Do While (handler = True)
Do
'# execute me
If weird_condition = True Then
Exit Do
' i return to the "handler" loop
End If
field = field + 1
Loop Until field = field_amount
Loop
The not so nice enforced way
Alternatively, you can stop the entire exution, with the Stop statement. I would strongly advise against doing this, but technically it is a possibility so I'm listing it here. Similarly like End it ends the execution, but unlike End (eg. End Sub), it does not close any files or clear any variables - so technically this means you could use it to exit a loop. I would however recommend simply using the Exit statement instead. Can't really think of a case when I would ever use this.

Is there an equivalent of Python's pass statement in VBA?

I would like to know if there is an equivalent of Python's pass statement in VBA.
I am using Excel 2016.
The use of Stop (see this answer) seems to be the best thing to do if you are looking for some "non-statement" that you can use to insert a breakpoint, because the Stop command causes the code to break when it is reached, i.e. you don't even need to mark it as a breakpoint because it is one.
You might also like to consider using Debug.Assert some_logical_expression, which will break automatically whenever the logical expression evaluates to False. So Debug.Assert False would be equivalent to Stop, and Debug.Assert x = 3 would be equivalent to If x <> 3 Then Stop.
In Python you need the Pass, because otherwise the methods will not run.
In VBA, its perfectly ok if you leave an empty method like this:
Public Function Foo() As String()
End Function
Maby you are looking for the "Stop" statement.
The good thing about it is that it doesn't clear your variables.
It depends what are you trying to achieve.
You may declare a Label and then use GoTo Label e.g. declare a label (like Skip:)in your code where you want to jump if a condition is met and then use GoTo Skip
Below is the small demo code to give you an idea about this...
Dim i As Long
For i = 1 To 10
If i = 5 Then GoTo Skip
MsgBox i
Next i
Skip:

Using VBA commands to work with Solver Dialogue box

Currently I'm creating a program in excel that runs solver. I have set a maximum time limit on the solver command. If the program exceeds the time limit, a solver dialogue box comes up that asks whether to continue or stop. I was wondering if there was a way to code into VBA to automatically select stop rather than having to have a user click the option.
Thanks in advance!
Yes, you can. You need to set some options on the Solver object. You can read more about it In the MSDN documentation
SolverSolve(UserFinish, ShowRef)
UserFinish Optional Variant. True to return the results without displaying the Solver Results dialog box. False or omitted to return the results and display the Solver Results dialog box.
ShowRef Optional Variant. You can pass the name of a macro (as a string) as the ShowRef argument. This macro is then called, in lieu of displaying the Show Trial Solution dialog box, whenever Solver pauses for any of the reasons listed
You need to define a macro that runs, which must take an integer argument. Here is a code example, straight from the linked page (posted here in case the link is broken in the future)
You call SolverSolve, passing it the arguments above:
SolverSolve UserFinish:=True, ShowRef:= "ShowTrial"
You then need to define the ShowTrail macro that runs, and it must have the correct signature:
Function ShowTrial(Reason As Integer)
'Msgbox Reason <= commented out, as you just want it to end, with no user input
ShowTrial = 0 'See comment below on the return value.
End Function
The return value is important. Return 0 if you want solver to just carry on regardless, or 1 if you want it to stop.
You could then get it to have different behavior on different reasons it finishes. Eg, if it reaches maximum time limit (your case), then stop. Otherwise, carry on:
Function ShowTrial(Reason As Integer)
Select Case Reason
Case 1 '//Show iterations option set
ShowTrial = 0 '//Carry on
Exit Function
Case 2 '//Max time limit reached
ShowTrial = 1 '//Stop
Exit Function
Case 3 '//Max Iterations limit reached
ShowTrial = 0 '//Keep going
Exit Function
Case 4 '//Max subproblems limit reached
ShowTrial = 0 '//Keep Going
Exit Function
Case 5 '//Max feasible solutions limit reached
ShowTrial = 0 '//Keep going
Exit Function
End Select
End Function

How does VB.Net evaluate the end test of a FOR...NEXT loop?

I am teaching students about the FOR NEXT loop in VB.Net and I seem to be burdened with an understanding from learning Assembly language long ago. Trying to count the number of iterations that a line of code would do in several cases:
FOR x = 1 TO 1 (implied STEP 1)
(body)
NEXT x
Should do 1 loop, right? But I read the test as "until x is 1", so after the first loop, x becomes 2 and the test should not work.
How about: FOR x = 1 TO 1 STEP -1? Is your answer the same?
How about: FOR x = 1 TO 0 (implied STEP 1)? The body should never execute. But the test is "until x = 0", so it should cause an infinite loop as x climbs away from 0... Starting to see the issue?
How about: FOR x = 1 TO 0 STEP -1? Now it will do the body twice, right? But what is x at that point? -1. How did the test stop when it is one beyond what is says it will stop at?
I guess the compiler is actually testing until x = (endval) + stepval. I can visualize that in Assembler, but otherwise I confess that I can't see or explain to my students how this all actually works the way it is assumed it "should". (This question seems trivial with constants like "1", but imagine variables or other ways of creating the FOR loop parameters.) Can anyone shed some light? Thank you.
It seems Tony Hinkle provided the answer, but did so as a comment. So I'm providing the particular text he mentioned here, as an answer:
"When a For...Next loop starts, Visual Basic evaluates start, end, and step. Visual Basic evaluates these values only at this time and then assigns start to counter. Before the statement block runs, Visual Basic compares counter to end. If counter is already larger than the end value (or smaller if step is negative), the For loop ends and control passes to the statement that follows the Next statement. Otherwise, the statement block runs.
Each time Visual Basic encounters the Next statement, it increments counter by step and returns to the For statement. Again it compares counter to end, and again it either runs the block or exits the loop, depending on the result. This process continues until counter passes end or an Exit For statement is encountered.
The loop doesn't stop until counter has passed end. If counter is equal to end, the loop continues. The comparison that determines whether to run the block is counter <= end if step is positive and counter >= end if step is negative."
To help clarify:
FOR x = 1 TO 1 (implied STEP 1) will loop 1 time.
FOR x = 1 TO 1 STEP -1 will loop 1 time.
FOR x = 1 TO 0 (implied STEP 1) will never loop because counter is already past end.
FOR x = 1 TO 0 STEP -1 will loop twice