This is my first question here and I must admit, I was not able to find any solution so far here or elsewhere. Here is the problem:
I wanted to program a code, which is supposed to do the following:
 Ask the user how many rows are needed
 Ask, how many columns are needed
 Create a matrix, where in the first column all rows are numbered, in the first row all columns are numbered and within the matrix, all these numbers are the multiplied (row 3/column 4 contains 12, for example).
 Finally, all prime numbers shall be colored.
My problem starts with the last step (in my code beginning at “‘Primzahlen hervorheben”). For each combination of row and column I use two for
loops, in which I first assume, the product IS a prime number by setting primzahl = true
and set k = 2
, which is 1 upped through all numbers up to the product itself… BUT for some reason, k
keeps growing and eventually reaches the five digits area, before it crashes. I guess, the problem must be in this line:
Do While (primzahl = True) Or (k <= i * j) Or (i * j <> 1)
I connected all conditions as one would in an if
construct. The Editor itself does not seem to have a problem with this, but why does it ignore the second condition, which does not allow for k
to become larger than i * j
? Am I missing something?
Just to put it in words: The loop shall continue, as long as
 it being not a prime number proves to be the case (p
rimzahl = false
), OR k
is smaller or equal toi * j
, ORi * j
is not 1
This case is no emergency or anything, I just want to know, where the hook is. I would appreciate your support and hope, to get some helpful advise.
Sub rechnen()
'Zellen leeren
Cells.ClearContents
Cells.ClearFormats
'Variablen definieren
Dim i As Integer, j As Integer, k As Integer, iMax As Integer, jMax As Integer, primzahl As Boolean
'Variablen Werte zuweisen
iMax = 3 'InputBox("Anzahl Zeilen")
jMax = 5 'InputBox("Anzahl Spalten")
'Eigentliche Prozedur
For i = 1 To iMax
Cells(1 + i, 1).Value = i
For j = 1 To jMax
Cells(1, 1 + j).Value = j
Cells(1 + i, 1 + j).Value = i * j
Next j
Next i
'Spaltenbreite anpassen
ActiveSheet.UsedRange.Columns.AutoFit
'Primzahlen hervorheben
For i = 1 To iMax
For j = 1 To jMax
k = 2
primzahl = True
''''''''
Do While (primzahl = True) Or (k <= i * j) Or (i * j <> 1)
If Cells(1 + i, 1 + j).Value Mod k = 0 Then
primzahl = False
Exit Do
End If
k = k + 1
Loop
''''''''
If primzahl = True Then
Cells(1 + i, 1 + j).Interior.Color = vbRed
End If
Next j
Next i
End Sub
``
You seem to be mixing up OR and AND:
The loop shall continue, as long as […] OR […] OR […]
You actually mean to say that the loop shall end when either one of these three conditions is not true. So logically the loop should continue while all of the conditions are still true. This expresses a logical AND, not an OR.
So you meant:
Do While (primzahl = True) And (k <= i * j) And (i * j <> 1)
But this can be simplified.
The expression primzahl = True
will always be true, because as soon as you set primzahl = False
, you explicitly exit the loop with Exit Do
, so the While
condition never gets evaluated with primzahl = False
.
Secondly, if (i * j <> 1)
is true the first iteration, it will also be true in any other iteration, since the iterations do not change i
nor j
. But even if it were true the first time, then certainly k <= i * j
is not true (you already set k = 2
and it only gets greater values), so also this condition is always going to be true once you get past the condition on k
.
So, taking that into account you would have:
k = 2
Do While k <= i * j
' etc..
k = k + 1
Loop
And then why not make it a For
loop, since you let k
go from 2 to i*j
?
For k = 2 To i * j
' etc.. (don't do k = k + 1 now)
Next
Concerning the assignment you gave yourself: numbers resulting from i * j
with i
and j
both greater than 1 are by definition not primes, so there is no sense in performing a check on them. They have at least i
and j
as divisors.
Answer：
I have finally returned, after I was absent for quite a while. With a fresh mind I just tried again to tackle the task described above. Naturally, I implemented certain changes:

First: The numbers in the matrix are no longer products of the given numbers in the first row and column, since that fully defeats the purpose of checking for prime numbers. Instead they are now random numbers, ranging from 1 to 10, to keep it simple.

Second: What my code now does , is for each cell (after receiving a random number) to FIRST ASSUME the number in question IS a prime number and color the cell red. This assumption is furthermore tested by dividing the given number with 2 then 3 then…. up to the given number1. If one of those checks proves to be positive, i.e. the mod is equal to zero, the format of the cell is cleared and the next cell undergoes the same mechanism.
Just wanted to share this insight 🙂
“
Sub matrix()
Cells.ClearContents
Cells.ClearFormats
Dim xMax As Integer, yMax As Integer, x As Integer, y As Integer, z As Integer
xMax = InputBox("Anzahl Spalten")
yMax = InputBox("Anzahl Spalten")
Randomize
For x = 1 To xMax
Cells(1 + x, 1) = x
For y = 1 To yMax
Cells(1, 1 + y) = y
Cells(1 + x, 1 + y) = Int(Rnd() * 10 + 1)
z = 2
Do While z < Cells(1 + x, 1 + y).Value
Cells(1 + x, 1 + y).Select
ActiveCell.Interior.Color = vbRed
If Cells(1 + x, 1 + y) Mod z = 0 Then
Cells(1 + x, 1 + y).Select
ActiveCell.ClearFormats
Exit Do
End If
z = z + 1
Loop
Next y
Next x
End Sub
Answer：
Just found another problem: 2s are ignored, since the loop only works, if z is < 2. However, I corrected this by simply check if the number is two before the loop. If this is the case, the loop will be skipped:
Sub matrix()
Cells.ClearContents
Cells.ClearFormats
Dim xMax As Integer, yMax As Integer, x As Integer, y As Integer, z As Integer
xMax = 10 'InputBox("Anzahl Spalten")
yMax = 10 'InputBox("Anzahl Spalten")
Randomize
For x = 1 To xMax
Cells(1 + x, 1) = x
For y = 1 To yMax
Cells(1, 1 + y) = y
Cells(1 + x, 1 + y) = Int(Rnd() * 10 + 1)
If Cells(1 + x, 1 + y).Value = 2 Then
Cells(1 + x, 1 + y).Interior.Color = vbRed
GoTo Skip
End If
z = 2
Do While (z < Cells(1 + x, 1 + y).Value)
Cells(1 + x, 1 + y).Interior.Color = vbRed
If (Cells(1 + x, 1 + y).Value Mod z = 0) And (Cells(1 + x, 1 + y).Value <> 2) Then
Cells(1 + x, 1 + y).ClearFormats
Exit Do
End If
z = z + 1
Loop
Skip:
Next y
Next x
End Sub
Tags: excelexcel, oop, vba