Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.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
Excel 为什么嵌套数组在达到上限时表现出色?_Excel_Vba_Crash - Fatal编程技术网

Excel 为什么嵌套数组在达到上限时表现出色?

Excel 为什么嵌套数组在达到上限时表现出色?,excel,vba,crash,Excel,Vba,Crash,我有以下代码,在运行excel时会崩溃: Option Explicit Private Type Calculations x As Double x2 As Double x3 As Double x4 As Double x5 As Double h1 As Double v1 As Double a1 As Double p1 As Double h2 As Double v2 As Double

我有以下代码,在运行excel时会崩溃:

Option Explicit

Private Type Calculations
    x As Double
    x2 As Double
    x3 As Double
    x4 As Double
    x5 As Double
    h1 As Double
    v1 As Double
    a1 As Double
    p1 As Double
    h2 As Double
    v2 As Double
    a2 As Double
    p2 As Double
    h3 As Double
    v3 As Double
    a3 As Double
    p3 As Double
    h4 As Double
    v4 As Double
    a4 As Double
    p4 As Double
    h5 As Double
    v5 As Double
    a5 As Double
    p5 As Double
End Type

Private Type Points
    Point() As Calculations
End Type

Private Type Sections
    Section() As Points
End Type

Function DynamicRedim()

    Dim aSections As Sections
    Dim aCalculations As Calculations
    Dim aPoints() As Points

    Dim i As Integer

    Dim aSectionsDimension As Integer
    Dim aPointsDimension As Integer

    Dim aSectionsCount As Integer
    Dim aPointsCount As Integer


    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False
    Application.EnableEvents = False

    aSectionsDimension = 1
    aPointsDimension = 5


    ReDim Preserve aSections.Section(aSectionsDimension)

    aPoints = aSections.Section()
    ReDim Preserve aPoints(aPointsDimension)

    For i = LBound(aSections.Section) To UBound(aSections.Section)
        aSections.Section(i).Point = aPoints
    Next

    For aSectionsCount = LBound(aSections.Section) To UBound(aSections.Section) '<< believe crash occurs when aSectionsCount = UBound(aSections.Section)?????
        For aPointsCount = LBound(aSections.Section(aSectionsCount).Point) To UBound(aSections.Section(aSectionsCount).Point)
            aSections.Section(aSectionsCount).Point(aPointsCount).x = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).x2 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).x3 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).x4 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).x5 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).h1 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).v1 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).a1 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).p1 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).h2 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).v2 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).a2 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).p2 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).h3 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).v3 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).a3 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).p3 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).h4 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).v4 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).a4 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).p4 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).h5 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).v5 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).a5 = 0
            aSections.Section(aSectionsCount).Point(aPointsCount).p5 = 0
        Next
    Next

    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.EnableEvents = True

End Function
选项显式
私有类型计算
双倍
x2为双精度
x3为双精度
x4为双精度
x5作为双
h1为双倍
v1为双精度
a1为双
p1为双精度
h2为双氢
v2为双精度
a2作为双
p2为双精度
h3为双倍
v3为双精度
a3为双倍
p3为双精度
h4作为双
v4为双精度
a4双精度
p4为双精度
h5病毒为双重病毒
v5作为双
a5为双倍
p5为双倍
端型
专用类型点
点()作为计算
端型
专用型区段
节()作为点
端型
函数DynamicRedim()
将分区设置为分区
作为计算的计算
将aPoints()变暗为点
作为整数的Dim i
Dim AseConctionsDimension为整数
Dim aPointsDimension为整数
Dim AsectionScont作为整数
Dim ApointScont作为整数
Application.Calculation=xlCalculationManual
Application.ScreenUpdating=False
Application.EnableEvents=False
AseConctionsDimension=1
aPointsDimension=5
ReDim保留AseConctions.节(AseConctionsDimension)
aPoints=aSections.Section()
ReDim保留aPoints(aPointsDimension)
对于i=LBound(aSections.Section)到UBound(aSections.Section)
A部分。第(i)节。点=点
下一个

