vba Excel 宏 - 仅将非空单元格从一张纸粘贴到另一张纸上
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14495769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Excel macro - paste only non empty cells from one sheet to another
提问by antnewbee
Below is the code which I am using to copy cells from one sheet and paste in to another.
下面是我用来从一张纸上复制单元格并粘贴到另一张纸上的代码。
Sheets("codes").Select
Range("A5:A100").Select
Selection.Copy
Sheets("Sheet2").Select
Range("B28").Select
ActiveSheet.Paste
The problem with this is some cells in this range are blank but I do not want them to be copied to Sheet2. I have got some idea from herebut this method is too long. Is there a way I can iterate on the selection and check if the value is non-empty and paste. This way I can also paste some other text (eg #NA) in the blank cells.
问题是此范围内的某些单元格为空白,但我不希望将它们复制到 Sheet2。我从这里得到了一些想法,但这种方法太长了。有没有办法可以迭代选择并检查值是否为非空并粘贴。这样我还可以在空白单元格中粘贴一些其他文本(例如#NA)。
回答by Lopsided
Looks like you may be making some common rookie mistakes here (it's okay we all did it).
看起来您可能在这里犯了一些常见的新手错误(没关系,我们都这样做了)。
VBA example with line-by-line explanations
带有逐行解释的 VBA 示例
TIP:Try not to use "Select" or "Copy". Why use select when all you have to do is reference the cells themselves? For example, instead of using
提示:尽量不要使用“选择”或“复制”。当您所要做的就是引用单元格本身时,为什么要使用 select?例如,而不是使用
Sheets("codes").Select
Range("A5:A100").Select
Selection.Copy
Sheets("Sheet2").Select
Range("B28").Select
ActiveSheet.Paste
Just use
只需使用
dim mySheet as Worksheet, myOtherSheet as Worksheet, myBook as Workbook 'Define your workbooks and worksheets as variables
set myBook = Excel.ActiveWorkbook
set mySheet = myBook.Sheets("codes")
set myOtherSheet = myBook.Sheets("Sheet2")
dim i as integer, j as integer 'Define a couple integer variables for counting
j = 28 'This variable will keep track of which row we're on in Sheet2 (I'm assuming you want to start on line 28)
for i = 5 to 100 'This is the beginning the the loop which will repeat from 5 to 100 . . .
if mySheet.Cells(i,1).value <> "" then ' . . . for each digit, it will check if the cell's value is blank. If it isn't then it will . . .
myOtherSheet.Cells(j,2).value = mySheet.Cells(i,1).value ' . . . Copy that value into the cell on Sheet2 in the row specified by our "j" variable.
j = j + 1 'Then we add one to the "j" variable so the next time it copies, we will be on the next available row in Sheet2.
end if
next i 'This triggers the end of the loop and moves on to the next value of "i".
I did the same thing all the time when I first started, and it never works out right. "Select" causes errors left and right. Use my code, read the comments, and you'll be fine. A quick WARNING:I don't have Excel on this computer so I couldn't test the code. If it doesn't work for some reason, leave me a comment and tomorrow I'll fix it at work.
刚开始的时候我一直在做同样的事情,但从来没有成功过。“选择”会导致左右错误。使用我的代码,阅读评论,你会没事的。快速警告:我在这台计算机上没有 Excel,所以我无法测试代码。如果由于某种原因它不起作用,请给我留言,明天我会在工作中修复它。
The above code will omit blank cells completely when copying the data over to your second sheet. If you want to input a certain text for blank cells instead (like "N/A"), then you can use the following:
将数据复制到第二个工作表时,上面的代码将完全省略空白单元格。如果要为空白单元格输入特定文本(如“N/A”),则可以使用以下命令:
dim mySheet as Worksheet, myOtherSheet as Worksheet, myBook as Workbook 'Define your workbooks and worksheets as variables
set myBook = Excel.ActiveWorkbook
set mySheet = myBook.Sheets("codes")
set myOtherSheet = myBook.Sheets("Sheet2")
dim i as integer, j as integer 'Define a couple integer variables for counting
j = 28 'This variable will keep track of which row we're on in Sheet2 (I'm assuming you want to start on line 28)
for i = 5 to 100 'This is the beginning the the loop which will repeat from 5 to 100 . . .
if mySheet.Cells(i,1).value <> "" then ' . . . for each digit, it will check if the cell's value is blank. If it isn't then it will . . .
myOtherSheet.Cells(j,2).value = mySheet.Cells(i,1).value ' . . . Copy that value into the cell on Sheet2 in the row specified by our "j" variable.
else 'If the cell is blank, then . . .
myOtherSheet.Cells(j,2).value = "N/A" ' . . . place the text "N/A" into the cell in row "j" in Sheet2.
end if 'NOTICE we moved the "end if" statement up a line, so that it closes the "if" statement before the "j = j + 1" statement. _
This is because now we want to add one to the "j" variable (i.e., move to the next available row in Sheet2) regardless of whether the cell in the "codes" sheet is blank or not.
j = j + 1 'Then we add one to the "j" variable so the next time it copies, we will be on the next available row in Sheet2.
next i 'This triggers the end of the loop and moves on to the next value of "i".
回答by Patrick Honorez
Easy:
简单:
Sheet1.Range("A1:a500").SpecialCells(xlCellTypeConstants).Copy Sheet2.Range("b2")
I used xlCellTypeConstants
but there are many other possibilities.
我用过,xlCellTypeConstants
但还有很多其他的可能性。
Sheet1
is generally equivalent to Sheets("Sheet1")
. The first one is the name in the VBE (programmer view), the second is the name in the user interface (user view). I generally prefer the fiirst syntax because it is shorter and allows renaming the sheets (for the user) without impacting the code.
Sheet1
一般等价于Sheets("Sheet1")
. 第一个是 VBE(程序员视图)中的名称,第二个是用户界面(用户视图)中的名称。我通常更喜欢第一种语法,因为它更短,并且允许在不影响代码的情况下重命名工作表(为用户)。
回答by CuberChase
If you don't need formatting I'd use the following. All it does is copy the range you specify on the worksheet to a variable, loop through that variable, check for cells that are empty and put in whatever string you like. It's nice and quick. If you want to preserve the formatting, you can paste special just the formats to the output range.
如果您不需要格式化,我会使用以下内容。它所做的只是将您在工作表上指定的范围复制到一个变量,遍历该变量,检查空单元格并放入您喜欢的任何字符串。它又好又快。如果您想保留格式,您可以将特殊格式粘贴到输出范围。
Sub CopyNonBlankCells(rFromRange As Range, rToCell As Range, sSubIn As String)
'You have three inputs. A range to copy from (rFromRange), a range to copy to (rToCell) and a string to put in the blank cells.
Dim vData As Variant, ii As Integer, jj As Integer
'Set to a variable since it's quicker
vData = rFromRange.Value
'Loop through to find the blank cells
For ii = LBound(vData, 1) To UBound(vData, 1) 'Loop the rows
For jj = LBound(vData, 2) To UBound(vData, 2) 'Loop the columns
'Check for empty cell. Quicker to use Len function then check for empty string
If VBA.Len(vData(ii, jj)) = 0 Then vData(ii, jj) = sSubIn
Next jj
Next ii
'Output to target cell. Use the 'With' statement because it makes the code easier to read and is more efficient
With rToCell.Parent
.Range(.Cells(rToCell.Row, rToCell.Column), .Cells(rToCell.Row + UBound(vData, 1) - 1, rToCell.Column + UBound(vData, 2) - 1)).Value = vData
End With
End Sub
And call it with:
并调用它:
Call CopyNonBlankCells(Sheets("codes").Range("A5:A100"), Sheets("Sheet2").Range("B28"), "Non-blank")