VBA : 从 2 列或更多列复制值并将它们粘贴到 1 列而不覆盖值
VBA : Copy values from 2 or more columns and paste them in 1 column without overwriting the values
我是 VBA 的新手,这是我第一次 post 在这里,所以请原谅我的业余问题,但是我如何从 2 列或更多列复制值并将它们粘贴到 1列而不覆盖值(即连续粘贴在单个列中的值)......包含值的列是要粘贴到 AB 列中的 U、V 和 W......
请查找以下代码:
Private Sub CommandButton1_Click()
Dim a As Integer
Range("u1").Select
Noofcolumns = Range(Selection, Selection.End(xlToRight)).Columns.Count
For i = 1 To Noofcolumns
Cells(1, 20 + i).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
For j = 1 To 500
a = Cells(j, 28).Value
If IsEmpty(a) Then
Cells(j, 28).Select
Selection.PasteSpecial Paste:=xlPasteValues
Else: GoTo 1
End If
Next j
Next i
End Sub
您需要考虑的一些事项:
阅读 how to avoid the use of .Select。我认为这里是 SO 上分享最多的 post 之一,也是更好地参考 Range
object.
的重要指南
要基于第一点,您需要明确引用 Range
objects。例如 Range("u1").Select
将在当前活动的工作表上 select U1
。相反,至少,使用工作表参考(即使是工作簿参考也可能更好)
其次,您已使用 XlToRight
检索上次使用的列。如果这是你的意图,那可能就好了。但是为了将来的参考,如果您的数据存在差距,您可能会得到 Range
不满意的结果。 XlToLeft
可能更好,例如下面会在第一行从右到左找到最后使用的列:
With Sheet1
LastColumn = .Cells(1, sht.Columns.Count).End(xlToLeft).Column
End with
在你的情况下,甚至可能不需要这样的评估,因为你的值在列 U:W
中,而你可以只使用 For x = # to #
循环。
当您要查找上次使用的行时同样如此。空白单元格可能会影响 XlDown
,但 XlUp
会反击。可以找到关于查找最后一行的更深入 post here,也是一个非常有价值的 SO post。例如,下面将从 A 列获取最后使用的行:
With Sheet1
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End with
还有就是不需要用Copy
传值,直接传值即可,例如(简体):
With Sheet1
.Cells(1, 1) = .Cells(1, 2)
End with
另一个(次要)点是使用 Integer
数据类型变量没有用。如果误用导致错误,它们很容易溢出。你最好使用 Long
数据类型。
尽量避免 Goto
语句,这会导致意大利面条式代码,在你的情况下甚至没有语句丢失(goto 实际上无处可去)
现在有了这些点你可以尝试改变你的代码,现在看起来像下面这样:
示例数据:
示例代码:
Private Sub CommandButton1_Click()
'Dimming our variables properly
Dim lr1 As Long, lr2 As Long, x As Long
'Using an explicit sheet reference
With Sheet1
'Looping over the columns U:W
For x = 21 To 23
'Getting the last used row from the column
lr1 = .Cells(.Rows.Count, x).End(xlUp).Row
'Getting the last used row from column J
lr2 = .Cells(.Rows.Count, 28).End(xlUp).Row + 1
'Transfer data directly
.Cells(lr2, 28).Resize(lr1 - 1).Value2 = .Range(.Cells(2, x), .Cells(lr1, x)).Value2
'Continue to next column in iteration
Next x
End With
End Sub
结果:
以上都是假设您在所有这些列中都有一个 header。如果不是,只需相应调整即可。
我是 VBA 的新手,这是我第一次 post 在这里,所以请原谅我的业余问题,但是我如何从 2 列或更多列复制值并将它们粘贴到 1列而不覆盖值(即连续粘贴在单个列中的值)......包含值的列是要粘贴到 AB 列中的 U、V 和 W......
请查找以下代码:
Private Sub CommandButton1_Click()
Dim a As Integer
Range("u1").Select
Noofcolumns = Range(Selection, Selection.End(xlToRight)).Columns.Count
For i = 1 To Noofcolumns
Cells(1, 20 + i).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
For j = 1 To 500
a = Cells(j, 28).Value
If IsEmpty(a) Then
Cells(j, 28).Select
Selection.PasteSpecial Paste:=xlPasteValues
Else: GoTo 1
End If
Next j
Next i
End Sub
您需要考虑的一些事项:
阅读 how to avoid the use of .Select。我认为这里是 SO 上分享最多的 post 之一,也是更好地参考
Range
object. 的重要指南
要基于第一点,您需要明确引用
Range
objects。例如Range("u1").Select
将在当前活动的工作表上 selectU1
。相反,至少,使用工作表参考(即使是工作簿参考也可能更好)其次,您已使用
XlToRight
检索上次使用的列。如果这是你的意图,那可能就好了。但是为了将来的参考,如果您的数据存在差距,您可能会得到Range
不满意的结果。XlToLeft
可能更好,例如下面会在第一行从右到左找到最后使用的列:With Sheet1 LastColumn = .Cells(1, sht.Columns.Count).End(xlToLeft).Column End with
在你的情况下,甚至可能不需要这样的评估,因为你的值在列
U:W
中,而你可以只使用For x = # to #
循环。当您要查找上次使用的行时同样如此。空白单元格可能会影响
XlDown
,但XlUp
会反击。可以找到关于查找最后一行的更深入 post here,也是一个非常有价值的 SO post。例如,下面将从 A 列获取最后使用的行:With Sheet1 LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row End with
还有就是不需要用
Copy
传值,直接传值即可,例如(简体):With Sheet1 .Cells(1, 1) = .Cells(1, 2) End with
另一个(次要)点是使用
Integer
数据类型变量没有用。如果误用导致错误,它们很容易溢出。你最好使用Long
数据类型。尽量避免
Goto
语句,这会导致意大利面条式代码,在你的情况下甚至没有语句丢失(goto 实际上无处可去)
现在有了这些点你可以尝试改变你的代码,现在看起来像下面这样:
示例数据:
示例代码:
Private Sub CommandButton1_Click()
'Dimming our variables properly
Dim lr1 As Long, lr2 As Long, x As Long
'Using an explicit sheet reference
With Sheet1
'Looping over the columns U:W
For x = 21 To 23
'Getting the last used row from the column
lr1 = .Cells(.Rows.Count, x).End(xlUp).Row
'Getting the last used row from column J
lr2 = .Cells(.Rows.Count, 28).End(xlUp).Row + 1
'Transfer data directly
.Cells(lr2, 28).Resize(lr1 - 1).Value2 = .Range(.Cells(2, x), .Cells(lr1, x)).Value2
'Continue to next column in iteration
Next x
End With
End Sub
结果:
以上都是假设您在所有这些列中都有一个 header。如果不是,只需相应调整即可。