【发布时间】:2018-09-24 14:17:54
【问题描述】:
如果没有任何内容已过期、即将过期并且只要 1、2 和 19 中有数据,我需要显示一个 msgbox。目前它会为符合上述条件的任何人显示它,但只有在每个单行符合上述要求。然后它应该拒绝其他 msgboxes 出现。
请查看下面的所有代码。
Sub Expire_New()
Dim arr() As Variant
Dim msg(1 To 4) As String
Dim x As Long
Dim dDiff As Long
With ActiveSheet
x = .Cells(.Rows.Count, 19).End(xlUp).Row
arr = .Cells(21, 1).Resize(x - 20, 26).Value
End With
For x = LBound(arr, 1) To UBound(arr, 1)
If Len(arr(x, 19)) * Len(arr(x, 1)) * Len(arr(x, 2)) Then
dDiff = DateDiff("d", Date, arr(x, 19))
Select Case dDiff
Case Is <= 0: msg(1) = Expired(msg(1), arr(x, 1), arr(x, 2), arr(x, 19))
Case Is <= 31: msg(2) = Expiring(msg(2), arr(x, 1), arr(x, 2), arr(x, 19), dDiff)
End Select
End If
If Len(arr(x, 19)) = 0 And Len(arr(x, 1)) > 0 And Len(arr(x, 2)) > 0 Then
msg(3) = NoTraining(msg(3), arr(x, 1), arr(x, 2), arr(x, 18))
End If
If Len(arr(x, 19)) > 0 And Len(arr(x, 1)) > 0 And Len(arr(x, 2)) > 0 Then
dDiff = DateDiff("d", Date, arr(x, 19))
Select Case dDiff
Case Is > 31: msg(4) = MsgBox("There are either no expired safeguarding certificates, or no certificate expiring within the next 31 days.", vbCritical, "Warning")
End Select
End If
Next x
For x = LBound(msg) To UBound(msg)
msg(x) = Replace(msg(x), "@NL", vbCrLf)
If Len(msg(x)) < 1024 Then
MsgBox msg(x), vbExclamation, "Safeguarding Certificate Notification"
Else
MsgBox "String length for notification too long to fit into this MessageBox", vbExclamation, "Invalid String Length to Display"
End If
Next x
Erase arr
Erase msg
End Sub
Private Function Expired(ByRef msg As String, ByRef var1 As Variant, ByRef var2 As Variant, ByRef var3 As Variant) As String
If Len(msg) = 0 Then msg = "Persons with EXPIRED Safeguading Certificates@NL@NL"
Expired = msg & "(@var3) @var1 @var2@NL"
Expired = Replace(Expired, "@var1", var1)
Expired = Replace(Expired, "@var2", var2)
Expired = Replace(Expired, "@var3", var3)
End Function
Private Function Expiring(ByRef msg As String, ByRef var1 As Variant, ByRef var2 As Variant, ByRef var3 As Variant, ByRef d As Long) As String
If Len(msg) = 0 Then msg = "Persons with EXPIRING Safeguarding Certificates@NL@NL"
Expiring = msg & "(@var3) @var1 @var2 (@d days remaining)@NL"
Expiring = Replace(Expiring, "@var1", var1)
Expiring = Replace(Expiring, "@var2", var2)
Expiring = Replace(Expiring, "@var3", var3)
Expiring = Replace(Expiring, "@d", d)
End Function
Private Function NoTraining(ByRef msg As String, ByRef var1 As Variant, ByRef var2 As Variant, ByRef var3 As Variant) As String
If Len(msg) = 0 Then msg = "SAFEGUARDING TRAINING NOT COMPLETED FOR @NL@NL"
NoTraining = msg & " @var1 @var2@NL"
NoTraining = Replace(NoTraining, "@var1", var1)
NoTraining = Replace(NoTraining, "@var2", var2)
NoTraining = Replace(NoTraining, "@var3", var3)
End Function
我认为这是导致问题的以下部分。我不认为这应该在主数组中?
If Len(arr(x, 19)) > 0 And Len(arr(x, 1)) > 0 And Len(arr(x, 2)) > 0 Then
dDiff = DateDiff("d", Date, arr(x, 19))
Select Case dDiff
Case Is > 31: msg(4) = MsgBox("There are either no expired safeguarding certificates, or no certificate expiring within the next 31 days.", vbCritical, "Warning")
End Select
End If
所以我实际上想要的“msg(4)”是我希望只有在 msg(1)、msg(2) 和 msg(3) 的标准不匹配时才会出现。如果 msg(4) 出现,那么其他 3 个 msg 不应该出现。 msg1 查找列出的日期早于当前日期的任何行/单元格。 msg2 查找当前日期在所列日期的 31 天内的行/单元格。 msg3 查找没有列出日期但在第 1 列或第 2 列中有名称的行/单元格。因此,如果列出的日期(在第 19 列的单元格中)超过 31 天,并且在 1 中有名称和 2,那么 msg4 应该出现,而不是 1、2 或 3。1 和 2 包含名称,19 包含日期。
代码在此处的第 3 页上:https://www.dropbox.com/s/9m1hx2tylv1k470/SCR%20as%20of%2017%2009%2018%20-%20Copy%20-%20Copy.xlsm?dl=0
【问题讨论】:
-
问题描述并不像您想象的那么清晰。请阅读minimal reproducible example。您是否尝试过设置断点 (F9) 并单步执行代码 (F8) 并检查 locals 工具窗口中的值以查看哪里出错了?
-
我认为这主要取决于代码的位置(也许这个位的编码也是错误的。我认为由于代码的位置,它是作为数组的一部分这样做的对与 IF 语句匹配的任何行/单元格也是如此。我需要它只在每一行都符合上述条件时才这样做(而不是 msg(1)、msg(2) 或 msg(3 中的任何一个) ) 部分),因此它不应该继续使用 msg(1)、msg(2) 或 msg(3)。这是更好的解释吗?
-
一方面,
msg(4) = MsgBox(...)表示您将MsgBox调用的结果存储到msg数组的下标 4 中,该结果将是 @987654329 的整数表示@, ...这很可能是无用的,而且根本不是你想要的,而且我不知道该代码应该做什么,也不知道你想要做什么。您需要缩小范围以解决更具体的问题。 -
所以我实际上想要的“msg(4)”是我希望只有当 msg(1)、msg(2) 和 msg(3) 的标准不满足时才会出现匹配。如果 msg(4) 出现,那么其他 3 个 msg 不应该出现。 msg1 查找列出的日期早于当前日期的任何行/单元格。 msg2 查找当前日期在所列日期的 31 天内的行/单元格。 msg3 查找没有列出日期但在第 1 列或第 2 列中有名称的行/单元格。因此,如果列出的日期(在第 19 列的单元格中)超过 31 天,并且在 1 中有名称和 2,那么 msg4 应该出现而不是 1、2 或 3。
-
您可以(并且应该)使用问题下方的edit 链接添加相关信息并删除无用的部分。从 cmets 中提取重要信息非常困难。