Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过VBA编码写入1到100之间的素数_Vba_Excel_Primes - Fatal编程技术网

通过VBA编码写入1到100之间的素数

通过VBA编码写入1到100之间的素数,vba,excel,primes,Vba,Excel,Primes,我发现下面的代码,但它不工作。请分享在VBA中编写素数的更合适的代码 Private Sub cmdPrime_Click() Dim p, n, i As Integer p = 1 Print “Prime Numbers are : ” For n = 1 To 100 For i = 2 To n – 1 If n Mod i = 0 Then p = 0 Exit For Else p = 1 End If Next If p = 1 Then Print n End If Nex

我发现下面的代码,但它不工作。请分享在VBA中编写素数的更合适的代码

Private Sub cmdPrime_Click()
Dim p, n, i As Integer
p = 1
Print “Prime Numbers are : ”
For n = 1 To 100
For i = 2 To n – 1
If n Mod i = 0 Then
p = 0
Exit For
Else
p = 1
End If

Next
If p = 1 Then
Print n
End If

Next
End Sub

我猜你是从另一种语言翻译过来的?你真的应该指出哪些线路失败了,你研究了什么

:智能引号。这是在应用程序之间进行复制时的典型情况,因此要小心。在visual basic编辑器中使用的语音标记必须是
,才能进行编译

如果将
Option Explicit
放在代码的顶部,那么它会对变量声明和拼写给出很多很好的警告

您只需要输入100,因此
Integer
是可以的,但是在本例中
Integer
Long
没有任何优势,因此如果您将来决定超出
Integer
的容量,则使用
Long
会更安全,从而有溢出的风险。在足够高的上限下,您还需要计算出
mod

如果除数(第二个参数)为 在MOD函数中),乘以134217728小于或等于 要计算的数字(MOD中的第一个参数 功能)

微软建议重新使用
=number-(INT(数字/除数)*除数)
;我想你可以用
CLng
替换
INT
,以保持长

Option Explicit
Private Sub cmdPrime_Click()
    Dim p As Long, n As Long, i As Long, iCounter As Long
    p = 1
    With ActiveSheet
        .Cells(iCounter + 1, 1) = "Prime Numbers are: " 'Debug.Print "Prime Numbers are: "
        For n = 2 To 100 ''< As pointed out 1 is not technically a prime btw so can start at 2
            For i = 2 To n - 1
                If n Mod i = 0 Then              ' If n - (CLng(n / i) * i) = 0 Then
                    p = 0
                    Exit For
                Else
                    p = 1
                End If
            Next
            If p = 1 Then
                iCounter = iCounter + 1
                .Cells(iCounter, 1) = n  'Debug.Print n  
            End If
        Next
    End With
End Sub
选项显式
私有子cmdPrime_Click()
变暗p为长,n为长,i为长,i为长
p=1
使用ActiveSheet
.Cells(iCounter+1,1)=“素数为:”'Debug.Print“素数为:
对于n=2到100''<如前所述,1在技术上不是主要btw,因此可以从2开始
对于i=2到n-1
如果n模i=0,则‘如果n-(CLng(n/i)*i)=0,则
p=0
退出
其他的
p=1
如果结束
下一个
如果p=1,则
i计数器=i计数器+1
.Cells(i计数器,1)=n'调试.Print n
如果结束
下一个
以
端接头
为未来读者保留:其他有用的评论来自@ChrisNeilsen


要测试
n
是否为素数,只需测试
n
的平方根的可除性。你只需要测试之前检测到的素数的可除性。您甚至可以跳过
n

的值,这是一个稍微高效的代码版本。修改了两件事:

a) 因为1是,所以外部循环从2开始

b) 默认情况下,该数字被视为素数。如果它被检测为非素数,则停止进一步的检查。(在公布的代码中,每次检查检测到一个数字为非素数时,都会设置值p=1。每次设置p=1时增加一个计数器,表明它被设置了1059次。)

输出:

 2 
 3 
 5 
 7 
 11 
 13 
 17 
 19 
 23 
 29 
 31 
 37 
 41 
 43 
 47 
 53 
 59 
 61 
 67 
 71 
 73 
 79 
 83 
 89 
 97 

在复习VBA技能时遇到这个问题。这是我的解决方案,使用算法进行优化,忽略所有偶数和5的除数

我创建了两个模块,用于分离逻辑和实用程序功能。大约在
10秒内打印第一个
100000
素数

模块1(素数):

Option Explicit

Sub PrintPrimes()

Dim count As Long
Dim s As Object
Dim primes As New ArrayList
Dim startTime As Date
Dim endTime As Date

startTime = Now

Set s = Sheet1.Cells
count = s(1, 2) - 1

Set primes = GetPrimeList(count)

PrintArray primes, "Sheet1", 2
endTime = Now

s(1, 3) = "Elapsed time: " & ElapsedTime(endTime, startTime)

