简体   繁体   English

Excel VBA:将行复制到另一张工作表的下一个空白行时出现问题

[英]Excel VBA: Problems copying rows to next blank row of another sheet

I have a spreadsheet where I add a person's details in columns AK See image 我有一个表格,我在列AK增加一个人的详细信息, 请参阅图像

I am trying to use VBA to run code everytime row L has "Yes" in it, and then look for any "Yes"'s in columns MT and copy the entire row from the current sheet "New Refs" to the corresponding tab (eg. if "Yes" in column M, copy the row to the "ASD 5P" tab). 我试图使用VBA在行L中每次包含“是”的情况下运行代码,然后在MT列中查找任何“是”,并将整行从当前工作表“ New Refs”复制到相应的标签(例如,如果M列中为“是”,则将该行复制到“ ASD 5P”标签中。

I have the following code, but it keeps overwriting rows that are already there. 我有以下代码,但它会覆盖已存在的行。 I need it to look for the next blank row in the corresponding tab, and paste it to that, without overwriting or deleting the other rows that are already there. 我需要它在相应选项卡中查找下一个空白行,并将其粘贴到该行,而不会覆盖或删除已经存在的其他行。 Here is the code I am using currently... 这是我当前正在使用的代码...

Sub Worksheet_Change(ByVal Target As Range)
  Dim KeyCells As Range

  ' The variable KeyCells contains the cells that will
  ' cause an alert when they are changed.
  Set KeyCells = Range("K:S")

  If Not Application.Intersect(KeyCells, Range(Target.Address)) _
       Is Nothing Then

  Application.ScreenUpdating = False
  Dim lastrow As Long
  lastrow = Sheets("New Refs").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
  Dim x As Long
  x = 4
  Dim rng As Range
  For Each rng In Sheets("New Refs").Range("M4:M" & lastrow)
      If rng.Value2 = "Yes" And Trim(Cells(rng.Row, "K")) <> vbNullString And Trim(Cells(rng.Row, "L")) = "Yes" Then
          rng.EntireRow.Copy Sheets("ASD 5P").Cells(x, 1)
          x = x + 1
      End If
  Next rng
  Application.ScreenUpdating = True


  Application.ScreenUpdating = False
  lastrow = Sheets("New Refs").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
  x = 4
  For Each rng In Sheets("New Refs").Range("N4:N" & lastrow)
      If rng.Value2 = "Yes" And Trim(Cells(rng.Row, "K")) <> vbNullString And Trim(Cells(rng.Row, "L")) = "Yes" Then
          rng.EntireRow.Copy Sheets("ASD PD").Cells(x, 1)
          x = x + 1
      End If
  Next rng
  Application.ScreenUpdating = True

  Application.ScreenUpdating = False
  lastrow = Sheets("New Refs").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
  x = 4
  For Each rng In Sheets("New Refs").Range("O4:O" & lastrow)
      If rng.Value2 = "Yes" And Trim(Cells(rng.Row, "K")) <> vbNullString And Trim(Cells(rng.Row, "L")) = "Yes" Then
          rng.EntireRow.Copy Sheets("IY Group").Cells(x, 1)
          x = x + 1
      End If
  Next rng
  Application.ScreenUpdating = True

  Application.ScreenUpdating = False
  lastrow = Sheets("New Refs").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
  x = 4
  For Each rng In Sheets("New Refs").Range("P4:P" & lastrow)
      If rng.Value2 = "Yes" And Trim(Cells(rng.Row, "K")) <> vbNullString And Trim(Cells(rng.Row, "L")) = "Yes" Then
          rng.EntireRow.Copy Sheets("Dina").Cells(x, 1)
          x = x + 1
      End If
  Next rng
  Application.ScreenUpdating = True

  Application.ScreenUpdating = False
  lastrow = Sheets("New Refs").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
  x = 4
  For Each rng In Sheets("New Refs").Range("Q4:Q" & lastrow)
      If rng.Value2 = "Yes" And Trim(Cells(rng.Row, "K")) <> vbNullString And Trim(Cells(rng.Row, "L")) = "Yes" Then
          rng.EntireRow.Copy Sheets("Indiv. Par.").Cells(x, 1)
          x = x + 1
      End If
 Next rng
  Application.ScreenUpdating = True   

  Application.ScreenUpdating = False
  lastrow = Sheets("New Refs").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
  x = 4
  For Each rng In Sheets("New Refs").Range("R4:R" & lastrow)
      If rng.Value2 = "Yes" And Trim(Cells(rng.Row, "K")) <> vbNullString And Trim(Cells(rng.Row, "L")) = "Yes" Then
          rng.EntireRow.Copy Sheets("ASD Psy. Ed.").Cells(x, 1)
          x = x + 1
      End If
  Next rng
  Application.ScreenUpdating = True

  Application.ScreenUpdating = False
  lastrow = Sheets("New Refs").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
  x = 4
  For Each rng In Sheets("New Refs").Range("S4:S" & lastrow)
      If rng.Value2 = "Yes" And Trim(Cells(rng.Row, "K")) <> vbNullString And Trim(Cells(rng.Row, "L")) = "Yes" Then
          rng.EntireRow.Copy Sheets("ADHD Psy. Ed.").Cells(x, 1)
          x = x + 1
      End If
  Next rng
  Application.ScreenUpdating = True   
  End If
