尝试使用Excel VBA跳过复制/粘贴循环中的空白行

我有一个Excel文件中的行项目的复制/粘贴循环,将这些行项目中的数据导出到基于Excel的表单中,并通过行B中的值保存每个表单。我的问题是这些行项目分为3个不同的行同一张表上的表格,每个表格都有不同数量的行项目进行复制。 此外,每个表格由2个空白行分隔。

我需要macros为我做什么:

  1. 从第17行开始,复制第一个表中的所有行项,直到它碰到一个空白行 – 这个从1行到600行不等。
  2. 跳到SecondTable并执行相同的function。
  3. 重复第三表

我忽略了一些声明,因为我删除了大部分代码以提高可读性。 我想我会需要3个独立的复制/粘贴循环来完成这个(我只包括2在这里),我试过使用。find引用第二/第三表的开始。 macros通过第一个表正常运行,但是当它到达一个空行时不会停止,并且当它尝试根据空单元格的值保存文件时失败。 我相信问题在于使用EndOne = .Range("B" & .Rows.Count).End(xlUp).Row参数。 它不是只计算第一个表的非空白行,而是统计第三个表末尾的行数。

 Sub CopyToForm() Dim wbSource As Workbook, wbForm As Workbook Dim wsSource As Worksheet, wsForm As Worksheet Dim formpath As String, foldertosavepath As String Dim EndOne As Long, EndTwo As Long, EndThree As Long, i As Integer Dim strProcessingFormPath As String 'Dim strCancel As String 'Dim strFilt As String 'Dim intFilterIndex As Integer 'Dim strDialogueFileTitle As String Dim SecondTable As String Dim ThirdTable As String Set wbSource = ThisWorkbook '~~> Write your code in Indication Tool.xls Set wsSource = wbSource.Sheets("Indication Tool") '~~> Put the source sheet name With wsSource '~~> Counts how many rows are in the Indication Tool EndOne = .Range("B" & .Rows.Count).End(xlUp).Row If EndOne < 17 Then MsgBox "No data for transfer": Exit Sub For i = 17 To EndOne Set wbForm = Workbooks.Open(formpath) '~~> open the form Set wsForm = wbForm.Sheets("Processing Form") '~~> Declare which worksheet to activate '~~> Proceed with the copying / pasting of values .Range("B" & i).Copy wsForm.Range("F7:K7") .Range("C" & i).Copy: wsForm.Range("D8").PasteSpecial xlPasteValues .Range("C" & i).Copy: wsForm.Range("D30").PasteSpecial xlPasteValues .Range("D" & i).Copy: wsForm.Range("H29").PasteSpecial xlPasteValues .Range("E" & i).Copy: wsForm.Range("E29").PasteSpecial xlPasteValues .Range("F" & i).Copy: wsForm.Range("D33").PasteSpecial xlPasteValues .Range("G" & i).Copy: wsForm.Range("K30").PasteSpecial xlPasteValues .Range("H" & i).Copy: wsForm.Range("P33").PasteSpecial xlPasteValues .Range("L" & i).Copy: wsForm.Range("H32").PasteSpecial xlPasteValues .Range("R" & i).Copy: wsForm.Range("D87").PasteSpecial xlPasteValues '.Range("C5:M5").Copy: wsForm.Range("E102").PasteSpecial xlPasteValues '~~> Save the form using the value in cell i,B wbForm.SaveAs .Range("B" & i).Value & ".xls" wbForm.Close Set wbForm = Nothing Set wsForm = Nothing Next End With With wsSource SecondTable = .Range("B:B").Find("SecondTable").Row EndTwo = .Range("B" & .Rows.Count).End(xlUp).Row For i = Second Table + 1 To EndTwo Set wbForm = Workbooks.Open(formpath) '~~> open the form Set wsForm = wbForm.Sheets("Processing Form") '~~> Declare which worksheet to activate '~~> Proceed with the copying / pasting of values .Range("B" & i).Copy wsForm.Range("F7:K7") .Range("C" & i).Copy: wsForm.Range("D8").PasteSpecial xlPasteValues .Range("C" & i).Copy: wsForm.Range("D30").PasteSpecial xlPasteValues .Range("D" & i).Copy: wsForm.Range("H29").PasteSpecial xlPasteValues .Range("E" & i).Copy: wsForm.Range("E29").PasteSpecial xlPasteValues .Range("F" & i).Copy: wsForm.Range("D33").PasteSpecial xlPasteValues .Range("G" & i).Copy: wsForm.Range("K30").PasteSpecial xlPasteValues .Range("H" & i).Copy: wsForm.Range("P33").PasteSpecial xlPasteValues .Range("L" & i).Copy: wsForm.Range("H32").PasteSpecial xlPasteValues .Range("R" & i).Copy: wsForm.Range("D87").PasteSpecial xlPasteValues .Range("C5:M5").Copy: wsForm.Range("E102").PasteSpecial xlPasteValues '~~> Save the form using the cells i,B wbForm.SaveAs .Range("B" & i).Value & ".xls" wbForm.Close Set wbForm = Nothing Set wsForm = Nothing Next End With End Sub 

