【问题标题】:Copy paste special VBA复制粘贴专用VBA
【发布时间】:2015-03-13 14:38:44
【问题描述】:

我是一名葡萄牙工程师,我最近开始使用 Visual Basic 在名为“Livro MQTEN”的工作簿上名为“Início”的特定工作表中的一个按钮上进行编程。在工作表“Início”上,我有一个带有以下代码的按钮:

Private Sub CommandButton1_Click()
Dim lngCount As Long
Dim j As String
Dim fileName As String
Dim lngIndex As Long
Dim strPath() As String
Dim nome As String
Dim folha As String

' Open the file dialog
With Application.FileDialog(msoFileDialogOpen)
    .Title = "Selecione o ficheiro dos comboios realizados do dia"
    .InitialFileName = "Explor. *"
    .AllowMultiSelect = False
    .Show
    .Filters.Add "Excel files", "*.xlsx; *.xls", 1

    ' Display paths of each file selected
    For lngCount = 1 To .SelectedItems.Count
        'MsgBox .SelectedItems(lngCount)
        j = .SelectedItems(lngCount)
        'MsgBox (j)

        strPath() = Split(j, "\")   'Put the Parts of our path into an array
        lngIndex = UBound(strPath)
        fileName = strPath(lngIndex)    'Get the File Name from our array

        'MsgBox (fileName)

        nome = fileName

        'Get name of sheet
        Dim wb As Workbook
        Dim ws As Worksheet
        Dim TxtRng  As Range

        Set wb = ActiveWorkbook
        Set ws = wb.Sheets("Início")

        ws.Unprotect

        Set TxtRng = ws.Range("D17")
        TxtRng.Value = nome

        ws.Protect

        folha = Cells.Item(21, 6)

        'MsgBox (folha)

        'Copy from sheet

        Dim x As Workbook, y As Workbook
        Dim ws1 As Worksheet, ws2 As Worksheet
        Dim SrcRange As Range

        Application.ScreenUpdating = False
        Application.DisplayAlerts = False

        Set x = Workbooks.Open(j)
        Set y = ThisWorkbook

        Set ws1 = x.Sheets(folha)
        Set ws2 = y.Sheets("Explor. do Mês")

        Set CopyData = ws1.Range("A1:M8000").EntireColumn
        CopyData.Copy
        Set Addme = ws2.Range("A1:M8000")
        Addme.PasteSpecial xlPasteValues

        x.Close True

        Application.ScreenUpdating = True
        Application.DisplayAlerts = True

    Next lngCount    
End With
End Sub

在代码中:

Set CopyData = ws1.Range("A1:M8000").EntireColumn
CopyData.Copy
Set Addme = ws2.Range("A1:M8000")
Addme.PasteSpecial xlPasteValues

我将整个列从 A 列粘贴到 M 列。我只需要复制和 PasteSpecial 工作表 ws1 中具有工作表 ws2 值的单元格。然后,如果我再次单击按钮并选择另一个工作簿,则将值添加到 ws2 而不是覆盖它们。如何在 Visual Basic 中执行此操作?我在这里缺少什么?拜托各位,我真的,真的需要你们的帮助!提前致谢。

解决了!

只是把上面的代码改成:

With ws2
    'Presuming the column "A" in ws2 will always contain the last row.
    intLastRow = .Cells(Rows.Count, 1).End(xlUp).Row

    'Presuming we will ALWAYS copy the "A1:M8000" range, and that the column "A" is filled.
    'Because we determine the last used row based on this column in ws2 (intLastRow)
    ws1.Range("A1:M8000").Copy
    .Cells(intLastRow + 1, 1).PasteSpecial xlPasteValues
    Application.CutCopyMode = False
End With

并在变量声明中添加:

Dim intLastRow As Integer

【问题讨论】:

  • 通过“然后,如果我再次单击按钮并选择另一个工作簿,则将值添加到 ws2 而不会覆盖它们。”你的意思是在相同的范围内它们应该加在一起(例如,在 ws2 "A1" = 5 中,你点击了按钮,现在 "A1" = 5 + 新值)你想粘贴ws2 中已填充范围底部的新值?
  • 我想将新值粘贴到ws2中已填充范围的底部,伙计。

标签: vba excel copy-paste


【解决方案1】:

用这个更改复制代码:

Dim intLastRow As Integer 'put it where you declare variables.
'Maybe use long, if data on ws2 can exceed 32K rows or something like that.

With ws2
    'Presuming the column "A" in ws2 will always contain the last row.
    intLastRow = .Cells(Rows.Count, 1).End(xlUp).Row

    'Presuming we will ALWAYS copy the "A1:M8000" range, and that the column "A" is filled.
    'Because we determine the last used row based on this column in ws2 (intLastRow)
    .Range(.Cells(intLastRow + 1, 1), .Cells(intLastRow + 1, 13)) = ws1.Range("A1:M8000").Value
End With

编辑 1

根据 OP 的评论修改了代码。现在使用正确的Range("A1:M8000")Cells(intLastRow + 1, 13)

编辑 2

With ws2
    'Presuming the column "A" in ws2 will always contain the last row.
    intLastRow = .Cells(Rows.Count, 1).End(xlUp).Row

    'Presuming we will ALWAYS copy the "A1:M8000" range, and that the column "A" is filled.
    'Because we determine the last used row based on this column in ws2 (intLastRow)
    ws1.Range("A1:M8000").Copy
    .Cells(intLastRow + 1, 1).PasteSpecial xlPasteValues
    Application.CutCopyMode = False
End With

【讨论】:

  • 我会试试这个,但我有一个问题:为什么使用 Range("B1:M8000").Value 而不是 Range("A1:M8000").Value?
  • 大声笑,我的错误,对不起。我以为我是从您的代码中复制的。但是你当然可以使用Range("A1:M8000")。那是我的测试用例。
  • 我测试过了,这段代码只复制了第一行。
【解决方案2】:

您可以尝试使用“For”方法单独读取每个单元格 只有当单元格不为空时,下面的代码才会从 sheet1 复制,并且只有在 sheet2 中的单元格未填充时才会粘贴

'this one will run each row    
For i = 1 to 8000 
     'this one will run each collumn
     For j = 1 to 13
          If ws1.cells(i,j) <> "" then
               ws1.cells(i,j).copy

          if ws2.cells(i,j) = "" then
               ws2.cells(i,j).PasteSpecial xlPasteValues

          Else:
               cutcopymode=false

          End if 
          End if
     Next
Next

【讨论】:

  • 我会尝试这个解决方案并报告它是否有效,谢谢队友:)
  • @user3664117 但是根据我阅读的内容,您需要编辑代码,因为我给您的代码只会在命运单元格为空的情况下粘贴值,您想要粘贴在下面的那个那已经可以了,所以你需要给 i 计数器设置一个条件,这样他就不会总是从第 1 行开始,而是从 8001 开始,如果你已经完成了一次,如果你已经完成了两次,则从 16001 开始,这就是你想要的吗?
  • 我输入了 8000 数字,因为它总是超过我导入数据的工作表中的值的数量。我有那个解决方案,因为我事先并不知道 Worsheet ws1 有多少价值。最终的解决方案是将 ws1 中的数据提取到底部,然后当我从另一个类似的工作表中导入数据时,新数据将进入第一个工作表的底部,依此类推。
  • @user3664117 如果它对你有用 =] 只需将答案标记为正确请
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多