End Sub

Please advise? 请指教?

UPDATE My header rows look like this 更新我的标题行看起来像这样

Had to get some things finished at work but.. there are different ways you can approach this, below is one: 必须完成一些工作,但是..您可以通过多种方法来实现,以下是一种:

Following are the assumption I made: 以下是我所做的假设:

  • Trigger column will be Column L in your sheet 触发列将是工作表中的Column L
  • You only want to copy from Column A to Column K 您只想从Column A Column K复制到Column K
  • To check if row already exists in the sheets where row is copied, I am using RIO ( Column C ) as a unique identifier 为了检查复制行的工作表中是否已经存在行,我使用RIO( Column C )作为唯一标识符

In your Worksheet_Change sub make the call to CopyCurrentRowToSheets sub as per screenshot below (NOTE: I used Sheet8 when developing this code): 在您的Worksheet_Change子句中,按照下面的屏幕快照调用CopyCurrentRowToSheets子句(注意:开发此代码时,我使用Sheet8 ): 在此处输入图片说明

Add reference to Microsoft Scripting Runtime by: In your VBA editor, select the Tools menu. 通过以下方式添加对Microsoft Scripting Runtime的引用:在VBA编辑器中,选择“ 工具”菜单。 Then select References... option. 然后选择引用...选项。 This will open References window (screen print below). 这将打开“ 引用”窗口(下面的屏幕打印)。 Scroll down and select Microsoft Scripting Runtime from the list and press OK button 向下滚动并从列表中选择Microsoft脚本运行时 ,然后按OK按钮 在此处输入图片说明

Then in a module, add the following sub: 然后在一个模块中,添加以下子项:

Sub CopyCurrentRowToSheets(ByVal oTarget As Range)
    Dim oW As Worksheet: Set oW = ThisWorkbook.Worksheets("Sheet8")     ' Change the sheet name
    Dim oWS As Worksheet
    Dim dSTU As New Scripting.Dictionary     ' Requires reference to Microsoft Scripting Runtime
    Dim oRange As Range
    Dim iLR As Long

    ' Capture sheets to update
    For Each oRange In oW.Range("M" & oTarget.Row & ":" & Chr(oW.Cells(1, oW.Columns.count).End(xlToLeft).Column + 64) & oTarget.Row)
        dSTU.Add Cells(1, oRange.Column).Value, oRange.Value
    Next

    ' Check if we need to update the sheets by checking the value in column L
    If Trim(LCase(oTarget.Value)) = "yes" Then

        ' Loop to go through all sheets in current workbook
        For Each oWS In ThisWorkbook.Worksheets

            ' Check if current sheet is one of the sheet that need updating
            If dSTU.Exists(oWS.Name) Then

                ' Check if current sheet should be updated
                If Trim(LCase(dSTU(oWS.Name))) = "yes" Then

                    ' Check if current row already exists in the target sheet
                    If Application.IfNa(Application.Match(oW.Cells(oTarget.Row, 3).Value, oWS.Columns(3), 0), "") = "" Then
                        iLR = oWS.Range("A" & oWS.Rows.count).End(xlUp).Row + 1
                        oW.Range("A" & oTarget.Row & ":K" & oTarget.Row).Copy oWS.Range("A" & iLR & ":K" & iLR)
                    End If

                End If
            End If

        Next

    End If

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM