【问题标题】:How to copy data whilst changing column如何在更改列时复制数据
【发布时间】:2015-09-24 13:04:19
【问题描述】:

又是我...我有一些代码可以从某个列(来自工作表“转换器”)复制单元格并将其粘贴到不同的列(工作表“未分配”)。然后将这些值(ID)用作参考点,将每行(记录)的其余单元格移动到我需要它的正确位置。

但是,我无法获取将 ID 连续复制到空白行中的代码,这样它们就不会覆盖前一组。我认为这与Master.Cells(rowB, colB) = yourData 行有关,但我无法弄清楚。我尝试将rowB 更改为相同的xlUp 以查找列中最后一个未使用的单元格(与lastA = Slave.Cells(Rows.Count, colA).End(xlUp).Row 一样),但我无法让它工作。有什么想法吗?

当前代码:

Private Sub CommandButton21_Click()

Dim colA As Integer, colB As Integer
Dim rowA As Integer, rowB As Integer
Dim Master As Worksheet, Slave As Worksheet 'declare both

Application.ScreenUpdating = False

Set Master = ThisWorkbook.Worksheets("Unallocated")
Set Slave = ThisWorkbook.Worksheets("Convertor")

colA = 17 
colB = 29 

rowA = 1 
rowB = 1 

lastA = Slave.Cells(Rows.Count, colA).End(xlUp).Row 'This finds the last row of the data of the column FROM which i'm copying
For x = rowA To lastA 'Loops through all the rows of A
    yourData = Cells(x, colA)
    Master.Cells(rowB, colB) = yourData
    rowB = rowB + 1 'Increments the current line of destination workbook
Next x 'Skips to next row

For j = 1 To 5000 '(the master sheet)

    For i = 1 To 5000 '(the slave sheet) 'for first 1000 cells

        If Trim(Master.Cells(j, 29).Value2) = vbNullString Then Exit For 'if ID cell is blank exit

        If Master.Cells(j, 29).Value = Slave.Cells(i, 17).Value Then

            If IsEmpty(Slave.Cells(i, 3)) Then Exit Sub

            Master.Cells(j, 2).Value = Slave.Cells(i, 3).Value 'Move all other data based on the ID
            Master.Cells(j, 8).Value = Slave.Cells(i, 4).Value
            Master.Cells(j, 9).Value = Slave.Cells(i, 5).Value
            Master.Cells(j, 10).Value = Slave.Cells(i, 6).Value
            Master.Cells(j, 11).Value = Slave.Cells(i, 7).Value
            Master.Cells(j, 12).Value = Slave.Cells(i, 8).Value
            Master.Cells(j, 13).Value = Slave.Cells(i, 9).Value
            Master.Cells(j, 4).Value = Slave.Cells(i, 10).Value
            Master.Cells(j, 23).Value = Slave.Cells(i, 11).Value
            Master.Cells(j, 24).Value = Slave.Cells(i, 12).Value
            Master.Cells(j, 25).Value = Slave.Cells(i, 13).Value
            Master.Cells(j, 26).Value = Slave.Cells(i, 14).Value
            Master.Cells(j, 27).Value = Slave.Cells(i, 15).Value
            Master.Cells(j, 28).Value = Slave.Cells(i, 16).Value

            If Not IsEmpty(Slave.Cells(i, 3)) Then _
            Slave.Cells(i, 3).EntireRow.Delete 'deletes row after it has been copied

        End If
    Next

Next

Application.ScreenUpdating = True

End Sub

【问题讨论】:

  • 你为什么不在同一个循环中完成所有的复制?
  • 我不太确定怎么做。最初我正在研究静态值(ID)被用作移动其余数据的锚点(第二个循环)。但是现在 ID 现在只在第一张纸上,所以我认为这些需要首先传输以作为其余数据的锚点。我使用第二个循环(值),因为它似乎是将大量数据移动到我需要的正确顺序的最快方法。谢谢。
  • 查看我的新答案。这将在当前工作表上逐行进行并将数据复制到另一张工作表。我们一次性完成。

标签: excel vba copy


【解决方案1】:

让我们从一个简单的循环开始,为每一行复制数据。然后你可以添加你的支票。

您可以使用 worksheet.range 写入单元格(列行),例如 ("A4") 或 ("A" & counter)。