End Sub

Function GetPrimeList(count) As ArrayList

Dim primeList As New ArrayList
Dim i As Long
Dim currentInt As Long

i = 2
primeList.Add (2)
currentInt = 3

Do While (primeList.count <= count)
    If IsPrime(currentInt) Then primeList.Add (currentInt)
    currentInt = currentInt + 2 'ignore even numbers
Loop

Set GetPrimeList = primeList

End Function

Function IsPrime(number)

Dim i As Long
Dim maxValidator As Long
Dim possiblePrime As Boolean

i = 3
IsPrime = True
possiblePrime = False
maxValidator = Round_Up(Sqr(number))

If number = 3 Then
    IsPrime = True
    Exit Function
ElseIf number Mod 5 = 0 And number > 5 Then
    IsPrime = False
    Exit Function
End If

If (number Mod 6 = 1 Or number Mod 6 = 5) Then possiblePrime = True

If possiblePrime Then
    Do While (i <= maxValidator)
        If number Mod i = 0 Then
            IsPrime = False
            Exit Do
        End If
        i = i + 2 'ignore even divisors
    Loop
Else
    IsPrime = False
End If

End Function

Option Explicit

Function Round_Up(ByVal d As Double) As Long
    Dim result As Long
    result = Math.Round(d)
    If result >= d Then
        Round_Up = result
    Else
        Round_Up = result + 1
    End If
End Function

Function PrintArray(Data, SheetName As String, intStartRow As Integer)

    Dim oWorksheet As Worksheet
    Dim item As Variant
    Dim i As Long
    Set oWorksheet = ActiveWorkbook.Worksheets(SheetName)

    i = intStartRow
    For Each item In Data
        oWorksheet.Cells(i, 1) = item
        i = i + 1
    Next

End Function

Function ElapsedTime(endTime As Date, startTime As Date)
    Dim strOutput As String
    Dim Interval As Date

    ' Calculate the time interval.
    Interval = endTime - startTime

    ' Format and print the time interval in days, hours, minutes and seconds.
    strOutput = Int(CSng(Interval)) & " days " & Format(Interval, "hh") _
        & " Hours " & Format(Interval, "nn") & " Minutes " & _
        Format(Interval, "ss") & " Seconds"
    ElapsedTime = strOutput

End Function

输入要在单元格中列出的素数数
B1

Alt+F8
,然后选择
PrintPrimes
(默认情况下应选中),然后单击
Run

瞧!素数列表将从单元格
A2
打印。 单元格
A1
留空,供用户输入,如输入要打印的素数

注意: 我使用了
Long
数据类型来覆盖更多的值,而不是
Integer
。如果需要打印的值多于
2147483647
,则只需将
Long
替换为
PrimeNumber
模块中的
Double
。如果使用
Double
数据类型,您将看到显著的性能下降


PS:确保使用链接提前绑定mscorlib.dll

非常感谢您的回复。这个代码现在起作用了。但是,如果我需要excel电子表格中的输出,而不是即时窗口中的输出,该怎么办。你能提供代码吗?@QHarr:你真的想让
p
n
成为
变体吗?@AJD我绝对没有。让我看一眼!谢谢。有两点:要测试n是否为素数,只需测试n的平方根。你只需要测试之前检测到的素数的可除性。您甚至可以跳过n@chrisneilsen谢谢我已在中添加了您的评论。我已经看到了Euler项目和Eratosthenes筛的一些很好的实现。非常感谢您的回复。这个代码现在起作用了。但是,如果我需要excel电子表格中的输出,而不是即时窗口中的输出,该怎么办。您可以提供代码吗?您可以将此代码添加到输出
i
的行中<代码>单元格(行、列)=i
。然后执行
row=row+1
。在开始循环之前初始化
。从我这里获取+1。
Option Explicit

Function Round_Up(ByVal d As Double) As Long
    Dim result As Long
    result = Math.Round(d)
    If result >= d Then
        Round_Up = result
    Else
        Round_Up = result + 1
    End If
End Function

Function PrintArray(Data, SheetName As String, intStartRow As Integer)

    Dim oWorksheet As Worksheet
    Dim item As Variant
    Dim i As Long
    Set oWorksheet = ActiveWorkbook.Worksheets(SheetName)

    i = intStartRow
    For Each item In Data
        oWorksheet.Cells(i, 1) = item
        i = i + 1
    Next

End Function

Function ElapsedTime(endTime As Date, startTime As Date)
    Dim strOutput As String
    Dim Interval As Date

    ' Calculate the time interval.
    Interval = endTime - startTime

    ' Format and print the time interval in days, hours, minutes and seconds.
    strOutput = Int(CSng(Interval)) & " days " & Format(Interval, "hh") _
        & " Hours " & Format(Interval, "nn") & " Minutes " & _
        Format(Interval, "ss") & " Seconds"
    ElapsedTime = strOutput

End Function