对于asectionScont=LBound(aSections.Section)到UBound(aSections.Section)“
都是Excel类。使用Excel数据类型的名称作为一个变量的名称总是一个坏主意。然而,我不认为这是造成这次坠机的原因

DynamicRedim不返回值,因此它是
子项
而不是
函数
。这并不重要,因为您没有尝试返回值

我相信第一个问题是:

aPoints=aSections.Section()

apoint
aSections.Section()
都是点数组,但它们的定义方式不同。我怀疑对齐方式略有不同,内存正在损坏

我相信同样的内存损坏也会发生在:

For i = LBound(aSections.Section) To UBound(aSections.Section)
  aSections.Section(i).Point = aPoints
Next
当我单步浏览您的代码时,Excel在第一个循环的中途崩溃。可以获取Excel变量的地址,以便我们进行详细调查,并证明问题是内存损坏,但我认为这不值得花时间

您的问题是,您正试图通过将预定义阵列复制到阵列来重拨阵列。我已成功复制了阵列,但源阵列和目标阵列具有相同的定义。你不能用传统的方式重拨数组,但你可以重拨分区。第(i)节。要点

我已经重写了你的代码,所以它可以工作。我已经为我的每一个变化都附上了解释。如果这些解释不充分,请回答问题

Option Explicit

Private Type Calculations
    x As Double
    x2 As Double
    x3 As Double
    x4 As Double
    x5 As Double
    h1 As Double
    v1 As Double
    a1 As Double
    p1 As Double
    h2 As Double
    v2 As Double
    a2 As Double
    p2 As Double
    h3 As Double
    v3 As Double
    a3 As Double
    p3 As Double
    h4 As Double
    v4 As Double
    a4 As Double
    p4 As Double
    h5 As Double
    v5 As Double
    a5 As Double
    p5 As Double
End Type

' Every use of "Point" replaced by "Pnt" to avoid any conflict
' with Excel classes Point and Points
Private Type Pnts
    Pnt() As Calculations
End Type

Private Type Sections
    Section() As Pnts
End Type
Function DynamicRedim2()

    Dim aSections As Sections
    'Dim aCalculations As Calculations    ' Not used by this code
    'Dim aPoints() As Points              ' Not used by this code

    Dim i As Integer

    Dim aSectionsDimension As Integer
    Dim aPntsDimension As Integer

    Dim aSectionsCount As Integer
    Dim aPntsCount As Integer

    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False
    Application.EnableEvents = False

    aSectionsDimension = 1
    aPntsDimension = 5

    ' Removed Preserve because nothing to preserve
    ReDim aSections.Section(aSectionsDimension)

    ' Use ReDim to size array rather than copying array of correct size
    ' Note: if "aSections.Section(i)" was an array, you cannot ReDim
    ' in this way because the syntax is invalid. You must pass
    ' "aSections.Section(i)" to a subroutine which can ReDim it.  If this
    ' in not clear, I will construct an example to show what I mean.
    For i = LBound(aSections.Section) To UBound(aSections.Section)
      ReDim aSections.Section(i).Pnt(aPntsDimension)
    Next

    ' Display aSections to show already initialised to zeros.  VBA initialises
    ' all variables to a default value.
    Call DsplSection(aSections)

    For aSectionsCount = LBound(aSections.Section) To UBound(aSections.Section)
        For aPntsCount = LBound(aSections.Section(aSectionsCount).Pnt) To _
                         UBound(aSections.Section(aSectionsCount).Pnt)
            ' I have changed the zeros to non-zero values to prove the code is
            ' changing all the elements.
            ' "1" is stored as an Integer and will have to be converted to a Double
            ' for each statement for each loop. "1#" tells the compiler to store 1
            ' as a Double.
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x = 1#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x2 = 2#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x3 = 3#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x4 = 4#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x5 = 5#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h1 = 6#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v1 = 7#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a1 = 8#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p1 = 9#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h2 = 10#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v2 = 11#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a2 = 12#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p2 = 13#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h3 = 14#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v3 = 15#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a3 = 16#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p3 = 17#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h4 = 18#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v4 = 19#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a4 = 20#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p4 = 21#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h5 = 22#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v5 = 23#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a5 = 24#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p5 = 25#
        Next
    Next

    ' Display new values
    Call DsplSection(aSections)

    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.EnableEvents = True