我在.Find的正确轨道和每个表的单独的复制/粘贴循环? 我意识到这是一个复杂的问题,我很感激你花时间帮助我。

我在.Find的正确轨道和每个表的单独的复制/粘贴循环?

不完全是。 这些循环内的代码基本上是相同的,所以它是子程序的一个很好的候选者。 这将使你的代码更易于阅读,而且更容易维护,因为只有一个地方可以修改,而不是多个(想象一下,如果你需要做10次不同的迭代,或者1000次 – 你不会可能会写1000个不同的循环来做同样的事情!!)

考虑这个,而不是(我观察到一些明显的错误,我会纠正,但这没有经过testing)。 我所做的是把你的几个循环,并巩固到一个单一的子程序。 然后我们发送一些信息,比如表的起始位置和结束位置等信息到子程序中:

 Sub CopyStuff(ws as Worksheet, tblStart as Long, tblEnd as Long) 

我们将发送它: wsSource ,其他variables将被用来/重新使用来确定每个表的开始/结束。 我删除了冗余variables(除非他们需要在其他地方重复使用,有两个variablesEndOneEndTwo是不必要的:我们可以使用更通用的variables,如tblStarttblEnd ,我们可以为后续表重新分配。

通过这种方式,我们正在以相同的方式处理多个表格。 如果代码将来需要更改,我们也只有一个For i = ...循环来pipe理。 所以理解起来比较容易,维护也比较容易。

 Sub CopyToForm() Dim wbSource As Workbook 'No longer needed in this context: wbForm As Workbook Dim wsSource As Worksheet 'No longer needed in this context: wsForm As Worksheet Dim formpath As String, foldertosavepath As String Dim tblEnd As Long, tblStart As Long, i As Integer Dim strProcessingFormPath As String Dim tblStart as Integer: tblStart = 16 Set wbSource = ThisWorkbook '~~> Write your code in Indication Tool.xls Set wsSource = wbSource.Sheets("Indication Tool") '~~> Put the source sheet name With wsSource '~~> Counts how many rows are in the Indication Tool tblEnd = .Range("B" & .Rows.Count).End(xlUp).Row If tblEnd < 17 Then GoTo EarlyExit '## I like to use only one exit point from my subroutines/functions CopyStuff wsSource, tblStart, tblEnd tblStart = .Range("B:B").Find("SecondTable").Row + 1 tblEnd = .Range("B" & .Rows.Count).End(xlUp).Row CopyStuff wsSource, tblStart, tblEnd 'And presumably... tblStart = .Range("B:B").Find("ThirdTable").Row + 1 tblEnd = .Range("B" & .Rows.Count).End(xlUp).Row CopyStuff wsSource, tblStart, tblEnd End With Exit Sub EarlyExit: MsgBox "No data for transfer" End Sub Private Sub CopyStuff(ws As Worksheet, tblStart as Long, tblEnd as Long) Dim wbForm as Workbook, wsForm as Worksheet, i As Long With ws For i = tblStart to tblEnd Set wbForm = Workbooks.Open(formpath) '~~> open the form Set wsForm = wbForm.Sheets("Processing Form") '~~> Declare which worksheet to activate '~~> Proceed with the copying / pasting of values .Range("B" & i).Copy wsForm.Range("F7:K7") .Range("C" & i).Copy: wsForm.Range("D8").PasteSpecial xlPasteValues .Range("C" & i).Copy: wsForm.Range("D30").PasteSpecial xlPasteValues .Range("D" & i).Copy: wsForm.Range("H29").PasteSpecial xlPasteValues .Range("E" & i).Copy: wsForm.Range("E29").PasteSpecial xlPasteValues .Range("F" & i).Copy: wsForm.Range("D33").PasteSpecial xlPasteValues .Range("G" & i).Copy: wsForm.Range("K30").PasteSpecial xlPasteValues .Range("H" & i).Copy: wsForm.Range("P33").PasteSpecial xlPasteValues .Range("L" & i).Copy: wsForm.Range("H32").PasteSpecial xlPasteValues .Range("R" & i).Copy: wsForm.Range("D87").PasteSpecial xlPasteValues '.Range("C5:M5").Copy: wsForm.Range("E102").PasteSpecial xlPasteValues '~~> Save the form using the value in cell i,B wbForm.SaveAs .Range("B" & i).Value & ".xls" wbForm.Close Set wbForm = Nothing Set wsForm = Nothing Next End With End Sub