【问题标题】:Find each row that has matching values in two columns查找在两列中具有匹配值的每一行
【发布时间】:2020-10-03 16:04:51
【问题描述】:

我有一个电子表格,用于管理我们即将更新的政策。有些客户有多个同时到期的政策,每个政策都显示在单独的行中,但我们将它们视为单个事务。

我有一个用户表单来向我们的管理团队提交任务,该用户表单由每行特定单元格中可见的命令按钮调用。然后我使用ActiveCell.Row 预先填写一些表单详细信息。 它有一个复选框来指示任务何时适用于所有策略,还有一个消息框告诉用户有多少策略。 我已经使用此代码来做到这一点

Dim strCount As String
strCount = Application.WorksheetFunction.CountIf(Range("C:C"), TxtClient.Value)

这可以正常工作并返回正确的值,但是我还需要搜索 D:D 列以匹配续订日期,并且只计算与两列都匹配的行。

稍后在我的代码中,我还需要遍历与客户名称和续订日期匹配的所有这些行,并在 A 列中添加一个请求 ID。

我整天都在寻找解决这个问题的方法,结果空手而归。谁能指出我正确的方向?

【问题讨论】:

  • 你不能使用自动筛选吗?
  • 为什么需要计算“匹配两列的行”?如果 C:C 和 D:D 都符合您的条件,则为了在 A:A 列中写入内容,您不需要初步计数。只有在出现更多此类政策时,您才会在 A:A 中记录此记录?

标签: excel vba


【解决方案1】:

如果不需要初步计数,请测试下一个(简单)代码:

Sub testFindMatching()
   Dim sh As Worksheet, lastRow As Long, i As Long
   Dim strCriteria As String

   Set sh = ActiveSheet
   lastRow = sh.Range("C" & Rows.Count).End(xlUp).row
   strCriteria = TxtClient.Value & CStr(DateValue(txtSomethingElse.Value)) 'use here your appropriate source for 'SomethingElse'
   For i = 2 To lastRow
      If sh.Range("C" & i).Value & sh.Range("D" & i).Value = _
                   strCriteria Then sh.Range("A" & i).Value = "RqID" 'Your "request ID" to be filled in A:A
   Next i
End Sub

如果要处理的范围很大,我也可以使用数组发布更快的版本。

事实上,更快的变体在任何情况下都可以很好地工作。我也会放第一个版本,对数组不太熟悉的人很容易理解:

Sub testFindMatching_Arrays()
   Dim sh As Worksheet, lastRow As Long, i As Long
   Dim arr As Variant, arrFin As Variant, strCriteria As String

   Set sh = ActiveSheet
   lastRow = sh.Range("C" & Rows.Count).End(xlUp).row
   arr = sh.Range("C2:D" & lastRow).Value
   ReDim arrFin(1 To UBound(arr, 1), 1 To 1)
   strCriteria = TxtClient.Value & CStr(DateValue(txtSomethingElse.Value)) 'use here your appropriate source for 'SomethingElse'
   For i = 1 To UBound(arr, 1)
      If arr(i, 1) & arr(i, 2) = strCriteria Then
          arrFin(i, 1) = "RqID" 'Your "request ID" to be filled in A:A
      Else
          arrFin(i, 1) = sh.Range("A" & i + 1).Value
      End If
   Next i
   sh.Range("A2:A" & lastRow).Value = arrFin
End Sub

已编辑:将代码调整为也可以使用第二个参数 (As Date)。

【讨论】:

  • 嗨@FaneDuru,谢谢你。我在这里试过你的第一个潜艇。当我在没有第二个标准 (RenDate) 的情况下执行此操作时,它可以完美运行,但它不适用于包含的 RenDate。是因为约会吗?工作表在此列中格式化为日期,我使用 strRnl = Format(DateAdd("d", 0, CDate(TxtRenDate)), "[$-en-UK}]dd-mm-yyyy;@") 将我的用户表单文本框值转换回日期,但在搜索匹配时似乎没有识别它?
  • @NicKitty:两种情况下的日期格式(在工作表上和文本框上)?如果是,它应该可以在没有任何变化的情况下工作。如果不是,我们必须做出一些调整。但是,在此之前,您能否声明第二个参数始终是日期?还是只是有时……?现在我无法打开我的笔记本电脑。大约两个小时后我就能做到,但我需要你就上述问题发表声明……
  • 工作表被明确格式化为日期,我假设将Format(DateAdd) 添加到我的子中也将我的文本框转换为日期格式。但也许事实并非如此?续订日期始终是第二个参数。
  • @NicKitty:日期在表格中的格式并不那么重要。将其放在数组元素中时,VBA将其转换为日期。但是在默认格式下,根据本地化...您可以使用 Debug.print Date 查看默认格式在您的情况下的外观。如果它看起来与您的工作表和文本框中的完全一样,则代码应该可以正常工作。该代码适用于字符串。只能连接字符串。但即使格式(在文本框中)不是默认格式,我也调整了代码以使其正常工作。请刷新页面(这个)并使用最后修改的代码。一些反馈 = 好...
  • 非常感谢您在这方面的帮助。经过一些试验/错误后,我最终使用了您的解决方案的略微修改版本。我认为我遇到的问题是因为我引用了我的用户表单数据(我已经在我的启动子中修改了之前的格式),所以我只是修改了你的代码,以便我的 strCriteria 指回 ActiveCell.Row而是在我的电子表格中,然后它奏效了!这也意味着我不必担心日期格式,因为该列中的所有值都是日期:)
【解决方案2】:

此代码在 A 列和 B 列中创建一个随机的 AB,并比较它们以查看它们是否相同,然后突出显示它们。

For Each cel In Range("a1:a15")
  cel.Value = Chr(65 + Int(Rnd * 2))
  cel.Offset(0, 1) = Chr(65 + Int(Rnd * 2))
    If cel = cel.Offset(0, 1) Then
      cel.Interior.Color = RGB(220, 210, 210)
      cel.Offset(0, 1).Interior.Color = RGB(220, 210, 210)
    End If
Next cel

【讨论】:

    【解决方案3】:

    我希望我能理解这个任务。请找到以下解决方案。我希望您可以根据您的最终目标对其进行修改。我还在下一个 sub 中包含了一个如何调用它的示例。请让我知道它是否适合您。谢谢。

    Sub SelectPolicies(TxtClient As String, dPolicyDate As Date)
        'The following three ranges are covering the part of C and D columns filled with data and the whole A column
        Dim rngClientNames As Range
        Dim rngPolicyDates As Range
        Dim rngOutputID As Range
        With ThisWorkbook.Sheets("Policies")
            Set rngClientNames = .Range("C1:C" & .Range("C" & .Rows.Count).End(xlUp).Row)
            Set rngPolicyDates = .Range("D1:D" & .Range("D" & .Rows.Count).End(xlUp).Row)
            Set rngOutputID = .Range("A:A")
        End With
        Dim i As Long
        For i = 1 To rngClientNames.Rows.Count 'Looping throug all the rows
    
            If rngClientNames(i).Value = TxtClient And rngPolicyDates(i).Value = dPolicyDate Then
                'If the client and the policy date (renewal) is matching write the client into A column
                rngOutputID(i).Value = TxtClient
            Else
                'if not matching, empty the relevant row in A column
                rngOutputID(i).Value = ""
            End If
        Next i
    End Sub
    
    Sub Test()
        'Call the sub with the actual TxtClient and renewal Date.
        'In the test these are in the K1 and L1 cells
        Call SelectPolicies(Range("K1").Value, Range("L1").Value)
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2019-01-19
      • 2018-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      相关资源
      最近更新 更多