VBA为什么在追加表后会出现空行?

huangapple go评论72阅读模式
英文:

VBA why do I have blank rows after appending tables?

问题

VBA新手。

基本上,我正在收集每周的合规记录,以获取逐周数据。
我的主要问题是,我有一个查询表,它是动态的,在一个好的周里,它是空的。
我想要能够提取此表的内容并将其粘贴到包含年度数据的静态表格下的第一个空行。

这一步骤手动完成很容易,但出于将这份报告交给不太懂技术的团队成员的考虑,我想要自动化。

这个问题: https://stackoverflow.com/questions/53054058/how-to-copy-and-paste-two-separate-tables-to-the-end-of-another-table-in-vba 给了我到目前为止使用的大部分内容。我已经更改了其中一些值和声明,以使其与我的工作表和范围相关,但在很大程度上,它是根据“Destination: =”列出的解决方案进行复制/粘贴。

在很大程度上,这个代码块确实做到了我想要的事情:

(我已经注释掉了GCC的第二个范围,但打算在解决了这个问题后再使用它。)

Sub Inv_Copy_Paste()
    Dim TC As Worksheet
    'Dim Chart As Worksheet
    Dim lr2 As Long

    Set TC = Worksheets("TC Data Dump")
    'Set Chart = Worksheets("Inventory for Charts")
    lr2 = TC.Cells(Rows.Count, 1).End(xlUp).Row

    With TC
        .Range("O2", ("W2" & .Range("O" & Rows.Count).End(xlUp).Row)).Copy Destination:=TC.Cells(Rows.Count, 1).End(xlUp).Offset(1)
        '.Range("K2", ("S2" & .Range("K" & Rows.Count).End(xlUp).Row)).Copy Destination:=Chart.Range("A" & lr2 + 1)
    End With
End Sub

我遇到的唯一例外是,一旦代码复制了填充的数据,它会在数据下方添加一些空白行。

20个空行

这是我在现有代码中忽略的问题吗?
我会承认我几乎不理解代码在“With TC”部分的工作原理,所以非常感谢任何额外的上下文。

额外问题:当我尝试将另一个动态查询表复制到第二个静态表时,我是否需要一个单独的子程序/工作表?

英文:

VBA newb here.

Essentially, I'm collecting weekly compliance records for week over week data.
My main issue is that I have a queried table that is dynamic and on a good week it's empty.
I would like to be able to pull the contents of this table and paste them to the first empty row below a static table that contains year to date data.

This step is an easy one to accomplish manually, but I'm looking to automate for the sake of handing this report off to my less-than-tech-savvy team members.

This question: https://stackoverflow.com/questions/53054058/how-to-copy-and-paste-two-separate-tables-to-the-end-of-another-table-in-vba has given me most of what I'm using so far. I've swapped a few of their values and declarations to be relevant to my sheet and ranges, but for the most part it's copy/paste with the listed solution for "Destination: ="

For the most part, this block does the exact thing I'm after:

