Is there a limit on the number of operations VBA can perform? - vba

Inspired by a puzzle I saw online , and since I'm a VBA newbie, I thought it might be an interesting exercise to help me learn how to use For loops by making a brute force method to search for solutions to it.
This led to creating a monstrosity that takes ages to partially run and actually won't fully run at all.
All the code is meant to do is print 3 columns of valid combinations
Private Sub CommandButton1_Click()
Dim j As Long
Dim abc As String
Dim def As String
Dim ghi As String
j = 1
For a = 1 To 9
For b = 1 To 9
For c = 1 To 9
For d = 1 To 9
For e = 1 To 9
For f = 1 To 9
For g = 1 To 9
For h = 1 To 9
For i = 1 To 9
'Line breaks included for ease of reading
If a = b Or a = c Or a = d Or a = e Or a = f Or a = g Or a = h Or a = i
Or b = c Or b = d Or b = e Or b = f Or b = g Or b = h Or b = i
Or c = d Or c = e Or c = f Or c = g Or c = h Or c = i
Or d = e Or d = f Or d = g Or d = h Or d = i
Or e = f Or e = g Or e = h Or e = i
Or f = g Or f = h Or f = i
Or g = h Or g = i
Or h = i Then
Else
abc = a & b & c
def = d & e & f
ghi = g & h & i
ThisWorkbook.Sheets("Sheet1").Cells(j, 1).Value = abc
ThisWorkbook.Sheets("Sheet1").Cells(j, 2).Value = def
ThisWorkbook.Sheets("Sheet1").Cells(j, 3).Value = ghi
j = j + 1
End If
Next i
Next h
Next g
Next f
Next e
Next d
Next c
Next b
Next a
End Sub
This obviously involves lots of simple operations, and results in variously (Not Responding) messages or it just doesn't run. Was it possible to tell before clicking "Go" that that would be the case?
My job has me working on, and adding to, spread sheets that perform lots of operations on other spread sheets with conceivably hundreds of thousands of data items in each. Continuing to add functionality to these files may or may not be sustainable, I need to know how to tell before I sink time into further development.
Is there a hard limit to what can be done with VBA in terms of volumes/numbers of operations? Is there a tool that will estimate the viability of a macro actually running to completion? A heuristic commonly employed in industry?
Basically, what methods or tools exist to inform as to whether the demands of a macro or series of macros will exceed available memory?
Thanks

You should attempt to do a tiny bit of maths before you begin.
Your code generates all the permutations of 9 thing taken 9 at a time. Before you begin, you know this this will fill 362880 rows; so the code should work.
A separate issue is how much time will it take, and is this the most efficient method .

Not an answer, but can it be tackled by just looping the numbers? Something along these lines, is checking the 1st char against the rest
Dim l As Long
Dim i As Integer
For l = 11111111 To 99999999
For i = 2 To 8
DoEvents
If (Mid(l, i, 1) <> Mid(l, 1, 1)) Then
Debug.Print l
End If
Next i
Next l

Related

If, Then and Select Case

I'm writing VB Code and I see a question below
There are three positive integers A, B, C
If A is greater than B, C is equal to A+B
If A is less than or equal to B, then C is equal to A-B.
Please use IF...Then and Select/Switch Case to write a program, both of which are used in this program, and additional variables can be added by yourself.
I would like to ask how to write this question, as far as I know, the answer just need only IF Then or Select Case can be realized?
Dim A As Double = 3
Dim B As Double = 2
Dim C As Double = 1
Dim D As Double = 0
D = A - B
Select Case D
Case D > 0
C = A + B
Case D < 0
C = A - B
End Select
If D > 0 Then
C = A + B
ElseIf D < 0 Then
C = A - B
End If
In the real world you wouldn't need to use both an If/Then statement and a Select/Case statement. Since this appears to be homework, I believe the exercise is to see if you can use both conditional check.
I would setup two functions that accept two arguments (a and b) that return the value of c. In your first function use an If/Then and in your second function use a Select/Case.
E.g.
Private Function IfThenOption(a As Integer, b As Integer) As Integer
Dim c As Integer
If (a > b) Then
c = a + b
ElseIf (a < b) Then
c = a - b
Else
c = a
End If
Return c
End Function
Private Function SelectCaseOption(a As Integer, b As Integer) As Integer
Dim c As Integer
Select Case True
Case a > b
c = a + b
Case a < b
c = a - b
Case Else
c = a
End Select
Return c
End Function
Example: https://dotnetfiddle.net/kwcyWc

How do i alter my program to use a for loop instead of a do until loop?

I have to write a race program between a coyote and a roadrunner. Both start at 1 and the finish line is 5. Each take turns moving until they reach 5. I can't figure out how to do this using a for loop instead of a do until loop please help.
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
Dim moves, mover, r, c, d As Integer
Dim rand As New Random
r = 1
c = 1
Do Until c = 5 Or r = 5
mover = rand.Next(2)
If mover = 0 Then
moves = rand.Next(1, 11)
If moves <= 6 Then
r = r + 1
ElseIf moves > 6 Then
r = r + 2
End If
End If
If mover = 1 Then
moves = rand.Next(1, 11)
If moves <= 6 Then
c = c + 1
ElseIf moves > 6 Then
c = c + 2
End If
End If
Loop
If r = 5 Then
lblWinner.Text = ("Roadrunner is the winner!")
End If
If c = 5 Then
lblWinner.Text = ("Coyote is the winner!")
End If
End Sub
If you know exactly how many times a loop will execute use a For loop. If the number of iterations is not known exactly, use a While loop. Do you know the number of times this program will execute exactly? No. One may move 2 moves every time and end the race in 5 turns. So, it could be somewhere between 5 and 10 turns thru the loop, therefore it is unknown the exact number of times the loop should execute.
although Loop Untilseems the way to go here, if there is a specific reason that you'd want to use a for loop you can always use :
If (c = 5) OrElse (r = 5) Then
Exit For
End If

