如何在通过用户窗体保存之前检测重复的管道分隔日期元素,因为它们已经存在于 Excel 表格中?

How to detect pipe-separated date elements that are duplicates before saving them via a Userform because they already exist in an Excel table?

提问人:Dilan Vargas 提问时间:10/3/2023 最后编辑:Tim WilliamsDilan Vargas 更新时间:10/3/2023 访问量:80

问:

我有一个用户表单,它捕获多个日期,格式化为保存在表格中的一行中,如下所示:

存储的日期
|9月10日||9月11日||9月12日||9月14日||9月17日|
|9月19日||9月23日||9月27日|
|9月12日||9月30日|

当用户点击“保存”按钮时,用户窗体将存储用户提交的以下数据: 我需要的是,当用户保存日期时,它首先检测表中是否已经存在一个(或多个)日期。如果是这样,新记录应保存在列表“存储日期”中,但“审阅”消息将出现在名为“注释”的下一列中,无论是在新记录中还是在检测到重复日期的表行中。

我希望根据表中每行的每个日期检查从用户窗体中保存的新记录的每个日期。

输出结果:

存储的日期 评论
|9月10日||9月11日||9月12日||9月14日||9月17日| 回顾
|9月19日||9月23日||9月27日|
|9月12日||9月30日| 回顾

请注意,第 1 行中的日期“|12-sep|”和第 3 行中的“|12-sep|”是重复的。

我尝试过重复检测方法,但没有成功,通过分隔符分隔,然后遍历每个日期,将表中保存的日期与用户输入的日期进行比较。(VBA 字典和数组)

欢迎任何帮助。

Excel VBA 日期 管道 用户窗体

评论


答:

1赞 taller 10/3/2023 #1

Dictionary 对象用于维护日期列表,并将连接的行号作为其对应值。

Option Explicit
Sub Demo()
    Dim objDic As Object, rngData As Range
    Dim i As Long, j As Long, sCmt As String
    Dim arrData, arrRes, sKey, arrKey
    Dim oSht As Worksheet
    Set objDic = CreateObject("scripting.dictionary")
    Set oSht = Sheets("Sheet3") ' Update as needed
    ' Loading table
    Set rngData = oSht.Range("A1").CurrentRegion
    arrData = rngData.Value
    ' Dict key: date string
    ' Dict value: concatenated row numbers
    For i = LBound(arrData) + 1 To UBound(arrData)
        sKey = Mid(arrData(i, 1), 2, Len(arrData(i, 1)) - 2)
        arrKey = Split(sKey, "||")
        For j = LBound(arrKey) To UBound(arrKey)
            sKey = arrKey(j)
            If objDic.exists(sKey) Then
                objDic(sKey) = objDic(sKey) & "," & i
            Else
                objDic(sKey) = i
            End If
        Next j
    Next i
    Dim inputText As String
    inputText = "|12-sep||30-sep|" ' Test 1
'    inputText = "|01-sep||02-sep|" ' Test 2
'    inputText = "|01-sep||27-sep|" ' Test 3
    sCmt = ""
    sKey = Mid(inputText, 2, Len(inputText) - 2)
    arrKey = Split(sKey, "||")
    ' Check the existance of date string
    For j = LBound(arrKey) To UBound(arrKey)
        If objDic.exists(arrKey(j)) Then
            arrRes = Split(objDic(arrKey(j)), ",")
            For i = LBound(arrRes) To UBound(arrRes)
                arrData(arrRes(i), 2) = "Review"
            Next i
            sCmt = "Review"
        End If
    Next
    ' Write upated table
    rngData.Value = arrData
    ' Write new recorde
    With oSht.Cells(oSht.Rows.Count, 1).End(xlUp).Offset(1, 0)
        .Value = inputText
        .Offset(0, 1).Value = sCmt
    End With
    Set objDic = Nothing
End Sub

enter image description here

评论

0赞 Dilan Vargas 10/6/2023
感谢您的帮助,但我收到以下错误:“下标超出范围”,它突出显示的行代码是:arrData(arrRes(i), 2) = “Review”。我不明白为什么会这样
0赞 taller 10/6/2023
您是否使用屏幕截图中显示的数据测试了代码?
0赞 Dilan Vargas 10/6/2023
我再次测试过,现在工作正常(我使用的是另一种数据)。谢谢!