End Function
Sub DsplSection(ByRef SectionCrnt As Sections)

  ' For VBA, "Integer" specifies a 16-bit integer while "Long" defines a
  ' 32-bit integer. Integer variable are supposed to take longer to process
  ' than Long variable on 32-bit and 64-bit computers.  VBA routines are
  ' difficult to time because of all the background processing that can occur
  ' at any time. My experiments have failed to detect any difference between
  ' Integer and Long variables. However, no harm in having the bigger variable.
  Dim InxS As Long
  Dim InxP As Long

  For InxS = LBound(SectionCrnt.Section) To UBound(SectionCrnt.Section)
    For InxP = LBound(SectionCrnt.Section(InxS).Pnt) To _
               UBound(SectionCrnt.Section(InxS).Pnt)
      Debug.Print InxS & " " & InxP & ": ";
      ' Note how much typing you save using a With statement
      With SectionCrnt.Section(InxS).Pnt(InxP)
        Debug.Print .x & " " & .x2 & " " & .x3 & " " & .x4 & " " & .x5 & " " & _
                    .h1 & " " & .v1 & " " & .a1 & " " & .p1 & " " & .h2 & " " & _
                    .v2 & " " & .a2 & " " & .p2 & " " & .h3 & " " & .v3 & " " & _
                    .a3 & " " & .p3 & " " & .h4 & " " & .v4 & " " & .a4 & " " & _
                    .p4 & " " & .h5 & " " & .v5 & " " & .a5 & " " & .p5
      End With
    Next
  Next

End Sub

Point
Points
都是Excel类。使用Excel数据类型的名称作为一个变量的名称总是一个坏主意。然而,我不认为这是造成这次坠机的原因

DynamicRedim不返回值,因此它是
子项
而不是
函数
。这并不重要,因为您没有尝试返回值

我相信第一个问题是:

aPoints=aSections.Section()

apoint
aSections.Section()
都是点数组,但它们的定义方式不同。我怀疑对齐方式略有不同,内存正在损坏

我相信同样的内存损坏也会发生在:

For i = LBound(aSections.Section) To UBound(aSections.Section)
  aSections.Section(i).Point = aPoints
Next
当我单步浏览您的代码时,Excel在第一个循环的中途崩溃。可以获取Excel变量的地址,以便我们进行详细调查,并证明问题是内存损坏,但我认为这不值得花时间

您的问题是,您正试图通过将预定义阵列复制到阵列来重拨阵列。我已成功复制了阵列,但源阵列和目标阵列具有相同的定义。你不能用传统的方式重拨数组,但你可以重拨分区。第(i)节。要点

我已经重写了你的代码,所以它可以工作。我已经为我的每一个变化都附上了解释。如果这些解释不充分,请回答问题

Option Explicit

Private Type Calculations
    x As Double
    x2 As Double
    x3 As Double
    x4 As Double
    x5 As Double
    h1 As Double
    v1 As Double
    a1 As Double
    p1 As Double
    h2 As Double
    v2 As Double
    a2 As Double
    p2 As Double
    h3 As Double
    v3 As Double
    a3 As Double
    p3 As Double
    h4 As Double
    v4 As Double
    a4 As Double
    p4 As Double
    h5 As Double
    v5 As Double
    a5 As Double
    p5 As Double
End Type

' Every use of "Point" replaced by "Pnt" to avoid any conflict
' with Excel classes Point and Points
Private Type Pnts
    Pnt() As Calculations
End Type

Private Type Sections
    Section() As Pnts
