从一个工作表粘贴到另一个工作表不起作用

时间:2015-11-05 14:47:02

标签: excel vba excel-vba

我有一个宏在工作簿中(在两个表格之间)执行此操作。但现在我想在两本工作簿之间做到这一点。我认为逻辑很好,但我错过了什么?

它运行所有代码,但我没有收到任何错误,但同时它没有做任何事情。

Sub CTClearINCIDENTS()

Dim ws1 As Workbook
Dim ws1sheet As Worksheet
Dim ws2 As Workbook
Dim ws2sheet As Worksheet
Dim lastRow As Long

Set ws1 = ThisWorkbook
Set ws1sheet = ws1.Sheets("INCIDENTS")

ws1sheet.Rows(5 & ":" & ws1sheet.Rows.Count).ClearContents

Dim FilePath As String
File_Path = "C:\TEMP\TestExcel\Cambridge Daily Tracker " & Format(Now, "dd-MM-yyyy") & ".xlsx"

Set ws2 = Workbooks.Open(File_Path)
Set ws2sheet = ws2.Sheets("Page 1")

With ws2sheet
    .AutoFilterMode = False
    lastRow = .Range("A" & Rows.Count).End(xlUp).Row
    .Range("A2" & lastRow).Copy
    ws1sheet.Range("A5").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
 End With

End Sub

edit1:minor xlPasteFormats> xlPasteValues我忘记了

2 个答案:

答案 0 :(得分:1)

  1. 如果您只需要复制数据(即没有单元格格式化),那么最有效的方法是将工作表的范围值读入Variant,然后将Variant写入范围你的新工作表。

  2. 在定义范围时,您需要注意失去对工作表对象的控制,以及进行比您需要的选择更大的选择,或者依赖可能会让您感到困惑的范围定义。在您的代码中有一些例子。在这一行中:lastRow = .Range("A" & Rows.Count).End(xlUp).Row您在ws2sheet中定义范围,但计算活动工作表中的行数(无论是哪种工作表 - 在这种情况下,很可能是相同的)。在这一行中:ws1sheet.Rows(5 & ":" & ws1sheet.Rows.Count).ClearContents您可以在第4行下方定义整个工作表以清除(即使您没有使用它们,也可以使用所有数百万行)。当然,使用ClearContents Excel将比处理使用范围之外的单元格更加智能,但有一天你可能会陷入困境。

  3. 如果您使用字符串,最简单的方法是遵循Excel本身使用的相同地址约定。一旦你开始偏离这些约定,你就会得到一些意想不到的结果。只需尝试在代码的这些行上添加Select,您就会惊讶于您所拥有的内容:

    lastRow = .Range("A" & Rows.Count).End(xlUp).Row
    .Range("2:2" & lastRow).Select
    
  4. 比方说,你的最后一行是23,你的代码实际上是选择“2:223”。

    作为个人偏好,我希望将最后一行设为Range而不是Long,因为我可以完全避免您所犯的错误类型,如下所示:

        set rng = .Range("A1", lastRow)
    

    如果您需要跨越第一列以外的范围,可以逐列调整大小。这与您的情况相关,因为当您的数据可能只有几列左右时,您正在使用整行。同样,Excel可能会处理大多数保留在工作表使用范围内的情况,但为什么不自己控制范围呢?

    我在下面给出了两个可能的编码解决方案示例。在这两种情况下,我都假设了最后一列“E”,但你会改变它以适应你的项目。版本1是Variant,lastCell是Range选项,版本2是粘贴,lastCell是Long选项:

    Dim fileName As String
    Dim sourceBook As Workbook
    Dim sourceSheet As Worksheet
    Dim targetSheet As Worksheet
    Dim sourceData As Variant
    Dim rng As Range
    Dim lastCell As Range
    
    'Prepare the target sheet
    Set targetSheet = ThisWorkbook.Sheets("INCIDENTS")
    Set rng = targetSheet.Range("A5", _
        targetSheet.UsedRange.Cells(sourceSheet.UsedRange.Cells.Count))
    rng.ClearContents
    
    'Open source workbook and find data range
    fileName = "C:\TEMP\TestExcel\Cambridge Daily Tracker " & Format(Now, "dd-MM-yyyy") & ".xls"
    Set sourceBook = Workbooks.Open(File_Path)
    Set sourceSheet = sourceBook.Sheets("Page 1")
    Set lastCell = sourceSheet.Cells(sourceSheet.Rows.Count, "A").End(xlUp)
    'Resize by desired columns (I've used '5', ie up to "E" column)
    sourceData = sourceSheet.Range("A2", lastCell).Resize(, 5).Value2
    
    'Copy the data
    targetSheet.Range("A5").Resize(UBound(sourceData, 1), UBound(sourceData, 2)) = sourceData
    

    版本2,如果你觉得有必要使用粘贴:

    Dim fileName As String
    Dim sourceBook As Workbook
    Dim sourceSheet As Worksheet
    Dim targetSheet As Worksheet
    Dim rng As Range
    Dim lastRow As Long
    
    'Clear below row 4 of sheets
    Set targetSheet = ThisWorkbook.Sheets("INCIDENTS")
    Set rng = targetSheet.Range("A5", _
        targetSheet.UsedRange.Cells(sourceSheet.UsedRange.Cells.Count))
    
    rng.ClearContents
    
    'Open source workbook and remove auto filter
    fileName = "C:\TEMP\TestExcel\Cambridge Daily Tracker " & Format(Now, "dd-MM-yyyy") & ".xls"
    Set sourceBook = Workbooks.Open(File_Path)
    Set sourceSheet = sourceBook.Sheets("Page 1")
    sourceSheet.AutoFilterMode = False
    
    'Copy the data
    lastRow = sourceSheet.Cells(sourceSheet.Rows.Count, "A").End(xlUp).Row
    Set rng = sourceSheet.Range("A2", sourceSheet.Cells(lastRow, "E")) ' whatever the last column is (I'ved used "E" as example)
    rng.Copy
    targetSheet.Range("A5").PasteSpecial xlPasteValues, xlPasteSpecialOperationNone, False, False
    

答案 1 :(得分:0)

Per @ Ambie的建议我改变了范围。起初(A2:A)它只复制A列。但我发现(2:2)会复制行。

现在正在运作:

Sub CTClearINCIDENTS()

Dim ws1 As Workbook
Dim ws1sheet As Worksheet
Dim ws2 As Workbook
Dim ws2sheet As Worksheet
Dim lastRow As Long

Set ws1 = ThisWorkbook
Set ws1sheet = ws1.Sheets("INCIDENTS")

ws1sheet.Rows(5 & ":" & ws1sheet.Rows.Count).ClearContents

Dim FilePath As String
File_Path = "C:\TEMP\TestExcel\Cambridge Daily Tracker " & Format(Now, "dd-MM-yyyy") & ".xls"

Set ws2 = Workbooks.Open(File_Path)
Set ws2sheet = ws2.Sheets("Page 1")

With ws2sheet
    .AutoFilterMode = False

    lastRow = .Range("A" & Rows.Count).End(xlUp).Row
    .Range("2:2" & lastRow).Copy
    ws1sheet.Range("A5").PasteSpecial Paste:=xlValues, Operation:=xlNone, _
    SkipBlanks:=False, Transpose:=False
 End With

End Sub