如何在VBA数组中复制特定单元格?替代For Each循环的方案
不用For Each循环,通过数组复制列中特定单元格的VBA实现
你已经通过数组搞定了整列复制,现在想跳过For Each循环,直接基于单元格地址或者Cell.Offset.Value来提取某列里的特定单元格对吧?其实咱们可以利用数组下标和工作表行号的对应关系,直接定位目标值,完全不用挨个遍历单元格。
下面给你两种常见场景的实现方案:
场景1:基于固定行号/单元格地址提取
比如要提取源表A列第2、4、6行的数据,直接通过数组下标对应就行:
Dim MyBook As Workbook Set MyBook = GetWorkbook("C:\Users\VV\Desktop\Source.xlsb") Dim sourceArr As Variant, targetArr As Variant Dim targetRows As Variant, i As Long, n As Long ' 把源列数据一次性读进数组 With MyBook.Sheets(1) sourceArr = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Value End With ' 定义要提取的行号(数组下标从1开始,和工作表行号直接对应) targetRows = Array(2, 4, 6) ' 初始化目标数组大小 ReDim targetArr(1 To UBound(targetRows) + 1, 1 To 1) ' 直接通过行号提取对应数组元素,全程不用For Each For i = LBound(targetRows) To UBound(targetRows) n = n + 1 targetArr(n, 1) = sourceArr(targetRows(i), 1) Next i ' 把处理好的数组一次性写入目标工作表 With ThisWorkbook.Sheets(2) .Range("A1").Resize(n).Value = targetArr End With ' 可选:关闭源工作簿 If Not MyBook Is Nothing Then MyBook.Close savechanges:=False End If
场景2:基于偏移/条件提取
比如要提取源表A列中,对应B列值为"有效"的单元格(相当于Cell.Offset(0,1).Value = "有效"的判断),可以一次性读取多列数组再筛选:
Dim MyBook As Workbook Set MyBook = GetWorkbook("C:\Users\VV\Desktop\Source.xlsb") Dim sourceArr As Variant, targetArr As Variant Dim lastRow As Long, i As Long, n As Long ' 一次性读取A、B两列数据到数组,比单独读一列更高效 With MyBook.Sheets(1) lastRow = .Range("A" & .Rows.Count).End(xlUp).Row sourceArr = .Range("A1:B" & lastRow).Value End With ' 先统计符合条件的数量,用来确定目标数组大小 n = 0 For i = 1 To UBound(sourceArr, 1) If sourceArr(i, 2) = "有效" Then ' 对应Offset(0,1)的判断逻辑 n = n + 1 End If Next i ' 初始化目标数组 ReDim targetArr(1 To n, 1 To 1) n = 0 ' 提取符合条件的A列值 For i = 1 To UBound(sourceArr, 1) If sourceArr(i, 2) = "有效" Then n = n + 1 targetArr(n, 1) = sourceArr(i, 1) End If Next i ' 写入目标工作表 With ThisWorkbook.Sheets(2) .Range("A1").Resize(n).Value = targetArr End With ' 可选:关闭源工作簿 If Not MyBook Is Nothing Then MyBook.Close savechanges:=False End If
核心要点
- 从A1开始读取的数组,下标和工作表行号是完全对应的,所以直接用行号当数组第一维下标,就能拿到对应单元格的值,根本不需要
For Each Cell循环。 - 一次性把整列/多列数据读进数组操作,比逐个操作单元格效率高得多,这也是你选择数组方案的核心优势。
- 如果是基于偏移的需求,比如要取
Cell.Offset(1,0)的单元格,直接用sourceArr(i+1,1)就能获取对应值,完全不用操作Range对象。
附上你提供的GetWorkbook函数(供参考):
Public Function GetWorkbook(ByVal sFullName As String) As Workbook Dim sFile As String Dim wbReturn As Workbook sFile = Dir(sFullName) On Error Resume Next Set wbReturn = Workbooks(sFile) If wbReturn Is Nothing Then Set wbReturn = Workbooks.Open(sFullName) End If On Error GoTo 0 Set GetWorkbook = wbReturn End Function
内容的提问来源于stack exchange,提问作者Zatary
相关产品推荐
相关产品推荐

