【问题标题】:Excel macro - paste only non empty cells from one sheet to anotherExcel 宏 - 仅将非空单元格从一张表粘贴到另一张表
【发布时间】:2013-01-24 07:11:32
【问题描述】:

下面是我用来从一张纸复制单元格并粘贴到另一张纸上的代码。

Sheets("codes").Select
Range("A5:A100").Select
Selection.Copy
Sheets("Sheet2").Select
Range("B28").Select
ActiveSheet.Paste

这个问题是这个范围内的一些单元格是空白的,但我不希望它们被复制到 Sheet2。我从here 得到了一些想法,但是这个方法太长了。有没有一种方法可以迭代选择并检查该值是否为非空并粘贴。这样我还可以在空白单元格中粘贴一些其他文本(例如#NA)。

【问题讨论】:

    标签: excel copy-paste vba


    【解决方案1】:

    看起来您可能在这里犯了一些常见的新手错误(没关系,我们都这样做了)。


    逐行解释的 VBA 示例

    提示:尽量不要使用“选择”或“复制”。当您所要做的就是引用单元格本身时,为什么还要使用 select 呢?例如,而不是使用

    Sheets("codes").Select
    Range("A5:A100").Select
    Selection.Copy
    Sheets("Sheet2").Select
    Range("B28").Select
    ActiveSheet.Paste
    

    随便用

    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".
    

    我刚开始时一直在做同样的事情,但从来没有成功过。 “选择”会导致左右错误。使用我的代码,阅读 cmets,你会没事的。 快速警告:我在这台计算机上没有 Excel,因此无法测试代码。如果由于某种原因它不起作用,请给我留言,明天我会在工作中修复它。

    将数据复制到第二张表时,上述代码将完全省略空白单元格。如果您想为空白单元格输入特定文本(如“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".
    

    【讨论】:

    • 非常感谢您抽出宝贵的时间......这是我第一次处理宏和 Excel 表,我在 3 天前开始工作,今天的截止日期是 EOD :( 所以我想到了什么垃圾:D ...我会尝试这段代码,希望它会起作用
    • @antnewbee 不客气。一开始我也经历了一段艰难的时期,并且完全按照您上面所做的那样做。我制作的代码/cmets 正是我希望有人在我刚开始时告诉我的内容。我不能为别人说话,但是一旦我点击了上述概念,一切就变得容易多了。
    • @Lopside 通过查看您的解决方案,在逐个单元格地复制时需要时间。而且它只复制值(公式、格式等)丢失。但是对于初学者的 cmets +1
    • 对 cme​​ts 正好 +1 :)
    • @Lopsid: 是的,现在快完成了
    【解决方案2】:

    简单:

      Sheet1.Range("A1:a500").SpecialCells(xlCellTypeConstants).Copy Sheet2.Range("b2")
    

    我使用了xlCellTypeConstants,但还有很多其他的可能性。

    Sheet1 通常等同于Sheets("Sheet1")。第一个是 VBE(程序员视图)中的名称,第二个是用户界面(用户视图)中的名称。我通常更喜欢第一种语法,因为它更短并且允许重命名工作表(为用户)而不影响代码。

    【讨论】:

      【解决方案3】:

      如果您不需要格式化,我会使用以下内容。它所做的只是将您在工作表上指定的范围复制到一个变量,循环遍历该变量,检查是否为空的单元格并放入您喜欢的任何字符串。它又好又快。如果您想保留格式,您可以只将特殊格式粘贴到输出范围。

      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
      

      然后调用它:

      Call CopyNonBlankCells(Sheets("codes").Range("A5:A100"), Sheets("Sheet2").Range("B28"), "Non-blank")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-08
        • 2019-10-10
        • 2015-02-09
        • 1970-01-01
        • 2020-02-02
        • 2015-01-17
        相关资源
        最近更新 更多