【问题标题】:Determine number of elements in array确定数组中的元素数
【发布时间】:2016-06-21 07:59:05
【问题描述】:

我知道,标题暗示了一个简单的答案。不过,请仔细阅读。在我的本科学习中,我有一门名为计算数学和数值分析的课程,在那里我学习了 C++。现在我昨天开始用 VBA 编码 - 只是为了好玩。我试图制作一个程序,可以计算多项式的根。经过一番来回,我设法写下了所有代码。我要做的最后一件事是在 Excel 中打印所有根。为此,我使用了一个名为“arroot”的数组。下面的子是我的主要:

Sub Main()
    Dim fx As Double, Dim dffx As Double, Dim n As Integer
    Dim x As Double, Dim root As Double, Dim arroot()
    Dim a(15) As Long, Dim i As Integer

    Sheet1.Cells.ClearContents
    Call PolyCoef(n, a)
    i = 0
    Do
         Call Table(n, a, x, fx, dffx)
         Call NewRapHorner(n, a, fx, dffx, root)
         Call HornerDivPol(n, a, root)
         arroot(i) = root
         i = i + 1
    Loop While (Not n = 0)
    Call Printroot(arroot)           
End Sub

您可以看到,我将值保存在数组中,始终更新“i”以确保获得每个值。负责打印根的代码如下:

Private Sub Printroot(arroot())

    Sheet1.Range("G3").Value = "Root"
    Sheet1.Range("H3").Value = "x-value"
    For i = 0 To UBound(arroot()) Step 1
        Sheet1.Range("G" & 4 + i).Value = i + 1 & ". root"
        Sheet1.Range("H" & 4 + i).Value = arroot(i)
    Next
End Sub

我的问题: 执行此操作时,我遇到了问题 - 代码无法运行。当我将数组定义为 Dim arroot (15) 时,代码有效。唯一的问题是,我打印了太多的 'i + 1 & ".root"'s。我该如何解决这个问题?我希望我的数组与根数一样大。如果这样说有意义的话:我希望数组的括号以某种方式为空,因此它会自动调整。

提前谢谢你!

编辑:

根据要求,这是完整的代码:

Sub Main()
    Dim fx As Double, Dim dffx As Double, Dim n As Integer
    Dim x As Double, Dim root As Double, Dim arroot(15)
    Dim a(15) As Long, Dim i As Integer

    Sheet1.Cells.ClearContents
    Call PolyCoef(n, a)
    i = 0
    Do
        Call Table(n, a, x, fx, dffx)
        Call NewRapHorner(n, a, fx, dffx, root)
        Call HornerDivPol(n, a, root)
        arroot(i) = root
        i = i + 1
    Loop While (Not n = 0)
    Call Printroot(arroot)    
End Sub

'Main Ends. Subs used in main are defined:

Private Sub PolyCoef(n As Integer, a() As Long)
    Dim e As Integer

    Sheet1.Range("A1").Value = "Enter n for polynomial"
    Sheet1.Range("B1").Value = InputBox("Enter n", "Degree of the polynomial")
    n = Sheet1.Range("B1").Value
    e = n
    Sheet1.Range("A3").Value = "Coefficients:"
    Sheet1.Range("B3").Value = "Values:"

    For i = 0 To n Step 1
        Sheet1.Range("A" & i + 4).Value = i + 1 & ". coefficient, a" & e
        Sheet1.Range("B" & i + 4).Value = InputBox("Enter coefficient", i + 1 & ". coefficient")
        a(i) = Sheet1.Range("B" & i + 4).Value
        e = e - 1
    Next
End Sub


Private Sub Horner(n As Integer, a() As Long, x As Double, fx As Double, dffx As Double)
    Dim e As Integer, Dim b(15), Dim c(15)

    b(0) = a(0)
    For i = 1 To n Step 1
        b(i) = a(i) + x * b(i - 1)
    Next
    c(0) = b(0)
    For i = 1 To n Step 1
        c(i) = b(i) + x * c(i - 1)
    Next
    fx = b(n)
    dffx = c(n - 1)
End Sub

