You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel VBA复制负数对应数据失败:粘贴无内容问题排查

问题:VBA代码无法将新工作簿的指定数据粘贴到当前工作簿

需求:从新打开的工作簿中,复制cases为负数对应的pallet type、SKU及对应cases值,粘贴到当前工作簿。现有代码看似执行了复制操作,但无法完成粘贴。

原代码

Sub buildPlan()
'
' buildPlan Macro
'
    Dim wb As Workbook
    Dim colValsF, colValsE, colValsB As Collection
    Dim v, arr, c, d, e As Range
    Dim nwb As Workbook, wsAPP As Worksheet, wsDNDR As Worksheet
    
    Set wb = Application.ActiveWorkbook           'ThisWorkbook?
    Set wsAPP = wb.Worksheets("Arils Pack Plan ") 'trailing space?
    
    'Opening Recent ATS report
     With Application.FileDialog(msoFileDialogOpen)
        .Filters.Clear
        .Filters.Add "Excel 2007-13", "*.xlsx; *.xlsm; *.xlsa"
        .AllowMultiSelect = False
        .Show
    Application.Workbooks.Open .SelectedItems(1)
    Set nwb = Application.ActiveWorkbook

    End With
    
    Set wsDNDR = nwb.Worksheets("DAILY NEED (DR)")
    
    Set colValsE = New Collection
    Set colValsF = New Collection
    Set colValsB = New Collection
    'Collect Pallet----------------------------------------------------------------------------------------------------------------------------------------------
    
    Set d = wsDNDR.Range("E5:E14,E15:E25").Cells
    
    For Each c In wsDNDR.Range("Q5:Q14,T5:T14,Q15:Q25,T15:T25").Cells
        v = c.Value
        If v < 0 Then colValsE.Add d
    Next c
    
    arr = CollectionToArray(colValsE) 'transfer the collection values to an array
    If Not IsEmpty(arr) Then
        wsAPP.Range("E7").Resize(UBound(arr, 1), 1) = arr 'place the array on the sheet
    End If
  'Collect SKU --------------------------------------------------------------------------------------------------------------------------------------------------
  
  Set e = wsDNDR.Range("B5:B14,B15:B25").Cells
  
  For Each c In wsDNDR.Range("Q5:Q14,T5:T14,Q15:Q25,T15:T25").Cells
        v = c.Value
        If v < 0 Then colValsB.Add e
    Next c
    
    arr = CollectionToArray(colValsB) 'transfer the collection values to an array
    If Not IsEmpty(arr) Then
        wsAPP.Range("B7").Resize(UBound(arr, 1), 1) = arr 'place the array on the sheet
    End If
    
    
    'collect all of the negative values----------------------------------------------------------------------------------------------------------------------------
    For Each c In wsDNDR.Range("Q5:Q14,T5:T14,Q15:Q25,T15:T25").Cells
        v = c.Value
        If v < 0 Then colValsF.Add v
    Next c
    
    arr = CollectionToArray(colValsF) 'transfer the collection values to an array
    If Not IsEmpty(arr) Then
        wsAPP.Range("F7").Resize(UBound(arr, 1), 1) = arr 'place the array on the sheet
    End If
    
End Sub

问题分析与修正方案

核心问题点

  • 变量声明不规范:VBA中Dim colValsF, colValsE, colValsB As Collection仅最后一个变量为Collection类型,前两个默认是Variant;同理v, arr, c, d, e As Range仅最后一个是Range类型,其余为Variant,易导致类型错误。
  • 错误收集Range对象而非单元格值:收集Pallet和SKU时,原代码直接将整个Range对象d/e加入集合,而非对应行的单元格值,导致后续数组赋值失败。
  • 依赖未定义的CollectionToArray函数:若未提前实现该函数,代码会直接报错中断。
  • 工作表名称存在潜在问题:"Arils Pack Plan "末尾有空格,需确认当前工作簿中目标工作表名称完全一致,否则会找不到工作表。

修正后的代码

Sub buildPlan()
'
' buildPlan Macro
'
    Dim wb As Workbook
    Dim colValsF As Collection, colValsE As Collection, colValsB As Collection
    Dim v As Variant, arr As Variant, c As Range, d As Range, e As Range
    Dim nwb As Workbook, wsAPP As Worksheet, wsDNDR As Worksheet
    
    ' 明确使用当前运行代码的工作簿,避免ActiveWorkbook切换问题
    Set wb = ThisWorkbook
    ' 确认工作表名称无多余空格,若实际名称有空格则保留
    Set wsAPP = wb.Worksheets("Arils Pack Plan")
    
    ' 打开目标工作簿
    With Application.FileDialog(msoFileDialogOpen)
        .Filters.Clear
        .Filters.Add "Excel 2007-13", "*.xlsx; *.xlsm; *.xlsa"
        .AllowMultiSelect = False
        If .Show = -1 Then
            Set nwb = Application.Workbooks.Open(.SelectedItems(1))
        Else
            ' 用户取消选择文件,直接退出
            Exit Sub
        End If
    End With
    
    Set wsDNDR = nwb.Worksheets("DAILY NEED (DR)")
    
    Set colValsE = New Collection
    Set colValsF = New Collection
    Set colValsB = New Collection
    
    ' 遍历所有需要检查的cases单元格
    For Each c In wsDNDR.Range("Q5:Q14,T5:T14,Q15:Q25,T15:T25").Cells
        v = c.Value
        If IsNumeric(v) And v < 0 Then
            ' 收集对应行的Pallet Type(E列)
            colValsE.Add wsDNDR.Cells(c.Row, "E").Value
            ' 收集对应行的SKU(B列)
            colValsB.Add wsDNDR.Cells(c.Row, "B").Value
            ' 收集负数cases值
            colValsF.Add v
        End If
    Next c
    
    ' 将集合转数组并写入当前工作簿
    If colValsE.Count > 0 Then
        arr = CollectionToArray(colValsE)
        wsAPP.Range("E7").Resize(UBound(arr, 1), 1) = arr
    End If
    
    If colValsB.Count > 0 Then
        arr = CollectionToArray(colValsB)
        wsAPP.Range("B7").Resize(UBound(arr, 1), 1) = arr
    End If
    
    If colValsF.Count > 0 Then
        arr = CollectionToArray(colValsF)
        wsAPP.Range("F7").Resize(UBound(arr, 1), 1) = arr
    End If
    
    ' 可选择关闭新工作簿,根据需求调整
    ' nwb.Close SaveChanges:=False
End Sub

' 实现Collection转数组的函数
Function CollectionToArray(col As Collection) As Variant
    Dim arr() As Variant
    ReDim arr(1 To col.Count, 1 To 1)
    
    Dim i As Integer
    For i = 1 To col.Count
        arr(i, 1) = col(i)
    Next i
    
    CollectionToArray = arr
End Function

关键修正说明

  • 变量声明:逐个明确变量类型,避免Variant类型导致的潜在错误。
  • 数据收集逻辑:通过c.Row获取当前负数cases所在行,直接提取对应B列(SKU)和E列(Pallet Type)的单元格值加入集合,确保收集的是有效数据而非Range对象。
  • 添加CollectionToArray函数:直接在代码中实现集合转数组的逻辑,避免依赖外部未定义函数。
  • 增加文件选择判断:用户取消选择文件时直接退出,避免后续代码报错。
  • 明确工作簿对象:使用ThisWorkbook指代当前运行代码的工作簿,避免打开新文件后ActiveWorkbook切换导致的错误。

内容的提问来源于stack exchange,提问作者Jonathan Anguiano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 17:05:32