【问题标题】:Copying and pasting data between workbooks in an array of sheets在工作表数组中的工作簿之间复制和粘贴数据
【发布时间】:2018-05-07 19:40:35
【问题描述】:

我迷路了,并试图在多个论坛上找到这个特定问题,但似乎无法将其拼凑起来。希望非常快速的问题。此代码旨在:

  • 在 5 个工作表中搜索包含数据的最后一个单元格。它应该搜索除“A”或“B”列之外的数据,因为这些数据可能为空,也可能不为空。
  • 对数组中的所有 5 个工作表重复
  • 将源工作簿中 5 个工作表中的所有数据依次粘贴到“工作表 4”上

我遇到的问题是 maybe usedrange.copy 奇怪地复制了 5 个工作簿中的所有数据。它似乎没有复制所有数据(也许计算列 A 以查找最后使用的行并基于此进行复制?)。

是否有不同的方式来实现我需要做的事情?我认为这会更容易,因为它只是从 5 张纸上复制所有数据并粘贴到不同的 wkbk 中……但是……不。非常感谢任何帮助。

    Sub Notes2()
'Last row in column
Dim WS As Worksheet, shAry As Variant, i As Long
Dim AOFF As Range
Dim rOWIS As Integer
Dim wb As Workbook, wb2 As Workbook
Dim vFile As Variant
'Set source workbook
Set wb = ActiveWorkbook
Set WS = Worksheets("Sheet 4")
With WS
    Set LastCell = .Cells(.Rows.Count, "A").End(xlUp)
    LastCellRowNumber = LastCell.Row + 1
End With
'Open the target workbook
vFile = Application.GetOpenFilename("Excel-files,*.xlsx", _
    1, "Select File To Open", , False)
'if the user didn't select a file, exit sub
If TypeName(vFile) = "Boolean" Then Exit Sub
Application.ScreenUpdating = False
Set wb2 = Workbooks.Open(vFile)
With wb2
    shAry = Array(.Sheets("Week 1"), .Sheets("Week 2"), .Sheets("Week 3"), .Sheets("Week 4"), .Sheets("Over 30"))
End With
    For i = LBound(shAry) To UBound(shAry)
        shAry(i).UsedRange.Copy
        wb.Activate
        WS.Cells(Rows.Count, 3).End(xlUp).End(xlUp)(2).PasteSpecial xlPasteValues
        Application.CutCopyMode = False
    Next
Application.ScreenUpdating = True
'Close
wb2.Close False
End Sub

【问题讨论】:

  • 您真的要连续使用两次.End(xlUp) 吗?这样做会覆盖 WS 表中的一行或多行数据。试试这个:WS.Cells(Rows.Count, 3).End(xlUp)(2).PasteSpecial xlPasteValues 从工作表末尾的第一个空白行开始粘贴数据。
  • 我不是故意这样连续两次。我的错误。即使在更正之后,问题似乎仍因某种原因而存在。这是要复制的 excel wkbk:ufile.io/fkz2z 和源 wkbk:ufile.io/6r9yf。我刚刚添加了一个包含更正代码的蓝色按钮。如果您使用该宏,您可以看到正在发生的事情。它只是不想看起来有条不紊地复制和粘贴并将它们混合起来
  • 找到粘贴数据的更好方法是:WS.Cells(WS.Cells.SpecialCells(xlCellTypeLastCell).Row + 1, 3).PasteSpecial xlPasteValues。这将从第一个未使用的行 C 列开始粘贴数据。(ps 虽然您花时间模拟数据很好,但我不喜欢从未知来源下载文件。更新您的问题以反映代码更改,并可能包括数据的屏幕截图。此外,如果问题仍然存在,请将您的数据减少到尽可能少的数量,以便准确了解发生了什么。
  • 效果很好。有点儿。它修复了非常奇怪的粘贴问题并且它是对齐的。但是,我使用此代码的电子表格的固有部分需要 P-T 列中的某些公式。它们只是计算其他(不相关)数据的公式。看起来这是粘贴在公式结束的那些列下方(第 1000 行是它停止的位置)。您是否知道任何快速修改粘贴代码以跳过读取这些列并将 A - O 粘贴到左侧的快速方法,它是第一个空白行?
  • 来自stackoverflow.com/questions/37077059... 尝试:Set LastCell = WS.Range("C:O").Find(What:="*", SearchDirection:=xlPrevious)WS.Cells(LastCell.Row + 1, 3).PasteSpecial xlPasteValues

标签: arrays excel range vba


【解决方案1】:

此代码找到了粘贴数据的正确位置,因此不会丢失或覆盖任何内容(例如,C 列中没有数据的第一行:)。

Sub Rectangle1_Click()

Dim WS As Worksheet
Dim wb2 As Workbook
Dim vFile As Variant
Dim shAry As Variant
Dim sh As Variant

Set WS = ActiveWorkbook.Worksheets("Sheet 1")

'Open the target workbook
vFile = Application.GetOpenFilename("Excel-files,*.xlsx", _
    1, "Select File To Open", , False)
'if the user didn't select a file, exit sub
If TypeName(vFile) = "Boolean" Then Exit Sub
Application.ScreenUpdating = False
Set wb2 = Workbooks.Open(vFile)

With wb2
    shAry = Array(.Sheets("Week 1"), .Sheets("Week 2"), .Sheets("Week 3"), .Sheets("Week 4"), .Sheets("Over 30"))
End With
For Each sh In shAry
    Dim LastCell As Range
    Set LastCell = WS.Range("C:O").Find(What:="*", SearchDirection:=xlPrevious)
    If LastCell Is Nothing Then Set LastCell = WS.Range("C1")
    Range(sh.Cells(1, 1), sh.Cells.SpecialCells(xlCellTypeLastCell)).Copy
    WS.Cells(LastCell.Row + 1, 3).PasteSpecial xlPasteValues
Next

Application.CutCopyMode = False
Application.ScreenUpdating = True
wb2.Close False
End Sub

注意:我删除了不必要的代码;有关解释,请参阅以前的答案。

【讨论】:

  • 你太棒了。正是我需要的。如果你不介意的话,我有一个问题。即使这段代码有效,我仍然想学习。为什么在 With wb2 数组下方调暗和设置 Lastcell?这是必需的吗?此外,问题最初是否需要另一个变体(因为 sh 设置为变体)来运行数组?这可能是它没有正确复制/粘贴的原因吗?再次感谢您的所有帮助。非常非常非常感谢。
  • 1) Dim 语句也可以在顶部;我将声明放在使用变量的位置之前;顺便说一句,它可能更像是一个 .net 的东西,并且在循环内声明对性能没有影响。 Set LastCell 必须位于它所在的位置,因为最后一个单元格在每个循环中都会更改。 2)我没有运行你的原始代码,所以我不能说为什么它之前没有正确复制/粘贴;看来您的代码是合理的,但只需要稍作调整(这很常见)。
