如何dynamic调整VBA中的数组的大小? 我不断收到下标和索引问题
Dim codesArray() As Variant ... If WorksheetExists(workSheetName) Then ... Else ReDim Preserve codesArray(UBound(codesArray) + 1) ' Error subscript codesArray(UBound(codesArray)) = cell.Value End If
我不知道为什么我得到一个索引超出范围的错误。
基本上每次没有find工作表名称,我想将其添加到数组,然后最终让用户知道缺less的工作表的名称。
所以最好的员工会丢失0个工作表。 最糟糕的是他们都错过了。
正如已经说过的var()
会在检查时出错。 要做到这一点没有任何错误,你可以使用这样的代码:
Dim codesArray ... If WorksheetExists(workSheetName) Then ... Else If IsArray(codesArray) Then ReDim Preserve codesArray(UBound(codesArray) + 1) Else ReDim codesArray(0) End If codesArray(UBound(codesArray)) = cell.Value End If
或者像这样:
Dim codesArray ... If WorksheetExists(workSheetName) Then ... Else If IsArray(codesArray) Then ReDim Preserve codesArray(UBound(codesArray) + 1) codesArray(UBound(codesArray)) = cell.Value Else codesArray = Array(cell.Value) End If End If
关于这一点的好处是避免了任何错误更改代码。 所以如果出现错误的原因不同,就不会被压制。 也应该是自我解释….如果你还有任何问题,请问;)
问题是与UBound(codesArray)
。 你不能在尚未UBound()
尺寸的数组上调用UBound()
。
您可以使用error handling来覆盖这种情况。 抽象为一个潜在的有用的sub:
Sub ExtendArray(A As Variant, Optional NewPlaces = 1, Optional LBase = 0) On Error GoTo err_handler ReDim Preserve A(LBound(A) To UBound(A) + NewPlaces) Exit Sub err_handler: ReDim A(LBase To LBase + NewPlaces - 1) End Sub
使用variablesk。
Dim codesArray() As Variant Dim k As Long ... If WorksheetExists(workSheetName) Then ... Else ReDim Preserve codesArray(k) ' Error subscript codesArray(k) = Cell.Value k = k + 1 End If
上面的代码arrays号从0开始。
波纹pipe代码arrays号从1开始.Lbound(codeArray)是1。
Dim codesArray() As Variant Dim k As Long ... If WorksheetExists(workSheetName) Then ... Else k = k + 1 ReDim Preserve codesArray(1 To k) ' Error subscript codesArray(k) = Cell.Value End If
使用集合而不是数组可能会更好 – 不需要resize。
Sub Test() Dim vSheetNames As Variant Dim sht As Variant Dim colMissing As Collection Dim vItem As Variant Dim sMissingString As String Dim lLastComma As Long vSheetNames = Array("Sheet1") ', "Sheet2", "Sheet3", "Sheet4", "Sheet5" 'Build a collection of missing sheets. Set colMissing = New Collection For Each sht In vSheetNames If Not WorkSheetExists(CStr(sht)) Then colMissing.Add sht End If Next sht If colMissing.Count = 0 Then MsgBox "All sheets are present", vbOKOnly + vbInformation Else 'Build the message string. For Each vItem In colMissing sMissingString = sMissingString & vItem & ", " Next vItem 'Remove the last comma. sMissingString = Left(sMissingString, Len(sMissingString) - 2) 'Replace last comma with the word 'and'. lLastComma = InStrRev(sMissingString, ",") If lLastComma > 0 Then sMissingString = Left(sMissingString, lLastComma - 1) & " and" & Mid(sMissingString, lLastComma + 1) End If MsgBox IIf(colMissing.Count = 1, "This sheet is ", "These sheets are ") & "missing: " & vbCr & _ sMissingString, vbOKOnly + vbInformation End If End Sub Public Function WorkSheetExists(SheetName As String, Optional WrkBk As Workbook) As Boolean Dim wrkSht As Worksheet If WrkBk Is Nothing Then Set WrkBk = ThisWorkbook End If On Error Resume Next Set wrkSht = WrkBk.Worksheets(SheetName) WorkSheetExists = (Err.Number = 0) Set wrkSht = Nothing On Error GoTo 0 End Function