简体   繁体   English

VBA 如果单元格与 ID 列表匹配,则复制并粘贴整行,但如果列表包含空白单元格或带有“”的单元格,则不要粘贴

[英]VBA Copy and paste entire row if cell matches list of IDs, but do not paste if list contains blank cell or cell with ""

I have what I thought would be a simple script, but I have some some strange results.我有一个我认为会很简单的脚本,但我有一些奇怪的结果。

Goal: Identify specific IDs in a SOURCE sheet using a list of IDs on a Translator Sheet.目标:使用翻译表上的 ID 列表识别SOURCE表中的特定 ID。 When found, copy the entire row to and OUTPUT sheet.找到后,将整行复制到OUTPUT 工作表。

The output has strange results that I can't figure out. output 有我无法弄清楚的奇怪结果。

  • Returns all results instead of the limited list.返回所有结果而不是有限列表。 AND results are in weird groupings. AND 结果是奇怪的分组。 (First result is on row 21 and only has 9 rows of data, the next group has 90 rows of data, starting on row 210, then blank rows, then 900 rows of data, etc. (第一个结果在第 21 行,只有 9 行数据,下一组有 90 行数据,从第 210 行开始,然后是空白行,然后是 900 行数据,等等。
  • Results do not start in row 2.结果不从第 2 行开始。

Full code is below attempts:完整代码如下:

Attempts:尝试:

  1. I first searched the SOURCE sheet based on one ID that was hard coded as a simple test and it worked.我首先根据一个硬编码为简单测试的 ID 搜索了SOURCE工作表并且它起作用了。 but when I changed the code to search a range (z21:z), two things happened: 1, it returns everything in the Source file in multiples of 9 as stated above, AND as you can imagine, the time to complete skyrocketed from seconds to minutes.但是当我更改代码以搜索范围 (z21:z) 时,发生了两件事:1,如上所述,它以 9 的倍数返回源文件中的所有内容,并且正如您可以想象的那样,完成时间从几秒开始猛增分钟。 I think I missed a add'l section of code to identify the range??我想我错过了一段代码来识别范围?

Old Code:旧代码:

For K = 1 To xRg.Count
If CStr(xRg(K).Value) = Worksheets("D62D627EB404207DE053D71C880A3E05") Then
xRg(K).EntireRow.Copy Destination:=Worksheets("Output").Range("A2" & J + 1)
J = J + 1
End If

New code:新代码:

For K = 1 To xRg.Count
If CStr(xRg(K).Value) = Worksheets("Translator").Range("z21:z" & I)** Then
xRg(K).EntireRow.Copy Destination:=Worksheets("Output").Range("A2" & J + 1)
J = J + 1
End If
  • 1a. 1a. I believe one issue is that the Translator list has duplicates.我认为一个问题是翻译列表有重复项。 Second, it is searching the entire column Z. Second issue may be that The list in Translator is generated via a formula in column Z, thus if the formula is false, it will insert a "" into the cell.其次,它正在搜索整个 Z 列。第二个问题可能是Translator中的列表是通过 Z 列中的公式生成的,因此如果公式为假,它将在单元格中插入一个“”。 I seek the code to NOT paste those rows where the cell content is either a "" or is a true blank cell.我寻找代码以不粘贴单元格内容是“”或真正空白单元格的那些行。 Reason: The "" will cause issues when we try to load the Output file into a downstream system because it is not a true blank cell.原因:当我们尝试将 Output 文件加载到下游系统时,“”会导致问题,因为它不是真正的空白单元格。
  1. Results in wrong location: When the script is complete, my first result does not start on Row 2 as expected.结果位置错误:脚本完成后,我的第一个结果没有按预期从第 2 行开始。 I thought the clear contents would fix this, but maybe a different clear function is required?我认为清晰的内容可以解决这个问题,但也许需要一个不同的清晰的 function? or the clear function is in the wrong place?或者清除 function 在错误的地方? Below screenshot shows how it should show up.下面的屏幕截图显示了它应该如何显示。 It is in the same columns but doesn't start until row 21. enter image description here它在同一列中,但直到第 21 行才开始。在此处输入图像描述

  2. Slow code: I have a command that copies and pastes of the first row from SOURCE to OUTPUT .慢代码:我有一个命令将第一行从SOURCE复制并粘贴到OUTPUT My code is cumbersome.我的代码很麻烦。 There has to be an easier way.必须有更简单的方法。 I am doing this copy and paste just in case the source file adds new columns in the future.我正在执行此复制和粘贴操作,以防源文件将来添加新列。

 Worksheets("Output").Cells.ClearContents Sheets("SOURCE").Select Rows("1:1").Select Selection.Copy Sheets("Output").Select Rows("1:1").Select ActiveSheet.Paste

Thank you for all your help.谢谢你的帮助。

Option Explicit
Sub MoveRowBasedOnCellValuefromlist()
'Updated by xxx 2023.01.18
Dim xRg As Range
Dim xCell As Range
Dim I As Long
Dim J As Long
Dim K As Long
I = Worksheets("SOURCE").UsedRange.Rows.Count
J = Worksheets("Output").UsedRange.Rows.Count
If J = 1 Then
If Application.WorksheetFunction.CountA(Worksheets("Output").UsedRange) = 0 Then J = 0
End If   
Worksheets("Output").Cells.ClearContents
Sheets("SOURCE").Select
Rows("1:1").Select
 Selection.Copy
Sheets("Output").Select
Rows("1:1").Select
 ActiveSheet.Paste
 Set xRg = Worksheets("SOURCE").Range("B2:B" & I)
On Error Resume Next
 Application.ScreenUpdating = False
'NOTE - There are duplicates in the Translator list. I only want it to paste the first instance.
'Otherwise, I need to create an =Unique() formula and that seems like unnecessary work.
 For K = 1 To xRg.Count
 If CStr(xRg(K).Value) = Worksheets("Translator").Range("z21:z" & I) Then
xRg(K).EntireRow.Copy Destination:=Worksheets("Output").Range("A2" & J + 1)
  J = J + 1
 End If
 Next
Application.ScreenUpdating = True
End Sub

Try this out - using Match as a fast way to check if a value is contained in your lookup list.试试这个 - 使用 Match 作为检查查找列表中是否包含值的快速方法。

Sub MoveRowBasedOnCellValuefromlist()
    Dim c As Range, wsSrc As Worksheet, wsOut As Worksheet, wb As Workbook
    Dim cDest As Range, wsTrans As Worksheet, rngList As Range
   
    Set wb = ThisWorkbook 'for example
    Set wsSrc = wb.Worksheets("SOURCE")
    Set wsOut = wb.Worksheets("Output")
    
    Set wsTrans = wb.Worksheets("Translator")
    Set rngList = wsTrans.Range("Z21:Z" & wsTrans.Cells(Rows.Count, "Z").End(xlUp).Row)
    
    ClearSheet wsOut
    wsSrc.Rows(1).Copy wsOut.Rows(1)
    Set cDest = wsOut.Range("A2")  'first paste destination
    
    Application.ScreenUpdating = False
    For Each c In wsSrc.Range("B2:B" & wsSrc.Cells(Rows.Count, "B").End(xlUp).Row).Cells
        If Not IsError(Application.Match(c.Value, rngList, 0)) Then 'any match in lookup list?
            c.EntireRow.Copy cDest
            Set cDest = cDest.Offset(1) 'next paste row
        End If
    Next c
    Application.ScreenUpdating = True
End Sub

'clear a worksheet
Sub ClearSheet(ws As Worksheet)
    With ws.Cells
        .ClearContents
        .ClearFormats
    End With
End Sub

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

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