【解决方案2】:

试试这个宝石:cells.SpecialCells(xlCellTypeLastCell)
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/range-specialcells-method-excel

尝试以下方法:

Dim sh as Variant

For Each sh In shAry
    Range(sh.cells(1,1),sh.cells.SpecialCells(xlCellTypeLastCell)).Copy
    'wb.Activate 'Leave out. Dont need this.
    WS.Cells(Rows.Count, 3).End(xlUp).End(xlUp)(2).PasteSpecial xlPasteValues
    'Application.CutCopyMode = False 'If you really need this, put it after loop.
Next

Application.CutCopyMode = False

【讨论】:

  • 感谢您对此进行调查,但它似乎仍然存在相同的问题。我做了一个快速模型。这是要复制的 excel wkbk:ufile.io/fkz2z 和源 wkbk:ufile.io/6r9yf。我刚刚添加了一个蓝色按钮,其中包含您上面包含的代码。如果您使用该宏,您可以看到发生了什么。它只是不想看起来有条不紊地复制和粘贴并将它们混合在一起。它把我逼疯了。
【解决方案3】:

额外的.End(xlUp) 是导致您的问题的原因。 (即使你说你在评论中删除了它,它仍然在你的示例文件中)

这是您重构的代码,包括解决的其他一些小问题和内联 cmets(在我所做的更改上标有 <---

Sub Notes2()
    'Last row in column
    Dim ws As Worksheet, shAry As Variant, i As Long
    Dim AOFF As Range
    Dim rOWIS As Long              ' <-- better to use long
    Dim wb As Workbook, wb2 As Workbook
    Dim vFile As Variant
    Dim LastCell As Range          ' <-- Define all variables
    Dim LastCellRowNumber As Long  ' <--
    'Set source workbook
    Set wb = ActiveWorkbook
    Set ws = wb.Worksheets("Sheet 4") ' <-- specify context
    'With ws                          ' <--- not used in rest of code
    '    Set LastCell = .Cells(.Rows.Count, "A").End(xlUp)
    '    LastCellRowNumber = LastCell.Row + 1
    'End With
    'Open the target workbook
    vFile = Application.GetOpenFilename("Excel-files,*.xlsx", _
        1, "Select File To Open", , False)
    'if the user didn't select a file, exit sub
    If vFile = False Then Exit Sub   ' <--  simpler
    Application.ScreenUpdating = False
    Set wb2 = Workbooks.Open(vFile)
    With wb2
        shAry = Array(.Sheets("Week 1"), .Sheets("Week 2"), .Sheets("Week 3"), .Sheets("Week 4"), .Sheets("Over 30"))
    End With
    For i = LBound(shAry) To UBound(shAry)
        shAry(i).UsedRange.Copy
        'wb.Activate                 ' <--- not needed
        ws.Cells(ws.Rows.Count, 3).End(xlUp)(2).PasteSpecial xlPasteValues ' <-- specify ws, remove extra End
        Application.CutCopyMode = False
    Next
    Application.ScreenUpdating = True
    'Close
    wb2.Close False
End Sub

【讨论】:

  • 它非常接近工作,但它仍然粘贴。根据上面来自 Rachel Hettinger 的注释,我们提出了一个很好的粘贴代码 Set LastCell = WS.Range("C:O").Find(What:="*", SearchDirection:=xlPrevious)WS.Cells(LastCell.Row + 1, 3).PasteSpecial xlPasteValues,但上面写着“对象变量或需要定义块”。有任何想法吗?我完全不知道为什么它拒绝正确粘贴。
  • 以上内容应该只从所有 5 张纸上粘贴 'C' 到 'O' 中的值,一张一张地粘贴,就像它出现在 5 张纸中一样(包括空白)。非常感谢您的时间和所有的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多