VBA验证 - 一个单元格上的多个日期验证

时间:2015-11-13 20:41:15

标签: vba validation excel-vba excel

我正在尝试验证在单元格中输入的日期,但我遇到了问题。场景是我有一个命名范围的单元格(列标题),它在日历视图中保存日期。然后用户输入开始和结束日期,我想验证: 1)开始日期在指定范围内的日期内 2)开始日期在结束日期之前。

如果日期无效,则应向用户显示错误消息,并且必须更正此问题。我已经能够让每个验证单独工作,但不能一起工作。

以下是我的工作,用于验证指定范围内的日期:

' Variables for the start and end dates of the calendar range
Dim sd As Date
Dim ed As Date

' Set the dates to the start and end of the calendar range
sd = DateValue(Range("weeks_rg")(1))
ed = DateValue(Range("weeks_rg")(Range("weeks_rg").Columns.Count))

' Validate that the start date is within the calendar range
With Range("start_dt").Validation
 .Delete
 .Add Type:=xlValidateDate, _
 AlertStyle:=xlValidAlertStop, _
 Operator:=xlBetween, Formula1:=sd, Formula2:=ed
 .ErrorTitle = "Start Date"
 .ErrorMessage = "You must enter a Start Date within the calendar date range of " & sd & " and " & ed
End With

这样可以正常工作,这个代码验证开始日期是在结束日期之前:

With Range("start_dt").Validation
 .Delete
 .Add Type:=xlValidateDate, _
 AlertStyle:=xlValidAlertStop, _
 Operator:=xlLessEqual, Formula1:=Range("end_dt")
 .ErrorTitle = "Start Date"
 .ErrorMessage = "You must enter a Start Date that is before the End Date"
End With

然而,我似乎无法让他们一起工作。我已经尝试将它们放在单独的子中并按顺序调用它们,但这不起作用;只发生第二次验证,第一次验证似乎被忽略。我也尝试将它们组合成一个With语句,但也忽略了第一次验证。

我确信这是一个很小的东西,因为我对VBA很陌生......而且由于在这个网站上提供了很大的帮助,所以我只能做到这一点:)我有什么想法可以做到这一点?< / p>

======================

已添加11/16: 我已经查看了很多关于这些功能的在线帮助,但找不到那些似乎正在尝试做的事情。我想使用类似下面的代码,但它不起作用,我不知道为什么。即使调试语句显示逻辑正在运行,也没有任何验证似乎会触发。

如果用户更改了他们想要查看的开始日期或结束日期,整个过程会调用验证和主过程:

Private Sub Worksheet_Change(ByVal Target As Range)
' This section calls the process utilization procedure when the user moves
' out of the start date or end date fields

    If Target.Address = Range("start_dt").Address Then
        Debug.Print "start changed"
        Range("start_dt").Validation.Delete
        Process_Utilization
        Verify_start_date
    End If

    If Target.Address = Range("end_dt").Address Then
        Debug.Print "end changed"
        Range("end_dt").Validation.Delete
        Process_Utilization
        Verify_end_date
    End If

End Sub

然后两个日期程序看起来像这样:

Private Sub verify_end_date()

' Variables for the start and end dates of the calendar range
Dim sd As Date
Dim ed As Date
' Variables for the user-entered start and end dates
Dim ued As Date
Dim usd As Date

' create string variable to store our custom formula
Dim title As String
Dim msg As String

Debug.Print "start"

' Set the dates to the start and end of the calendar range
sd = DateValue(Range("weeks_rg")(1))
ed = DateValue(Range("weeks_rg")(Range("weeks_rg").Columns.Count))

' Set the user-entered dates
usd = DateValue(Range("start_dt"))
ued = DateValue(Range("end_dt"))

' Check if the user-entered end date is within the calendar range
If Not (sd <= ued And ued <= ed) Then
    Debug.Print "ued out of range"
    title = "End Date"
    msg = "You must enter a Start Date within the calendar date range of " & sd & " and " & ed

    With Range("end_dt").Validation
     .Delete ' needed to delete any existing validation
     .Add Type:=xlBetween, _
     AlertStyle:=xlValidAlertStop, _
     Formula1:=sd, Formula2:=ed
     .ErrorTitle = title
     .ErrorMessage = msg
    End With

ElseIf ued < usd Then ' Check if the user end date is prior to the user start date
    Debug.Print "end before start"
    title = "End Date"
    msg = "The End Date must be later than the Start Date"

    With Range("end_dt").Validation
     .Delete ' needed to delete any existing validation
     .Add Type:=xlgretaerequal, _
     AlertStyle:=xlValidAlertStop, _
     Formula1:=usd
     .ErrorTitle = title
     .ErrorMessage = msg
    End With

End If


End Sub

我是否遗漏了某些东西,或者我正在尝试做一些不起作用的事情?

1 个答案:

答案 0 :(得分:1)

以下是修改后的代码段以执行自定义验证。你正在做一个excel内置日期验证,你注意到它只能用一个条件验证。

要在excel验证中使用多个条件,需要使用自定义验证(xlValidateCustom而不是xlValidateDate)。当您使用此类型时,您需要创建一个公式并将其分配给&#34; Formula1&#34;属性。

正如您所看到的,为了使用多个条件,我只使用了自定义公式&#39; =和(condition1,condition2 [,...])&#39;功能。 &#39; =和()&#39;只有当所有条件都返回true时,函数才会返回true。

'=and()' function documentation

' Variables for the start and end dates of the calendar range
Dim sd As Date
Dim ed As Date 
' create string variables to store range addresses
Dim sdRange as string
Dim edRange as string
Dim start_dtRange as string
Dim end_dtRange as string
' create string variable to store our custom formula
Dim formula as string

' Set the dates to the start and end of the calendar range
sd = DateValue(Range("weeks_rg")(1))
ed = DateValue(Range("weeks_rg")(Range("weeks_rg").Columns.Count)) 
' store the range addresses of named ranges
sdRange = Range("weeks_rg")(1).Address
edRange = Range("weeks_rg")(Range("weeks_rg").Columns.Count).Address
start_dtRange = Range("start_dt").Address
end_dtRange = Range("end_dt").Address
' store our custom formula in a string
formula = "=and(" & start_dtRange & ">" & sdRange & "," & start_dtRange & "<" & edRange & "," & start_dtRange & "<" & end_dtRange & ")"

' Validate that ('start date' > sd and < ed and < 'end date')
With Range("start_dt").Validation
 .Delete ' needed to delete any existing validation
 .Add Type:=xlValidateCustom, _
 AlertStyle:=xlValidAlertStop, _
 Formula1:=formula
'Modify ErrorTitle and ErrorMessage to have appropriate content
 .ErrorTitle = "Start Date"
 .ErrorMessage = "You must enter a Start Date within the calendar date range of " & sd & " and " & ed
End With