Private Sub CommandButton21_Click()
    Dim ws As Excel.Worksheet
    Dim wsMaster As Excel.Worksheet
    Dim strValue As String

    Set ws = ActiveWorkbook.Sheets("Convertor")
    Set wsMaster = ActiveWorkbook.Sheets("Unallocated")

    'Count of row to read from
    Dim lRow As Long
    lRow = 1

    'Count of row to write to
    Dim jRow As Long
    jRow = 1

    ws.Activate
    'Loop through and copy what is in the rows
    Do While lRow <= ws.UsedRange.Rows.count

        wsMaster.Range("AC" & jRow).Value = ws.Range("Q" & lRow).Value

        wsMaster.Range("B" & jRow).Value = ws.Range("C" & lRow).Value
        wsMaster.Range("H" & jRow).Value = ws.Range("D" & lRow).Value
        wsMaster.Range("I" & jRow).Value = ws.Range("E" & lRow).Value
        wsMaster.Range("J" & jRow).Value = ws.Range("F" & lRow).Value
        wsMaster.Range("K" & jRow).Value = ws.Range("G" & lRow).Value
        wsMaster.Range("L" & jRow).Value = ws.Range("H" & lRow).Value
        wsMaster.Range("M" & jRow).Value = ws.Range("I" & lRow).Value
        wsMaster.Range("D" & jRow).Value = ws.Range("J" & lRow).Value
        wsMaster.Range("W" & jRow).Value = ws.Range("K" & lRow).Value
        wsMaster.Range("X" & jRow).Value = ws.Range("L" & lRow).Value
        wsMaster.Range("Y" & jRow).Value = ws.Range("M" & lRow).Value
        wsMaster.Range("Z" & jRow).Value = ws.Range("N" & lRow).Value
        wsMaster.Range("AA" & jRow).Value = ws.Range("O" & lRow).Value
        wsMaster.Range("AB" & jRow).Value = ws.Range("P" & lRow).Value

        ws.Rows(lRow).EntireRow.Delete

        'Increment counters for both sheets. We can actually use just one counter, but if there is ever a condition that will cause us to not copy a row, then we will need two counters.
        jRow = jRow + 1
        'lRow = lRow + 1 'This is commented out because we are deleting rows after we copy them.

    Loop
End Sub

如果您确实需要在复制后删除行,那么我们将不得不不增加 lRow 值。

【讨论】:

  • HI @MatthewD 是的,不幸的是,我需要在复制后删除行,因为“转换器”表每天都会输入大量数据,因此需要自行清除。除非可能在所有复制循环结束时,只需添加一个带有数据的选择单元格并删除某种代码?还是简单地添加一个清除循环以从前面提到的每个单元格的列中删除所有数据?
  • 如果每一行每天都会被删除。您可以继续删除 lrow = lrow + 1,然后它将复制 lRow(将为 1),然后将其删除,然后再次复制 lrow(这将是向上移动的下一行)。
  • 非常感谢@MatthewD。这个当前的代码显然是无穷无尽的,因为我认为它可以浏览整张纸。在 jRow = jRow + 1 之前使用 IsEmpty() 为 ID 添加 if 语句是否有效?此外,如果多次使用,它会覆盖“未分配”表上的先前数据。为了防止这种情况,我只需在 jRow = 中添加一个行 xlUp 计数器?再次感谢!
  • 我设法让代码正常工作。我将 lRow 更改为 2(以防止它触及标题,抱歉我没有指定),将 `jRow = 1` 更改为 jRow = wsMaster.Range("B" &amp; Rows.Count).End(xlUp).Row + 1 以在“未分配”表上写入连续行,并添加 if 语句 @987654323 @ 在 ws.Rows(lRow).EntireRow.DeletejRow = jRow + 1 之间添加一个停止到循环中。感谢您的所有帮助@MatthewD!
【解决方案2】:

.Cells 限制了你的方法。

考虑更改为使用 Range("A1:C3000") 表示法,它更强大。

范围.选择 Range.Paste(在目的地为 UsedRows.Count 设置新的高点)

此外,除非您正好有 5000 行,否则它不会那么准确,

实验

ActiveSheet.UsedRange.Rows.Count

【讨论】:

  • 我在第二个大循环部分使用.Cells 将值移动到我需要它们的正确顺序(因此工作表名称为“转换器”),因为我不知道该怎么做任何其他方式。老实说,我得到了第一部分(使用了互联网上的所有 colArowB
猜你喜欢
  • 2020-08-05
  • 1970-01-01
  • 2019-12-25
  • 1970-01-01
  • 2016-06-27
  • 2012-07-19
  • 2021-04-16
  • 2021-07-25
  • 1970-01-01
相关资源
最近更新 更多