取決於你有多少數據在dataRange
它可能會更快地加載到一個臨時數組和過程,而不是循環工作表上的單元格。另外ReDim Preserve
是一個昂貴的操作,所以如果可能的話更好地避免。
下面的代碼存儲dataRange
在一個臨時數組,循環溫度陣列以查找匹配並存儲的行索引號,重新尺寸kRow
以適應然後複製在匹配值
Sub PopulateArray()
Dim ws As Worksheet
Dim dataRange As Range
Dim temparr() As Variant, kRow() As Variant
Dim i As Long, InstanceCount As Long
Dim RwIndexList As String, Rw As Variant
Set ws = Sheet1
Set dataRange = ws.Range("AE4", ws.Range("AE4").End(xlDown))
'store dataRange in 1D array for processing
temparr = Application.Transpose(dataRange.Value)
'loop to determine # of instances > 0
For i = LBound(temparr) To UBound(temparr)
If temparr(i) > 0 Then RwIndexList = RwIndexList & "_" & i
Next i
'only process if matches found
If Not RwIndexList = vbNullString Then
'determine # of matches
InstanceCount = Len(RwIndexList) - Len(Replace(RwIndexList, "_", ""))
'resize kRow to match # of instances > 0
ReDim kRow(1 To InstanceCount)
'initialize kRow counter
i = 1
'copy matching rows to kRow
For Each Rw In Split(Mid(RwIndexList, 2), "_")
kRow(i) = temparr(Rw)
i = i + 1
Next Rw
End If
End Sub
一種替代選項,將只需要一個數組,1循環將使用Application.Index
來切片數組以濾除不匹配的行;然而,這隻適用於二維數組,所以你會留下一個二維數組作爲輸出,不知道這是否是一種選擇嗎?
Sub PopulateArray_Alternative()
Dim ws As Worksheet, dataRange As Range
Dim kRow() As Variant, i As Long, RwIndexList As String
Set ws = Sheet1 'change to suit
Set dataRange = ws.Range("AE4", ws.Range("AE4").End(xlDown))
'store dataRange in 2D array for processing
kRow = dataRange.Value
'store matching rows in index list
For i = LBound(kRow) To UBound(kRow)
If kRow(i, 1) > 0 Then RwIndexList = RwIndexList & "_" & i
Next i
'only process if matches found
If Not RwIndexList = vbNullString Then
'slice array to filter non-matching rows
kRow = Application.Index(kRow, Application.Transpose(Split(Mid(RwIndexList, 2), "_")), 0)
End If
End Sub
由於@Peh提到你可能還需要一些數據驗證添加到測試標準,除非你知道你所有的數據是數字。
你確定嗎?用'Debug.Print UBound(kRow)'作爲最後的語句測試它是什麼結果?代碼對我來說工作正常,沒有問題。你確定'cell.Value'是數字而不是文本嗎? –
代碼也適用於我,儘管我使用了不同的範圍聲明。如果你的範圍聲明有效,其餘的代碼也應該如此。 – Vegard
要驗證'ws.Range(「AE4」)。End(xlDown)'是否真的是你想要的,請手動選擇AE4並按Ctrl +向下(向下箭頭)。現在選擇的單元格是從AE4開始的'dataRange'的最後一個單元格。如果你的意思是AE列中的最後一個單元格,那麼使用'Set dataRange = ws.Range(「A4」,ws.Range(「A」&ws.Rows.Count).End(xlUp))'代替。 –