在vba中使用循环创建值并将其存储在工作表中的列中吗?

时间:2018-07-10 12:20:32

标签: excel excel-vba

我正在尝试计算速度和加速度,变量为时间t。我想用vba编写这些文件,以使其更快,因为稍后我将需要速度和加速度来进行其他几种结合了不同逻辑条件的计算。我希望将结果打印在工作表中,以便在计算过程中再次检查结果是否现实。

更多或更少希望的示例

t        vel          a

0.002   39        -777
0.004   38.6      -802
0.006   35        -500
0.008   33.4      -400
0.01    32.1      -12297.1

所以我根据评论尝试了一些不同的事情: 我认为从结果来看,第一个代码示例可以很好地工作,但是我仍然可以看到介于两者之间的任何结果,所以主要的问题是:我有什么机会可以改变对写到工作表的建议,而无需进行其他更改?

第二个代码示例是尝试将所有内容都写入数组:我确实理解了我认为的原理,但是这里的主要错误似乎是我的变量t没有正确生成,因此没有计算公式:can找不到错误,在此感谢您提供更多帮助...

Kinematics Calculation

'Set t from 0 to 2 s with time step of 0.002s; Calculate Rot_vel until <= 0, 
'Find index t_2 when Rot_vel <= 0
t = 0
Do

t = t + 0.002

Rot_vel = -10356# * t ^ 6 + 24130# * t ^ 5 - 19002# * t ^ 4 + 4933# * t ^ 3 + 
362# * t ^ 2 - 213# * t + 39
    Worksheets("test").Range(Cells(3, 2), Cells(1003, 2)) = Rot_vel

Loop Until Rot_vel <= 0


If Rot_vel <= 0 Then

t_2 = t

    If t_2 > 0 Then
       Debug.Print t_2
    End If
 End If

'Continue calculations for t 0 to t_2 with 0.002 steps
t = 0
Do

t = t + 0.002

    A_rot = -62136# * t ^ 5 + 120650# * t ^ 4 - 76008# * t ^ 3 + 14797.8 * t 
 ^ 2 + 723.26 * t - 212.7                                                                                                    


    Worksheets("test").Range(Cells(3, 3), Cells(1003, 3)).value = A_rot

    L = MoI * Rot_vel / 1000
    M = MoI * A_rot / 1000

    Worksheets("test").Range(Cells(3, 8), Cells(1003, 8)).value = L
    Worksheets("test").Range(Cells(3, 9), Cells(1003, 9)).value = M

    G = L / t_2
    Worksheets("test").Range(Cells(3, 10), Cells(1003, 10)).value = G


 Loop Until t = t_2

第二个版本:

Kinematics Calculation

'Set t from 0 to 2 s with time step of 0.002s; Calculate Rot_vel until <= 0, 
'Find index t_2 when Rot_vel <= 0

Dim arrCalc As Variant
Dim i As Integer
Dim j As Integer

ReDim arrCalc(i To 1003, j To 13)

For i = LBound(arrCalc, 2) To UBound(arrCalc, 2)

t = 0
Do
t = t + 0.002

    arrCalc(i, 1) = t

    arrCalc(i, 2) = -10356# * t ^ 6 + 24130# * t ^ 5 - 19002# * t ^ 4 + 4933# 
  * t ^ 3 + 362# * t ^ 2 - 213# * t + 39                    'Rot_vel

Loop Until arrCalc(i, 2) < 0

Dim pos, val
val = 0
pos = Application.Match(val, arrCalc(i, 2), False)
pos = t_2


t = 0
Do
t = t + 0.002

    arrCalc(i, 3) = -62136# * t ^ 5 + 120650# * t ^ 4 - 76008# * t ^ 3 + 
    14797.8 * t ^ 2 + 723.26 * t - 212.7

    arrCalc(i, 8) = MoI * Rot_vel / 1000      'L                                                                                       


    arrCalc(i, 9) = MoI * A_rot / 1000    'M                                                                                        


    arrCalc(i, 10) = 1 / t_2 * L     'G                                                                                           


Loop Until t = t_2

Next i

With Worksheets("test")

    .Cells(2, "A") = 0
    .Cells(3, "A").Resize(UBound(arrCalc, 1), UBound(arrCalc, 2)) = Rot_vel
    .Cells(2, "A").Resize(UBound(arrCalc, 1) + 1, 1) = t
    '.Cells(3, "C").Resize(UBound(arrCalc, 1), UBound(arrCalc, 3)) = A_rot

End With

2 个答案:

答案 0 :(得分:1)

您的变量a_rot和rot_val在我看来并不像数组,而是普通变量。因此,只有一个值存储在其中,当然,您只能得到一个值作为输出。

我看到两个选择:1)您将所有值写入一个数组,然后将该数组复制到工作表中。 2)您将每一计算行逐行写入工作表。 1号)要快得多。

解决方案可能看起来像这样:

fetchType

答案 1 :(得分:1)

使用时间和计算结果构建二维数组,然后将结果转储到工作表中。

顺序时间很容易发生15 significant digit floating point errors。可以使用基准尺寸标注的形式将这些误差减至最小,该尺寸标注将创建相对于原始起点而不是先前值的所有新条目。前一种方法的误差不会大于单个计算,而后一种方法则可以通过将误差带入下一个计算来复合误差。

Sub kinematicsCalculation()
    Dim t As Double, start As Double, i As Long, arr As Variant

    start = TimeSerial(0, 0, 0)   'start at 0 second mark
    ReDim arr(1 To 1000, 1 To 2)

    For i = LBound(arr, 1) To UBound(arr, 1)
        arr(i, 1) = start + TimeSerial(0, 0, 2 * i) / 1000
        'cannot attempt velocity calc without Rot_vel_i
        arr(i, 2) = "<velocity calculation here>"
    Next i

    With Worksheets("sheet")
        .Cells(2, "B") = start
        .Cells(3, "B").Resize(UBound(arr, 1), UBound(arr, 2)) = arr
        .Cells(2, "B").Resize(UBound(arr, 1) + 1, 1).NumberFormat = "[hh]:mm:ss.000"
    End With
End Sub