VBA 根据第三列中存在的条件连接两列中的单元格

VBA Concatenate Cells from two columns based on criteria present in a third

我目前正在尝试根据第三列中存在的另一组数据合并来自两个不同列的两组数据。

在这种情况下,我需要将 G 列(三个字母代码的字符串)中的基本国家/地区标签连接到 H 列中提供字符串 "Missing Audio" 或 "Missing Audio/Subs" 的字符串的前面出现在列 F

我当前的固定变量是所有数据都将从其各个列的第六行开始,但是它们将 运行 一个未确定的点。

我尝试了各种代码,我很乐意 post,但其中 none 似乎有效,我开始觉得我已经我脑子里的过程太复杂了,它创建了一种编码块形式!提供的任何帮助将不胜感激

As Asked here is my attempt, try to pull in a basic Concatenate script with the variable requirements:

回复
Sub Notestidy()

Dim w1 As Worksheet
Dim c As Range, AC As String
Dim rng As Range, rng2 As Range, iRow As Integer, iCol As Integer, i As Integer

Application.ScreenUpdating = False
Set w1 = Worksheets("Sheet1")
Set rng = w1.Range("G6", w1.Range("G" & Rows.Count).End(X1up))
Set rng2 = w1.Range("H6", w1.Range("H" & Rows.Count).End(X1up))

For Each c In w1.Range("F6", w1.Range("F" & Rows.Count).End(xlUp))
  AC = .String("Missing Audio", "Missing Audio/Subs")
  On Error Resume Next
  If c = Range Then
    Dim varConctnt As Variant
    For iRow = 1 To rng.Rows.Count: rng2.Rows.Count
    For iCol = 1 To rng.Columns.Count: rng2.Columns.Count
    If Not rng(iRow, iCol).Value = vbNullString Then
      varConctnt = varConctnt & ", " & rng(iRow, iCol).Value
    End If
Next iCol
If varConctnt = vbNullString Then MsgBox "Empty Array": GoTo skip1
MsgBox Mid(varConctnt, 2)
varConctnt = ""

skip1:
Next iRow

Application.ScreenUpdating = True

End Sub

新代码尝试:

> Sub Notestidy()
> 
> Dim w1 As Worksheet Dim rng As Range Dim FirstRow As Integer
> 
> 
> 
> Set w1 = Worksheets("Sheet1") FirstRow = 0
> 
> 
> Set rng = w1.Range("F:F").Find(What:="Missing Audio",
> LookIn:=xlValues, _   LookAt:=xlPart, SearchDirection:=xlNext,
> MatchCase:=False) While Not rng Is Nothing   If FirstRow <> rng.Row
> Then
>     If FirstRow = 0 Then
>       FirstRow = rng.Row
>     End If
>     w1.Range("H" & rng.Row) = w1.Range("G" & rng.Row) & w1.Range("H" & rng.Row)
>     rng.FindNext After:=rng   Else
>     Set rng = Nothing   End If Wend
> 
> Application.ScreenUpdating = True
> 
> End Sub

如果我对你的问题的解释是正确的,我想你可能把它想得太复杂了!

Sub Notestidy()    

    Dim cc, sc, nc As String
    Dim ws As Worksheet

    Set ws = Sheet1

    cc = "G"
    sc = "H"
    nc = "F"

    Dim i, max As Integer
    max = ws.UsedRange.Rows.Count

    For i = 2 To max

        If ws.Range(nc & i).Value = "Missing Audio" Or ws.Range(nc & i).Value = "Missing Audio/Subs" Then

            ws.Range(sc & i).Value = ws.Range(cc & i).Value & " " & ws.Range(sc & i).Value

        End If

    Next i

    Set ws = Nothing
End Sub

编辑:或根据 FreeMan 使用 Find 方法的回答:

Sub Notestidy()

    Dim w1 As Worksheet
    Dim result As Range
    Dim FirstRow As Integer

    Set w1 = Worksheets("Sheet1")
    FirstRow = 0

    With w1.Range("F:F")
        Set result = .Find(What:="Missing Audio", LookIn:=xlValues, LookAt:=xlPart)

        If Not result Is Nothing Then
            FirstRow = result.Row
            Do
                w1.Range("H" & result.Row) = w1.Range("G" & result.Row) & w1.Range("H" & result.Row)
                Set result = .FindNext(result)
            Loop While Not result Is Nothing And result.Row <> FirstRow
        End If
    End With

    Set w1 = Nothing
    Set result = Nothing

End Sub

一些帮助您入门的提示:

  • 永远不要使用 Application.ScreenUpdating = False,直到您的代码生效。它只会隐藏正在发生的事情并使找出问题变得更加困难
  • 您想使用 On Error Resume Next 的情况非常罕见且特定,而这不是其中之一。它所做的只是掩盖了 运行 次错误发生的事实。它允许您处理您预期可能发生的特定错误。那不是你想要的。
  • 将工作表和范围分配给变量而不是使用 Active... 非常好!
  • .String 不是有效的方法或对象,当未包含在 With...End With 块中时,前导点表示法无效
  • 在一行中使用 : 组合多个语句是有效的,有些人这样做。我个人的看法是,它使代码更难阅读和精神分析,即使编译器没有问题。当您将一些代码与 : 组合在一行上,然后在该代码块中执行未组合在该行上的其他代码时,尤其如此。
  • 正确且一致的缩进将帮助您确定代码块以及在何处结束已开始的块。
  • 内置函数,例如 .Find() 比循环遍历单元格块查找内容要快得多。

所以...

Sub Notestidy()

Dim w1 As Worksheet
Dim rng As Range
Dim FirstRow as Integer

'Application.ScreenUpdating = False

Set w1 = Worksheets("Sheet1")
FirstRow = 0

'find "Missing Audio" in column F
set rng = w1.Range("F:F").Find (What:="Missing Audio", LookIn:=xlValues, _
  LookAt:=xlPart)              'look at some additional parameters here
While Not rng is Nothing       'if we found it somewhere
  If FirstRow <> rng.row Then  'we haven't wrapped back around to the first found item
    If FirstRow = 0 then       'this is our first time through the loop
      FirstRow = rng.row       'Store off the first found row
    End If
    'Assign H = F & H for this row. 
    w1.Range("H" & rng.row) = w1.Range("F" & rng.row) & w1.Range("H" & rng.row) 
'------------------------
'update this line:
    Set rng = rng.FindNext After:=rng  'find the next occurrence
  Else
    set rng = nothing          'we've wrapped around the search, let's get out
  End If
Wend

Application.ScreenUpdating = True

End Sub

一些最后的笔记:

  • 请注意 .Find() 将使用上次在搜索对话框中设置的任何参数,代码中设置的参数将反映在对话框中。这没有任何问题,您只需要了解,在从代码调用它时 没有 显式设置的任何内容都会让您使用上次搜索中碰巧出现的任何随机设置。您可能需要查看所有参数的 MS Docs on .find()
  • .Find() 的主题上,它会回绕并再次找到第一次出现的地方。如果你不替换你找到的东西,你将陷入无限循环,所以你必须存储某种标记(FirstRow,在这种情况下)所以你知道什么时候得到回到那里。
  • w1.Range("H" & rng.row) = 行中,您可以根据需要在国家代码 (Col F) 和 Col H 中的字符串之间添加某种分隔符。我不知道你可能想要什么,所以我只是把它们撞在一起。
  • 使用 F8 键在调试器中逐步执行代码,一次执行 1 行代码。这将帮助您了解代码中发生的事情。