Private Sub Table(n As Integer, a() As Long, x As Double, fx As Double, dffx As Double)
    Dim xmax As Double, Dim dx As Double

    x = InputBox("Enter first x-value", "Enter xmin")
    xmax = InputBox("Enter last x-value", "Enter xmax")
    dx = (xmax - x) / 19
    Sheet1.Range("D3").Value = "x-value"
    Sheet1.Range("E3").Value = "f(x)"
    For i = 0 To 19 Step 1
        Call Horner(n, a, x, fx, dffx)
        Sheet1.Range("D" & 4 + i).Value = x
        Sheet1.Range("E" & 4 + i).Value = fx
        x = x + dx
    Next
End Sub

Private Sub NewRapHorner(n As Integer, a() As Long, fx As Double, dffx As Double, root As Double)
    Dim xnew As Double, Dim xold As Double, Dim eps As Double
    Dim ite As Integer, Dim x0 As Double, Dim i As Integer

    x0 = InputBox("Enter x-value close to root", "x-value")
    eps = InputBox("Enter tolerance", "Tolerance")
    ite = InputBox("Enter number of max iterations", "Max iterations")
    i = 0
    xnew = x0
    root = 0
    Do
        xold = xnew
        Call Horner(n, a, xnew, fx, dffx)
        xnew = xnew - (fx / dffx)
        i = i + 1
    Loop While (Abs(xnew - xold) > eps And i < ite)
    If i >= ite Then
        MsgBox "Number of max iterations has been exeeded"
    Else
        root = xnew
    End If
End Sub

Private Sub HornerDivPol(n As Integer, a() As Long, root As Double)
    Dim b(15) As Long

    b(0) = a(0)
    For i = 1 To n Step 1
        b(i) = a(i) + root * b(i - 1)
    Next   
    For i = 1 To n Step 1
        a(i) = b(i)
    Next 
    n = n - 1
End Sub

Private Sub Printroot(arroot())

    Sheet1.Range("G3").Value = "Root"
    Sheet1.Range("H3").Value = "x-value"
    For i = 0 To UBound(arroot()) Step 1
        Sheet1.Range("G" & 4 + i).Value = i + 1 & ". root"
        Sheet1.Range("H" & 4 + i).Value = arroot(i)
    Next
End Sub

【问题讨论】:

  • 你试过 ReDim 吗?
  • Printroot 的代码看起来不错,应该按原样打印数组中的所有元素。您唯一可能要考虑更改的是For i = LBound(arroot) To UBound(arroot),原因如下:msdn.microsoft.com/en-us/library/aa266179(v=vs.60).aspx 因此,如果数组不包含您期望的内容,那么生成数组的代码就会出现问题(未显示在问题)。
  • @Ralph 正如文章所述,“因为默认基数是 0,所以永远不需要 Option Base 语句。”并且因为在调用 arroot(i) = root 之前 i 被设置为 0,所以下限将为零。
  • 在 VB6/VBA 中,arr(15) 的数组定义是一个长度为 16 的数组,从 0 到 15,而不是像大多数语言那样创建一个长度为 15 的数组从 0 到 14。
  • 添加...如果您声明一个带有空括号的数组,您需要在循环中的每次迭代中使用 ReDim Preserve 语句,以便分配您正在使用的数组。带空括号的数组不能包含任何内容。尝试将您的声明更改为 Dim arroot (14),这将为您提供 15 个编号为 0 到 14 的元素。

标签: arrays vba excel


【解决方案1】:

数组对于您想要在 VBA 中执行的操作不是很有效。 我建议创建一个像这样的集合:

Public yourArray As New Collection

添加相同类型的元素将动态调整其大小。下面我将展示如何将元素添加到集合中。

Public yourArray As New Collection

Sub trieal()

i = 10
Do Until i = 1
    yourArray.Add i
    i = i - 1

Loop

For Each e In yourArray
    Debug.Print (e)
Next
End Sub

这解决了循环遍历“数组”元素的问题。

【讨论】:

  • 集合从 1 开始计数,数组从 0 开始。集合用于存储对象,数组用于存储原始数据类型。集合不如数组有效。将集合命名为 yourArray 令人困惑,因为集合和数组是两个根本不同的容器。
  • 我同意你说的。我在使用问题中指出的数组时遇到了类似的问题,我认为既然这对我有用,它也可以对其他人有用。
  • 那么您根本没有正确循环数组,也没有准确地跟踪您的计数器。数组用于原始数据 - - 始终。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 2018-12-03
相关资源
最近更新 更多