End Type
Function DynamicRedim2()

    Dim aSections As Sections
    'Dim aCalculations As Calculations    ' Not used by this code
    'Dim aPoints() As Points              ' Not used by this code

    Dim i As Integer

    Dim aSectionsDimension As Integer
    Dim aPntsDimension As Integer

    Dim aSectionsCount As Integer
    Dim aPntsCount As Integer

    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False
    Application.EnableEvents = False

    aSectionsDimension = 1
    aPntsDimension = 5

    ' Removed Preserve because nothing to preserve
    ReDim aSections.Section(aSectionsDimension)

    ' Use ReDim to size array rather than copying array of correct size
    ' Note: if "aSections.Section(i)" was an array, you cannot ReDim
    ' in this way because the syntax is invalid. You must pass
    ' "aSections.Section(i)" to a subroutine which can ReDim it.  If this
    ' in not clear, I will construct an example to show what I mean.
    For i = LBound(aSections.Section) To UBound(aSections.Section)
      ReDim aSections.Section(i).Pnt(aPntsDimension)
    Next

    ' Display aSections to show already initialised to zeros.  VBA initialises
    ' all variables to a default value.
    Call DsplSection(aSections)

    For aSectionsCount = LBound(aSections.Section) To UBound(aSections.Section)
        For aPntsCount = LBound(aSections.Section(aSectionsCount).Pnt) To _
                         UBound(aSections.Section(aSectionsCount).Pnt)
            ' I have changed the zeros to non-zero values to prove the code is
            ' changing all the elements.
            ' "1" is stored as an Integer and will have to be converted to a Double
            ' for each statement for each loop. "1#" tells the compiler to store 1
            ' as a Double.
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x = 1#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x2 = 2#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x3 = 3#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x4 = 4#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).x5 = 5#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h1 = 6#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v1 = 7#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a1 = 8#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p1 = 9#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h2 = 10#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v2 = 11#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a2 = 12#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p2 = 13#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h3 = 14#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v3 = 15#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a3 = 16#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p3 = 17#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h4 = 18#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v4 = 19#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a4 = 20#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p4 = 21#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).h5 = 22#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).v5 = 23#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).a5 = 24#
            aSections.Section(aSectionsCount).Pnt(aPntsCount).p5 = 25#
        Next
    Next

    ' Display new values
    Call DsplSection(aSections)

    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.EnableEvents = True

End Function
Sub DsplSection(ByRef SectionCrnt As Sections)

  ' For VBA, "Integer" specifies a 16-bit integer while "Long" defines a
  ' 32-bit integer. Integer variable are supposed to take longer to process
  ' than Long variable on 32-bit and 64-bit computers.  VBA routines are
  ' difficult to time because of all the background processing that can occur
  ' at any time. My experiments have failed to detect any difference between
  ' Integer and Long variables. However, no harm in having the bigger variable.
  Dim InxS As Long
  Dim InxP As Long

  For InxS = LBound(SectionCrnt.Section) To UBound(SectionCrnt.Section)
    For InxP = LBound(SectionCrnt.Section(InxS).Pnt) To _
               UBound(SectionCrnt.Section(InxS).Pnt)
      Debug.Print InxS & " " & InxP & ": ";
      ' Note how much typing you save using a With statement
      With SectionCrnt.Section(InxS).Pnt(InxP)
        Debug.Print .x & " " & .x2 & " " & .x3 & " " & .x4 & " " & .x5 & " " & _
                    .h1 & " " & .v1 & " " & .a1 & " " & .p1 & " " & .h2 & " " & _
                    .v2 & " " & .a2 & " " & .p2 & " " & .h3 & " " & .v3 & " " & _
                    .a3 & " " & .p3 & " " & .h4 & " " & .v4 & " " & .a4 & " " & _
                    .p4 & " " & .h5 & " " & .v5 & " " & .a5 & " " & .p5
      End With
    Next
  Next

End Sub

我不清楚哪一个应该是您期望的结果,
aSections.Section(aSectionsDimension)
它定义为一维数组。这就是你正在尝试的吗?我不清楚哪一个应该是你期望的结果,无论如何,
aSections.Section(aSectionsDimension)
它定义为一维数组。这是你正在尝试的吗?