我发现这个有同样的问题。我注意到问题出在格式化的工作表中。
我取出格式化的,现在它可以工作,除了当到期日期很远并且无需执行任何操作时,它只会弹出"测试文本",而没有名称和日期。
如果到期日期接近"40"范围,它会给出正确的消息,其中包含"测试文本"以及名称和日期。
Sub popup()
Dim lstRow As Long
Dim i As Long
Dim msg As String
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("sheet1") ' rename as required
With ws
msg = "test text " & vbCrLf & vbCrLf
lstRow = .Cells(.Rows.Count, "S").End(xlUp).Row
For i = 2 To lstRow
If .Range("S" & i) - (Date) <= 40 Then
msg = msg & .Range("B" & i).value & " in " & .Range("S" & i).value - Date & " days" & vbCrLf
End If
Next i
End With
MsgBox msg
'Call settimer
End Sub
日期被视为数字,1 表示 1899 年 12 月 31 日之后的每一天。如果您只是在计算天数,您实际上不需要使用 DateDiff
;您可以简单地从日期中减去有问题的日期以获得天数。
您声明您的"到期日期"在 C 列中,但您在代码中使用了 S 列。我猜这与它有关。VBA有一个IsDate
,可以很好地猜测值是否是日期。
如果该代码使用Integer
来管理行号,则该代码非常旧。最好使这些长整数覆盖XLSX的1,048,576行(即使您现在没有全部使用它们)。
Private Sub Workbook_Open()
Dim LRow As Long
Dim LName As String
Dim LResponse As String
Dim LDiff As Long
Dim LDays As Long
LRow = 2 'start at row 2
LDays = 50 'Warning - Number of days to check for expiration
With Sheets("Sheet1")
'Check the first 37 rows in column C
While LRow < 37
'Only check for expired certificate if value in column S is not blank
If IsDate(.Range("C" & LRow)) Then
LDiff = .Range("C" & LRow).Value2 - Date
If (LDiff > 0) And (LDiff <= LDays) Then
'Get names
LName = .Range("B" & LRow).Value
LResponse = LResponse & LName & " will expire in " & LDiff & " days." & Chr(10)
End If
End If
LRow = LRow + 1
Wend
If CBool(Len(LResponse)) Then _
MsgBox "These insurance certificate(s) are nearing expiration:" & Chr(10) & LResponse, vbCritical, "Warning"
End With
End Sub
我通过一些示例数据运行了 C 列中的日期,它似乎在接近到期日期时正确报告了 B 列中的名称。