I have to print the sequential 25 prime numbers after I ask the user to input a number. The code below indeed does print prime numbers but it prints empty spaces. I can't figure out how to make it print ONLY the prime numbers and no empty spaces. I have this thus far:
Public Function IsPrime(value)
Dim remainder As Double
Dim rounded As Long
Dim Max As Long
Dim j As Long
IsPrime = 0
Max = 1 + Int(value / 2)
For j = 2 To Max
rounded = Int(value / j)
remainder = (value / j) - rounded
If remainder = 0 Then
Exit For
End If
Next j
If j = Max + 1 Or value = 2 Then
IsPrime = 1
End If
If value <= 1 Then
IsPrime = 0
End If
End Function
Public Sub printprime()
Dim x As Integer
Dim row As Integer
Dim col As Integer
Dim j As Integer
Dim matrix1(1 To 5, 1 To 5) As Integer
x = InputBox("Please enter a number ")
j = 1
For row = 1 To 5
For col = 1 To 5
If IsPrime(x + j) = 1 Then
Cells(row, col) = x + j
matrix1(row, col) = Cells(row, col)
End If
j = j + 1
Next col
Next row
You just need to keep going and only record the primes:
Public Sub printprime()
Dim x As Long
Dim row As Long
Dim col As Long
Dim j As Long
x = InputBox("Please enter a number ")
row = 1
col = 1
For j = x + 1 To 9999
If IsPrime(j) Then
Cells(row, col) = j
col = col + 1
If col = 6 Then
col = 1
row = row + 1
End If
If row = 7 Then Exit Sub
End If
Next j
End Sub
Here's my version
Sub print_prime()
Dim i As Integer
Dim j As Integer
Dim if_prime As Boolean
Dim Count
Count = InputBox("Enter Max Number")
For i = 2 To Count
if_prime = True
If i = 2 Then GoTo nextItem
For j = 2 To i - 1
If i Mod j = 0 Then
if_prime = False
GoTo nextItem
End If
Next j
nextItem:
If if_prime Then Debug.Print i
Next i
End Sub
Related
I want to sort below Two-digit array by VBA code
A 1
B 2
A 1
C 3
or below:
1 A
2 B
1 A
3 C
I have tried to sort them by Dictionary, but, Dictionary is not allowed to insert duplate key.
Is there any want to sort above array by number 1,2,3
I made this some time ago, it might help.
Function ArraySorter(ByVal RecArray As Variant, Optional ByVal RefCol As Integer = 0) As Variant
Dim Menor As String
Dim NewArray() As Variant
Dim i As Double, j As Double
Dim menorIndex As Double
Dim NewArrayIndex() As Double
Dim UsedIndex() As Double
ReDim NewArrayIndex(UBound(RecArray, 2))
ReDim NewArray(UBound(RecArray), UBound(RecArray, 2))
For i = 0 To UBound(NewArrayIndex)
NewArrayIndex(i) = -1
Next i
UsedIndex = NewArrayIndex
For i = 0 To UBound(RecArray, 2)
Menor = ""
menorIndex = -1
For j = 0 To UBound(RecArray, 2)
If UsedIndex(j) = -1 Then
If Menor = "" Then
Menor = RecArray(RefCol, j)
menorIndex = j
Else
If RecArray(RefCol, j) < Menor Then
Menor = RecArray(RefCol, j)
menorIndex = j
End If
End If
End If
Next j
UsedIndex(menorIndex) = 1
NewArrayIndex(i) = menorIndex
Next i
For i = 0 To UBound(NewArrayIndex)
For j = 0 To UBound(NewArray)
NewArray(j, i) = RecArray(j, NewArrayIndex(i))
Next j
Next i
ArraySorter = NewArray
End Function
If you have something like:
Function testArraySorter()
Dim myArr() As Variant
ReDim myArr(1, 3)
myArr(0, 0) = "A"
myArr(0, 1) = "B"
myArr(0, 2) = "A"
myArr(0, 3) = "C"
myArr(1, 0) = 1
myArr(1, 1) = 2
myArr(1, 2) = 1
myArr(1, 3) = 3
myArr = ArraySorter(myArr)
For i = 0 To UBound(myArr, 2)
Debug.Print myArr(0, i), myArr(1, i)
Next i
End Function
you'll get this in your immediate verification :
A 1
A 1
B 2
C 3
If you need to sort based in two or more columns, you could add a dummy column into your array, concatenate the criteria columns into it and then set this dummy column as RefCol: myArr = ArraySorter(myArr, addedColNumberHere).
Hope this helps.
I'm a bit new with Visual Basic and I'm trying to make a program that would generate random numbers from 1 to 9 without repetition using arrays. I've also read that instead of using GoTo statements (as they are generally frowned upon), Do While Loop or While End While Statements could be used. I've tried using these loops but have not made it work. Here is the code:
Dim x As Integer = 0, y As Integer = 0, num As Integer = 0, arr(8) As Integer
lstLoop.Items.Clear()
For x = 0 To 8
Start:
Randomize()
num = Fix(Rnd() * 9) + 1
For y = 0 To 8
If num = arr(y) Then
GoTo Start
End If
Next
arr(x) = num
lstLoop.Items.Add(arr(x))
Next
The idea is to loop while you have found the number in the array:
Sub GenerateRandom()
Dim x As Integer
Dim num As Integer
Dim arr(8) As Integer
Randomize Timer
For x = 0 To 8
Do
num = Fix(Rnd() * 9) + 1
Loop While FindInArray(arr, x - 1, num)
arr(x) = num
Next x
End Sub
Function FindInArray(arr() As Integer, maxIndex As Integer, num As Integer) As Boolean
Dim i As Integer
FindInArray = False
For i = 0 To maxIndex
If arr(i) = num Then
FindInArray = True
Exit Function
End If
Next
End Function
use dictionary.
Sub test()
Dim dic As Object
Dim n As Integer
Dim Num As Integer
Set dic = CreateObject("Scripting.Dictionary")
Do Until n = 9
num = WorksheetFunction.RandBetween(1, 9)
If dic.Exists(num) Then
Else
n = n + 1
dic.Add num, num
End If
Loop
Range("a1").Resize(1, 9) = dic.Keys
End Sub
or
Sub test()
Dim dic As Object
Dim Num As Integer
Set dic = CreateObject("Scripting.Dictionary")
Do Until dic.Count = 9
num = WorksheetFunction.RandBetween(1, 9)
If dic.Exists(num) Then
Else
dic.Add num, num
End If
Loop
Range("a1").Resize(1, 9) = dic.Keys
End Sub
Never used VBA before and basically just trying write this sub:
Sub Populate_Empties()
Dim i As Integer
Dim j As Integer
Dim n As Integer
Dim m As Integer
Dim k As Integer
' test for 50 rows...then change i from 2 to 278970
m = 2
For k = 3 To 8
For i = 2 To 50
If (IsEmpty(Cells(i, k).Value)) Then
m = i 'any statement
Else
j = i - 1
For n = m To j
Cells(n, k).Value = Cells(i, k).Value
m = i + 1
End If
End Sub
I keep getting error End If without Block
Any suggestions?
You're missing the closing statements on your for loops
Sub Populate_Empties()
Dim i As Integer
Dim j As Integer
Dim n As Integer
Dim m As Integer
Dim k As Integer
' test for 50 rows...then change i from 2 to 278970
m = 2
For k = 3 To 8
For i = 2 To 50
If (IsEmpty(Cells(i, k).Value)) Then
m = i 'any statement
Else
j = i - 1
For n = m To j
Cells(n, k).Value = Cells(i, k).Value
Next n
m = i + 1
End If
Next i
Next k
End Sub
This is an error I've been trying to figure out for awhile now, my find method is not producing any results and I cannot figure out why.
The code is suppose to search InputSheet for a string, report the row number and start moving information over to Background based on that row number. Then the next .find will find the string in SummaryResults and start moving information from Background, reformat it a bit, and paste to SummaryResults.
My find method is not producing any results and leaves FindRow = Nothing even though the strings are present in the sheets and in the correct Ranges.
This error started occurring after running the macro with another Excel sheet open so maybe the ActiveWorkbook was incorrect, but I have not been able to get it to run since.
Some of the variables shown are from other sections of the code but when I hover over them in the debug mode they are showing what they're suppose to.
Option Explicit
Sub CAESARCONVERSION()
Dim InputSheet As Worksheet, SummaryResults As Worksheet, Background As Worksheet
Dim i As Integer
Dim j As Integer
Dim x As Integer
Dim y As Integer
Dim h As Integer
Dim v As Integer
Dim c As Integer
Dim z As Integer
Dim myBook As Workbook
Set myBook = Excel.ThisWorkbook
Set InputSheet = myBook.Sheets("Input Sheet")
Set SummaryResults = myBook.Sheets("Summary Results")
Set Background = myBook.Sheets("Background")
Dim NodeList As Integer
Dim TotalCases As Integer
Dim sMyString As String
Dim Nodes As Variant
Dim FindRow As Range
Dim intValueToFind As String
Dim FindRowNumber As Long
Dim SecondRowNumber As Long
'Clear the last run of macro
Background.Range("A2:A1000").Cells.Clear
Background.Range("C2:I10000").Cells.Clear
SummaryResults.Cells.Clear
'Code that will count the total number of load cases
TotalCases = 0
h = 2
Dim text As String
For v = 12 To 100
If InputSheet.Cells(v, 2).Value <> "" Then
text = LTrim(InputSheet.Cells(v, 2).Value)
Background.Cells(h, 3).Value = text
h = h + 1
TotalCases = TotalCases + 1
Else
GoTo NodeCounter
End If
Next v
NodeCounter:
y = TotalCases - 1
x = 0
Dim LoadCaseList() As Variant
ReDim LoadCaseList(y)
LoadCaseList:
For x = 0 To y
LoadCaseList(x) = Background.Cells(2 + x, 3).text
Next x
j = 2
For i = 17 + TotalCases To 20000 'Need to define how far for the program to search, we may exceed 20000 at some point
If InputSheet.Cells(i, 2).Value <> "" Then
Background.Cells(j, 1).Value = InputSheet.Cells(i, 2).Value
j = j + 1
End If
Next i
With Background
NodeList = Background.Cells(2, 2).Value
Background.Range("AA1:XX" & NodeList + 1).Cells.Clear
End With
ReDim Nodes(NodeList - 1)
v = 0
j = 2
For i = 0 To NodeList - 1
Nodes(i) = Background.Cells(j, 1).Value
j = j + 1
Next i
Headers:
Dim LoadCaseHeader() As String
Dim TypHeader()
TypHeader = Array("Node", "L", "Direction", "Magnitude")
Dim LoadDirections()
LoadDirections = Array("X", "Y", "Z", "MX", "MY", "MZ")
x = 0
z = 0
For x = 0 To NodeList - 1
For z = 0 To TotalCases - 1
SummaryResults.Range(("B" & 2 + (NodeList * 6 + 2) * z) & ":" & "E" & 2 + (NodeList * 6 + 2) * z) = TypHeader()
SummaryResults.Range("A" & 2 + (NodeList * 6 + 2) * z) = Background.Range("C" & 2 + z)
Next z
Next x
'Search rows for the first instance of this value.
LoadCases:
'Code that copies information from the InputSheet to the SummaryResults
Dim LoadCases() As Long
ReDim LoadCases(NodeList, 6)
FindRowNumber = 0
SecondRowNumber = 0
For c = 0 To y
intValueToFind = LoadCaseList(c)
For i = 7 To 31 + TotalCases
With InputSheet
If Trim(Cells(i, 3).Value) = intValueToFind Then
MsgBox ("Found")
Set FindRow = InputSheet.Range("C:C").Find(What:=intValueToFind, LookIn:=xlValues)
FindRowNumber = FindRow.Row
End If
End With
Next i
'MsgBox FindRowNumber
With InputSheet
For i = 0 To NodeList - 1
x = 4
For j = 0 To 5
LoadCases(i, j) = InputSheet.Cells(FindRowNumber + (TotalCases + 3) * i, x)
x = x + 1
Next j
Next i
End With
Background.Range("AC2:AH" & NodeList + 1).Offset(0, c * 7) = LoadCases
For i = 1 To NodeList * 6 * TotalCases
With SummaryResults
If Trim(Cells(i, 5).Value) = intValueToFind Then
Set FindRow = SummaryResults.Range("A:A").Find(What:=intValueToFind, LookIn:=xlValues)
SecondRowNumber = FindRow.Row
GoTo Step2
End If
End With
Next i
Step2:
With SummaryResults
For x = 0 To NodeList - 1
For j = 0 To 5
SummaryResults.Cells(SecondRowNumber + 1 + j + 6 * x, 5) = Background.Cells(x + 2, 29 + j)
SummaryResults.Cells(SecondRowNumber + 1 + j + 6 * x, 3) = TypHeader(1)
SummaryResults.Cells(SecondRowNumber + 1 + j + 6 * x, 4) = LoadDirections(j)
SummaryResults.Cells(SecondRowNumber + 1 + j + 6 * x, 2) = Nodes(x)
Next j
Next x
End With
Next c
End Sub
Any help would be appreciated. EDIT: Uploaded the entire code. Additional information, the code works when not tabbed into excel but will fail when tabbed in a ran again.
The issue seems to be that the LoadCaseList() array is never getting populated. This is your Find statement:
Set FindRow = InputSheet.Range("C:C").Find(What:=intValueToFind, LookIn:=xlValues)
intValueToFind is set by this statement:
intValueToFind = LoadCaseList(c)
But the LoadCaseList() array is populated by the following code which is a label that is never called by a GoTo statement (as far as I can tell):
LoadCaseList:
For x = 0 To y
LoadCaseList(x) = Background.Cells(2 + x, 3).text
Next x
So because the LoadCaseList label statement is never being called by a GoTo statement, the LoadCaseList() array is never being populated so intValueToFind has no value and therefore the Find method has no value to search for (except for maybe the empty string).
I have a function in VBA that makes a few operations by calling other smaller functions. This function doesn't work in any sheets, just in one. In the sheets it doesn't work it just gets out of the whole algorithm when getting the value from another function.
This is my Function determinarCantidadPorPedido(ByVal material As String, ByVal mes As String)
Dim demanda As Double
Dim pProgramado As Double
Dim numPedidos As Integer
demanda = determinarDemanda(material, mes)
Call contarProductosMateriales
Sheets("LlegadaMateriales").Activate
Dim fila As Integer
Dim columna As Integer
For i = 1 To numMateriales Step 1
If Sheets("LlegadaMateriales").Cells(1 + i, 1) = material Then
fila = 1 + i
Exit For
End If
Next
For j = 1 To 12 Step 1
If Sheets("LlegadaMateriales").Cells(1, j + 1) = mes Then
columna = j + 1
Exit For
End If
Next
pProgramado = Sheets("LlegadaMateriales").Cells(fila, columna)
numPedidos = darCantidadPedidos(determinarDiasMes(mes), darLeadTime(material))
determinarCantidadPorPedido = WorksheetFunction.Round((demanda - pProgramado) / numPedidos, 0)
and it calls Public Function determinarDemanda(ByVal material As String, ByVal mes As String) As Double
Dim filaProducto As Double
Dim numMat As Double
Dim columnaDemanda As Double
Worksheets("ProductosYMateriales").Activate
numMat = Sheets("ProductosYMateriales").Range(Cells(3, 1), Cells(3, 1).End(xlDown)).Rows.Count
For i = 1 To numMat Step 1
If Sheets("ProductosYMateriales").Cells(i + 2, 1) = material Then
filaProducto = i + 2
Exit For
End If
Next
For j = 1 To 12 Step 1
If Sheets("Demanda").Cells(1, j + 2) = mes Then
columnaDemanda = j + 2
Exit For
End If
Next
Dim numProd As Double
numProd = Sheets("ProductosYMateriales").Range(Cells(2, 2), Cells(2, 2).End(xlToRight)).Columns.Count
Dim demanda As Double
demanda = 0
For k = 1 To numProd Step 1
Dim x As Double
x = Sheets("Demanda").Cells(k + 1, columnaDemanda)
Dim y As Double
y = Sheets("ProductosYMateriales").Cells(filaProducto, k + 1)
Dim prod As Double
prod = x * y
demanda = demanda + prod
Next
determinarDemanda = demanda
and Function determinarCantidadPorPedido(ByVal material As String, ByVal mes As String)
Dim demanda As Double
Dim pProgramado As Double
Dim numPedidos As Integer
demanda = determinarDemanda(material, mes)
Call contarProductosMateriales
Sheets("LlegadaMateriales").Activate
Dim fila As Integer
Dim columna As Integer
For i = 1 To numMateriales Step 1
If Sheets("LlegadaMateriales").Cells(1 + i, 1) = material Then
fila = 1 + i
Exit For
End If
Next
For j = 1 To 12 Step 1
If Sheets("LlegadaMateriales").Cells(1, j + 1) = mes Then
columna = j + 1
Exit For
End If
Next
pProgramado = Sheets("LlegadaMateriales").Cells(fila, columna)
numPedidos = darCantidadPedidos(determinarDiasMes(mes), darLeadTime(material))
determinarCantidadPorPedido = WorksheetFunction.Round((demanda - pProgramado) / numPedidos, 0)
One Problem is in this Line:
numMat = Sheets("ProductosYMateriales").Range(Cells(3, 1), Cells(3, 1).End(xlDown)).Rows.Count
when you call Cells, this reference the current active sheet. Therefore you will get different results, if you call the function on different sheets.
You will have to specify from what sheets you want to reference the cells. I guess you want this:
numMat = Sheets("ProductosYMateriales").Range(Sheets("ProductosYMateriales").Cells(3, 1), Sheets("ProductosYMateriales").Cells(3, 1).End(xlDown)).Rows.Count