Variable in VBA doesn't change

I'm trying to make a new table from some information in a table, with an
structure like this:
A B D G L
A B D G M
A B D H N
A B E I O
A C F J P
A C F K Q
So, It returns a table with rows like this:
A | D | B | "G: L M H: N"
The original data base has the following columns:
Role
Object
Instance
Field
Value
The new table should be: Role, Instance, Object, Object value. So, if the object is the same, it means it's a new instance for that object, an it's new value will be every field(with all it's values), like the example above.
This is the code (The text is supposed to be in the first 5 columns, and it should be returned from the G column):
Sub instancia()
Dim fila, filacol As Long
Dim cad, c As String
fila = 2
filacol = 2
Do
cad = ""
Cells(filacol, 7) = Cells(fila, 1)
Cells(filacol, 8) = Cells(fila, 3)
Cells(filacol, 9) = Cells(fila, 2)
Do
c = " "
cad = cad + Cells(fila, 4).Value + ": "
Do
c = c + Cells(fila, 5).Value + " "
fila = fila + 1
Loop While Cells(fila, 4) = Cells(fila + 1, 4)
cad = cad + c
Loop While Cells(fila, 2).Value = Cells(fila + 1, 2).Value
Cells(filacol, 10).Value = car
filacol = filacol + 1
Loop While Cells(fila + 1, 2) <> Empty
End Sub
It does't work because it says there's a problem with execution time, but trying to debug, I found out that the variable 'fila' never changes. What can I do?

How do I compare values in two columns and then mark true/false in a third?

Can someone please help me create a macro that will search two columns on a worksheet for a list of conditions and mark true/false on the third column. (office 2010)
e.g.
Column A would have the following values: 1111,1,2,3,3,4,...
Column B would have the following values: O,A,Y,A,S,3Y,...
If the following matching conditions are met, the column C would mark as TRUE, otherwise FALSE.
A B
1111 = O
0 = Y
1 = A
2 = S
3 = 3YRY
4 = Q
6 = B
12 = M
13 = V
360 = D
CONDITION RULES:
IF column A = 1111 AND column B = O
OR
IF column A = 0 AND column B = Y
OR
IF column A = 1 AND column B = A
OR
IF column A = 2 AND column B = S
OR
IF column A = 3 AND column B = 3YR
OR
IF column A = 4 AND column B = Q
OR
IF column A = 6 AND column B = B
OR
IF column A = 12 AND column B = M
OR
IF column A = 13 AND column B = V
OR
IF column A = 360 AND column B = D
THEN COLUMN C = "TRUE" ELSE "FALSE"
This should match more closely what you're wanting to accomplish, any questions about what's happening here let me know.
Option Base 1
Sub testCriteria()
'arrays for criteria r, r2. Array for T/F r3
Dim r, r2, r3(10, 1)
'iterators for loop and variable for output column
Dim i As Long, j As Long, c As Long
'column for output of t/f
c = 3
'location of criteria cells h1 through i10
r = [h1:i10]
'location of comparison
r2 = [a1:b10]
'loop through rows of rows to check (r2) and compare with all rows from criteria (r)
For i = LBound(r2) To UBound(r2)
For j = LBound(r) To UBound(r)
If CStr(r(j, 1)) = CStr(r2(i, 1)) _
And CStr(r(j, 2)) = CStr(r2(i, 2)) _
Then r3(i, 1) = "TRUE"
Next j
If Not r3(i, 1) Then r3(i, 1) = "FALSE"
Next i
'reusing iterators for array limits
i = LBound(r3): j = UBound(r3)
'loading t/f array into api
Range(Cells(i, c), Cells(j, c)) = r3
End Sub

Randomly ordering variables

I have 4 strings in variables a,b,c and d. I need to randomly order these variables in such a way so that I can input them into 4 different text boxes but not the same ones every time the program is ran.
I've tried to simplify it for myself by putting the strings into an array. Tell me what I'm doing wrong or if there's a way I could do it much easier.
Private Sub Random()
For i = 1 To 4
If a = 0 Then
a = r.Next(2, 5)
ElseIf b = 0 Then
Do Until b <> a
b = r.Next(2, 5)
Loop
ElseIf c = 0 Then
Do Until c <> a Or c <> b
c = r.Next(2, 5)
Loop
ElseIf d = 0 Then
Do Until d <> a Or d <> b Or d <> c
d = r.Next(2, 5)
Loop
End If
Next
End Sub
Here is one way to do it:
Dim a As String = "a"
Dim b As String = "b"
Dim c As String = "c"
Dim d As String = "d"
Dim all As String() = {a, b, c, d}
Dim random As New Random
Dim allRandom As String() = all.OrderBy(Function() random.Next).ToArray