在不同的私有子例程中使用公共声明的数组时下标超出范围
Posted
技术标签:
【中文标题】在不同的私有子例程中使用公共声明的数组时下标超出范围【英文标题】:Subscript out of range when using a public declared array in a different private subroutine 【发布时间】:2020-03-29 01:49:51 【问题描述】:我已将 refedit selected range 分配给名为 dataarray0
的数组,我已将其声明为公共,然后在主子例程中使用此数组。但是,当我从 Private sub 运行到 main 子例程时,我得到了 subscript out of range
错误,我无法弄清楚。请在下面找到两个代码 1 是定义数组的 USERFORM 的代码,2 是使用该数组的代码:
Option Explicit
Public dataarray0 As Variant
Private Sub ActiWorkBook_Change()
If ActiWorkBook <> "" Then Application.Workbooks(ActiWorkBook.Text).Activate
Label1.Caption = "": RefEdit1 = ""
End Sub
Private Sub CommandButton1_Click()
Unload Me
End
End Sub
Private Sub CommandButton2_Click()
Dim addr As String, partderivrng As Range, cell As Range, thisbook As String, NROWSPDIV As Integer
Dim NCOLSPDIV As Integer
Dim mydestination As Range
Dim dataarray0() As Variant, DEST As Variant
If RefEdit1.Value = "" Then
Partderiv.Hide
ERR1.Show
Else
addr = RefEdit1.Value
Set partderivrng = Range(addr)
NROWSPDIV = Range(addr).Rows.Count
NCOLSPDIV = Range(addr).Columns.Count
' ReDim dataarray0(NROWSPDIV, NCOLSPDIV)
dataarray0() = partderivrng
ThisWorkbook.Activate
Sheets("PD").Select
Set mydestination = Application.InputBox(Prompt:= _
"What is the first cell in the destination range for data?", Type:=8)
mydestination.Select
' mydestination.Paste Link:=True
Partderiv.Hide
Set DEST = mydestination.Resize(NROWSPDIV, NCOLSPDIV)
DEST.Value = dataarray0
End If
Data1.Show
End
End Sub
Private Sub CommandButton3_Click()
Unload Me
DYNA1.Show
End Sub
Private Sub UserForm_Initialize()
Dim wb As Workbook
For Each wb In Application.Workbooks
ActiWorkBook.AddItem wb.Name
Next
ActiWorkBook = ActiveWorkbook.Name
Partderiv.RefEdit1.Text = ""
End Sub
Private Sub RefEdit1_Change()
Label1.Caption = ""
If RefEdit1.Value <> "" Then _
Label1.Caption = "[" & ActiWorkBook & "]" & RefEdit1
End Sub
Sub CALC1_Run(ByRef dataarray1 As Variant, ByRef dataarray0 As Variant)
' This subroutine runs the calculation for the Isolated brick: Simple KWR Strength Calculation
' Created 27/11/2019 by Owen Booler
' Version 1: 27/11/2019 - Creation of subroutine by Owen Booler
'Integer definitions
' Loop Identifiers
Dim i As Integer, j As Integer, k As Integer
' Other Variables
Dim NSIM As Integer, NSITES As Integer, NKWRS As Integer, NTIME As Integer, NHITS As Integer
' Double Precision definitions
' String definitions
Dim DIST As String
' Array definitions
Dim Prob() As Double, SAMPSTRENGTH() As Double, SDV23 As Double, IRRSAMPSTRENGTH() As Variant
Dim NEWARRAY() As Variant, HITTIME() As Double
' Range definitions
Dim DEST1 As Range, DEST2 As Range
Randomize
' Defintions for Testing
NSIM = 1000
DIST = "N"
NTIME = Val(DYNA1.NUMTINC) + 2
' Real definitions
'NSIM = Val(MCINPUT1.NUMSIM)
'DIST = Val(MCINPUT1.DSTRENGTH)
NSITES = 16 ' Number of cracking sites
NKWRS = 16
'Re define arrays to match size of number of simulations
ReDim SAMPSTRENGTH(NSIM, NKWRS), Prob(NSIM, NKWRS), IRRSAMPSTRENGTH(NSIM, NKWRS)
ReDim NEWARRAY(2, NKWRS)
ReDim HITTIME(NTIME)
'NEWARRAY = Array(Data1.dataarray1)
For i = 1 To NSIM
' Calculate Sample Strength
If DIST = "N" Then
For j = 1 To NKWRS
HITTIME(0) = 0
NHITS = 0
Prob(i, j) = Rnd()
SAMPSTRENGTH(i, j) = sabNORMINV(Prob(i, j), 27.5653, 1.1777)
' SAMPSTRENGTH(i, j) = sabNORMINV(Prob, Val(MCINPUT1.MSTRENGTH), Val(MCINPUT1.SSTRENGTH))
IRRSAMPSTRENGTH(i, j) = SAMPSTRENGTH(i, j) * dataarray1(2, j + 1)
For k = 1 To NTIME
' Maybe put a check in here to see whether keyway root are the same in stress and strength
If dataarray0(k + 2, j + 1) > IRRSAMPSTRENGTH(i, j) Then
NHITS = NHITS + 1
HITTIME(k) = dataarray0(k + 2, 1)
Else
HITTIME(k) = HITTIME(k - 1)
End If
If HITTIME(k) = 0 Then
GoTo 10
ElseIf HITTIME(k) < HITTIME(k - 1) Then
HITTIME(j) = HITTIME(k)
Else
End If
10 Next
Next
Else
MsgBox "ERROR - VALUE FOR DISTRIBUTION NOT RECOGNISED"
End
End If
Next
Set DEST1 = Sheets("Sample").Range("B2").Resize(NSIM + 1, NKWRS + 1)
Set DEST2 = Sheets("Data").Range("B10").Resize(NSIM + 1, NKWRS + 1)
DEST1.Value = IRRSAMPSTRENGTH
DEST2.Value = SAMPSTRENGTH
End Sub
【问题讨论】:
补充一下,错误发生在``` If dataarray0(k + 2, j + 1) > IRRSAMPSTRENGTH(i, j) Then``` 在您的子程序中,您正在定义一个新数组Dim dataarray0() As Variant, DEST As Variant
。这个新数组是 Sub 中的一个使用,不是上面定义的 public 的,它的作用域也不一样。
去掉Sub中的附加定义。
@VincentG 谢谢,但是当我按照您的建议删除 Dim dataarray0()
作为变体时,它在流程的早期出现了另一个错误,现在在dataarray0()=partderivrng
的第一个代码中,错误也是下标范围。
【参考方案1】:
模块中声明的Public变量dataarray0
在SubCommandButton2_Click
中没有被修改,因为你还在sub中定义了同名的局部变量。
因此,所有对 Sub 中dataarray0
的访问都是在本地定义的变量上进行的,而不是全局公共变量。当尝试从其他地方访问变量时,您访问的是未初始化的 Variant。
如果没有用,请删除屏蔽全局变量的本地不需要的局部变量。
Private Sub CommandButton2_Click()
Dim addr As String, partderivrng As Range, cell As Range, thisbook As String, NROWSPDIV As Integer
Dim NCOLSPDIV As Integer
Dim mydestination As Range
'Dim dataarray0() As Variant, DEST As Variant
Dim DEST As Variant
.
.
.
End Sub
编辑: 在您当前的代码中,公共声明是:
Public dataarray0 As Variant
变体可以包含一个数组,因此语法dataarray0 = partdelivery
会将范围的内容分配给该变量,然后该变量将变为 Variant/Variant 数组类型
您将访问这样的数据:
您将无法像这样将 dataarray0 声明为 Variant 数组,至少不能在模块范围内:
Public dataarray0() As Variant 'WRONG -> compile error
【讨论】:
谢谢,但是,当这样做时,错误subscript out of range
现在与dataarray0()=partderivrng
一起存在
dataarray0
没有被定义为一个数组,而是一个变体......所以还没有 dataarray0() 。将定义更改为 Variant 数组,或使用 dataarray0 = partdelivery
初始化值(在这种情况下,它将是包含数组的 Variant)
我不确定你的意思是什么,partdelivrng
是一个范围,我认为为了给一个数组分配一个范围,你需要在末尾加上 ()。在模块中调用它时如何知道它是带有下标 k 和 j 的二维数组?
感谢并抱歉让您感到痛苦,但现在在模块中应用它后,它会在If dataarray0(k + 2, j + 1) > IRRSAMPSTRENGTH(i, j) Then
处出现超出范围的下标,所以回到开头。
数组的Lbounds和Ubounds的值是多少,失败时k、j、i的值是多少?它应该指出错误所在。【参考方案2】:
我发现因为dataarray0
在userform
中被声明为public,所以它不会作为全局变量,因此当我在我的模块中使用它时,我应该在使用之前放置用户表单名称dataarray0 即
Partderiv.dataarray0
这似乎现在可以工作了
谢谢
【讨论】:
以上是关于在不同的私有子例程中使用公共声明的数组时下标超出范围的主要内容,如果未能解决你的问题,请参考以下文章