(I've commented out GCC's second range, but intend to utilize it once this one's settled.)

Sub Inv_Copy_Paste()
    Dim TC As Worksheet
    'Dim Chart As Worksheet
    Dim lr2 As Long

    Set TC = Worksheets("TC Data Dump")
    'Set Chart = Worksheets("Inventory for Charts")
    lr2 = TC.Cells(Rows.Count, 1).End(xlUp).Row

    With TC
        .Range("O2", ("W2" & .Range("O" & Rows.Count).End(xlUp).Row)).Copy Destination:=TC.Cells(Rows.Count, 1).End(xlUp).Offset(1)
        '.Range("K2", ("S2" & .Range("K" & Rows.Count).End(xlUp).Row)).Copy Destination:=Chart.Range("A" & lr2 + 1)
    End With
End Sub


The one exception that I'm running into is that once the code copies populated data over, it adds a handful of blank lines below the data:

20 Blank Rows

Is this something I'm overlooking in the code that's already here?
I'll grant that I barely understand what the code is doing in the With TC portion, so any additional context would be greatly appreciated.

Bonus question: Will I need a separate Sub/Worksheet when I attempt to copy another dynamic query table to a second static table?

答案1

得分: 0

-lr2 = TC.Cells(Rows.Count, 1).End(xlUp).Row
这里。
与其计算要复制的表格中的行数,不如计算第一列中的行数。
如果您想在此行中更改数字1为要复制的列,我认为应该是"O",即15。

然后,恐怕您需要重新定义第二个表的lr2,或者为其创建另一个变量。
lr3 = TC.Cells(Rows.Count, 11).End(xlUp).Row '11代表k列

请告诉我这是否有帮助。

英文:

Firstly, the row count is counting the number of lines in the first column.
-lr2 = TC.Cells(Rows.Count, 1).End(xlUp).Row
Here.
Rather than counting the number of rows in the tablese you're trying to copy.
If you change the number 1 in this line to the column you are copying. I think its "O" which would be 15.

Then I'm afraid you'd have to redefine the lr2 for the second table or make another variable for it.
lr3 = TC.Cells(Rows.Count, 11).End(xlUp).Row '11 for the k column

Please let me know if this helps.

答案2

得分: 0

以下是您提供的代码的翻译:

Sub oddzac()

Dim RowCount As Integer

ActiveSheet.Range("O2", Cells(Range("W" & Rows.Count).End(xlUp).Row, "W")).Copy Cells(Range("A" & Rows.Count).End(xlUp).Row, 1)
ActiveSheet.Range("K2", Cells(Range("S" & Rows.Count).End(xlUp).Row, "S")).Copy Cells(Range("A" & Rows.Count).End(xlUp).Row + 1, 1)

End Sub
英文:
Sub oddzac()

Dim RowCount As Integer

ActiveSheet.Range("O2", Cells(Range("W" & Rows.Count).End(xlUp).Row, "W")).Copy Cells(Range("A" & Rows.Count).End(xlUp).Row, 1)
ActiveSheet.Range("K2", Cells(Range("S" & Rows.Count).End(xlUp).Row, "S")).Copy Cells(Range("A" & Rows.Count).End(xlUp).Row + 1, 1)

End Sub

This more what you're looking for?

答案3

得分: 0

处理空白

  • 如果您的数据在Excel表中,应该使用它们的方法和属性。
  • 如果您不想使用它们,您将需要编写特殊的、通常复杂的代码。
  • End(xlUp) 只会到达表中的最后一行(单元格)。如果底部有空行或空白行,它们也会被复制。
  • Find 方法与 xlFormulas 一起会到达最后一个非空行,而与 xlValues 一起,它会到达最后一个非空白行。

初始

VBA为什么在追加表后会出现空行?
VBA为什么在追加表后会出现空行?

结果

VBA为什么在追加表后会出现空行?

Sub InvCopyPaste()
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' 包含此代码的工作簿
    
    Dim wsTC As Worksheet: Set wsTC = wb.Sheets("TC Data Dump")
    Dim wsInv As Worksheet: Set wsInv = wb.Sheets("Inventory for Charts")
    
    Dim srg As Range, drg As Range
    
    ' 源:'wsTC' 到 目标:'wsTC'
    Set srg = RefNonBlankRange(wsTC.Range("O2:W2"))
    If Not srg Is Nothing Then
        Set drg = RefFirstNonBlankRowRange(wsTC.Range("A2") _
            .Resize(, srg.Columns.Count)).Resize(srg.Rows.Count)
        drg.Value = srg.Value ' 仅值(最高效)
        'srg.Copy drg ' 替代方法:包括值、公式和格式
        Debug.Print "从 " & srg.Address & " 复制到 " & drg.Address & "。"
    End If
    
    ' 源:'wsTC' 到 目标:'wsInv'
    Set srg = RefNonBlankRange(wsTC.Range("K2:S2"))
    If Not srg Is Nothing Then
        Set drg = RefFirstNonBlankRowRange(wsInv.Range("A2") _
            .Resize(, srg.Columns.Count)).Resize(srg.Rows.Count)
        drg.Value = srg.Value ' 仅值(最高效)
        'srg.Copy drg ' 替代方法:包括值、公式和格式
        Debug.Print "从 " & srg.Address & " 复制到 " & drg.Address & "。"
    End If
    
End Sub

帮助

Function RefNonBlankRange( _
    ByVal FirstRowRange As Range) _
As Range
    With FirstRowRange
        Dim cel As Range: Set cel = .Resize(.Worksheet.Rows.Count - .Row + 1) _
            .Find("*", , xlValues, , xlByRows, xlPrevious)
        If Not cel Is Nothing _
                Then Set RefNonBlankRange = .Resize(cel.Row - .Row + 1)
    End With
End Function

Function RefFirstNonBlankRowRange( _
    ByVal FirstRowRange As Range) _
As Range
    Dim rg As Range: Set rg = FirstRowRange.Rows(1)
    With rg
        Dim cel As Range: Set cel = .Resize(.Worksheet.Rows.Count - .Row + 1) _
            .Find("*", , xlValues, , xlByRows, xlPrevious)
        If Not cel Is Nothing Then Set rg = .Offset(cel.Row - .Row + 1)
    End With
    Set RefFirstNonBlankRowRange = rg
End Function

Debug.Print即时窗口 (Ctrl+G) 中的结果

从 $O$2:$W$6 复制到 $A$4:$I$8。
从 $K$2:$S$6 复制到 $A$6:$I$10。

英文:

Dealing With Blanks

  • If your data is in Excel tables, you should use their methods and properties.
  • If you don't wanna, you'll need to write special, often complicated codes.
  • End(xlUp) will only go up to the last row (cell) in the table. If there are empty or blank rows at the bottom, they will also be copied.
  • The Find method with xlFormulas will go up to the last non-empty row while with xlValues, it will go up (further) to the last non-blank row.

Initial

VBA为什么在追加表后会出现空行?
VBA为什么在追加表后会出现空行?

Result

VBA为什么在追加表后会出现空行?

Main

<!-- language: lang-vb -->

Sub InvCopyPaste()
    
    Dim wb As Workbook: Set wb = ThisWorkbook &#39; workbook containing this code
    
    Dim wsTC As Worksheet: Set wsTC = wb.Sheets(&quot;TC Data Dump&quot;)
    Dim wsInv As Worksheet: Set wsInv = wb.Sheets(&quot;Inventory for Charts&quot;)
    
    Dim srg As Range, drg As Range
    
    &#39; Source: &#39;wsTC&#39; to Destination: &#39;wsTC&#39;
    Set srg = RefNonBlankRange(wsTC.Range(&quot;O2:W2&quot;))
    If Not srg Is Nothing Then
        Set drg = RefFirstNonBlankRowRange(wsTC.Range(&quot;A2&quot;) _
            .Resize(, srg.Columns.Count)).Resize(srg.Rows.Count)
        drg.Value = srg.Value &#39; for only values (most efficient)
        &#39;srg.Copy drg &#39; instead: for values, formulas and formats
        Debug.Print &quot;Copied from &quot; &amp; srg.Address &amp; &quot; to &quot; &amp; drg.Address &amp; &quot;.&quot;
    End If
    
    &#39; Source: &#39;wsTC&#39; to Destination: &#39;wsInv&#39;
    Set srg = RefNonBlankRange(wsTC.Range(&quot;K2:S2&quot;))
    If Not srg Is Nothing Then
        Set drg = RefFirstNonBlankRowRange(wsInv.Range(&quot;A2&quot;) _
            .Resize(, srg.Columns.Count)).Resize(srg.Rows.Count)
        drg.Value = srg.Value &#39; for only values (most efficient)
        &#39;srg.Copy drg &#39; instead: for values, formulas and formats
        Debug.Print &quot;Copied from &quot; &amp; srg.Address &amp; &quot; to &quot; &amp; drg.Address &amp; &quot;.&quot;
    End If
    
End Sub

The Help

<!-- language: lang-vb -->

Function RefNonBlankRange( _
    ByVal FirstRowRange As Range) _
As Range
    With FirstRowRange
        Dim cel As Range: Set cel = .Resize(.Worksheet.Rows.Count - .Row + 1) _
            .Find(&quot;*&quot;, , xlValues, , xlByRows, xlPrevious)
        If Not cel Is Nothing _
                Then Set RefNonBlankRange = .Resize(cel.Row - .Row + 1)
    End With
End Function

Function RefFirstNonBlankRowRange( _
    ByVal FirstRowRange As Range) _
As Range
    Dim rg As Range: Set rg = FirstRowRange.Rows(1)
    With rg
        Dim cel As Range: Set cel = .Resize(.Worksheet.Rows.Count - .Row + 1) _
            .Find(&quot;*&quot;, , xlValues, , xlByRows, xlPrevious)
        If Not cel Is Nothing Then Set rg = .Offset(cel.Row - .Row + 1)
    End With
    Set RefFirstNonBlankRowRange = rg
End Function

Debug.Print Results in the Immediate window (Ctrl+G)

Copied from $O$2:$W$6 to $A$4:$I$8.
Copied from $K$2:$S$6 to $A$6:$I$10.

答案4

得分: 0

另一个论坛提供了以下解决方案:

Sub TC_Copy_Paste()
Dim TC As Worksheet, RowNum As Long
'
Set TC = Worksheets("TC Data Dump")

On Error Resume Next

With TC.Range("P3").ListObject
    RowNum = Application.WorksheetFunction.CountA(.ListColumns(1).DataBodyRange)
    .DataBodyRange.Cells(1, 1).Resize(RowNum, 9).Copy Destination:=TC.Cells(Rows.Count, 5).End(xlUp).Offset(1)
End With

With TC.Range("AJ3").ListObject
    RowNum = Application.WorksheetFunction.CountA(.ListColumns(1).DataBodyRange)
    .DataBodyRange.Cells(1, 1).Resize(RowNum, 9).Copy Destination:=TC.Cells(Rows.Count, 26).End(xlUp).Offset(1)
End With
End Sub

再次强调,我不确定为什么这个代码有效而另一个不起作用,但我想分享最终结果。

英文:

Another forum responded with this solution:

Sub TC_Copy_Paste()
Dim TC As Worksheet, RowNum As Long
&#39;
Set TC = Worksheets(&quot;TC Data Dump&quot;)

On Error Resume Next

With TC.Range(&quot;P3&quot;).ListObject
    RowNum = Application.WorksheetFunction.CountA(.ListColumns(1).DataBodyRange)
    .DataBodyRange.Cells(1, 1).Resize(RowNum, 9).Copy Destination:=TC.Cells(Rows.Count, 5).End(xlUp).Offset(1)
End With

With TC.Range(&quot;AJ3&quot;).ListObject
    RowNum = Application.WorksheetFunction.CountA(.ListColumns(1).DataBodyRange)
    .DataBodyRange.Cells(1, 1).Resize(RowNum, 9).Copy Destination:=TC.Cells(Rows.Count, 26).End(xlUp).Offset(1)
End With
End Sub

Again, I'm not sure why this works and the other doesn't but I wanted to share the end result.

huangapple
  • 本文由 发表于 2023年2月19日 22:17:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75500760.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定