Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VBA验证-一个单元格上的多个日期验证_Vba_Validation_Excel - Fatal编程技术网

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

VBA验证-一个单元格上的多个日期验证,vba,validation,excel,Vba,Validation,Excel,我试图验证单元格中输入的日期,但遇到问题。这种情况是,我有一个命名的单元格范围(列标题),这些单元格在日历视图中保存日期。然后,用户输入开始和结束日期,我想验证: 1) 开始日期在指定范围内的日期内 2) 开始日期早于结束日期 如果日期无效,则应向用户显示一条错误消息,并应纠正该问题。我已经能够让每个验证单独工作,但不能一起工作 以下是用于验证指定范围内日期的工具: ' Variables for the start and end dates of the calendar range Dim

我试图验证单元格中输入的日期,但遇到问题。这种情况是,我有一个命名的单元格范围(列标题),这些单元格在日历视图中保存日期。然后,用户输入开始和结束日期,我想验证: 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
然而,我似乎无法让他们一起工作。我试着把它们放在不同的sub中,并按顺序调用它们,但这不起作用;只有第二次验证发生,第一次验证似乎被忽略。我还尝试将它们组合成一个With语句,但这也忽略了第一次验证

我相信这是一件小事,因为我对VBA非常陌生……我之所以能做到这一点,是因为我在这个网站上得到了巨大的帮助:)我能做些什么来让它工作呢

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

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
Private Sub-verify\u end\u date()
'日历范围的开始日期和结束日期的变量
Dim sd作为日期
日期
'用户输入的开始和结束日期的变量
日期
日期为美元
'创建字符串变量以存储自定义公式
将标题设置为字符串
作为字符串的Dim msg
调试。打印“开始”
'将日期设置为日历范围的开始和结束
sd=日期值(范围(“周”)(1))
ed=日期值(范围(“周”)(范围(“周”).Columns.Count))
'设置用户输入的日期
usd=日期值(范围(“开始时间”))
ued=日期值(范围(“结束时间”))
'检查用户输入的结束日期是否在日历范围内

如果没有(sd这里是修改后的代码段,用于执行自定义验证。您正在执行excel内置的日期验证,正如您所注意到的,它只能在一个条件下进行验证

要在excel验证中使用多个条件,需要使用自定义验证(xlValidateCustom而不是xlValidateDate)。使用此类型时,需要创建公式并将其指定给“Formula1”属性

如您所见,为了使用多个条件,我只使用了一个自定义公式和“=and(condition1,condition2[,…])”函数。只有当所有条件都返回true时,“=and()”函数才会返回true

日历范围的开始日期和结束日期的变量 Dim sd作为日期 日期 '创建字符串变量以存储范围地址 作为字符串的Dim sdRange 作为字符串的Dim edRange Dim start\u dtRange作为字符串 Dim end_dtRange作为字符串 '创建字符串变量以存储自定义公式 作为字符串的Dim公式 '将日期设置为日历范围的开始和结束 sd=日期值(范围(“周”)(1)) ed=日期值(范围(“周”)(范围(“周”).Columns.Count)) '存储命名范围的范围地址 sdRange=范围(“周”)(1)。地址 edRange=Range(“weeks\u rg”)(Range(“weeks\u rg”).Columns.Count)。地址 起始距离=范围(“起始距离”)。地址 end_dtRange=范围(“end_dt”)。地址 '将自定义公式存储在字符串中
公式=“=和(“&start\u dtRange&“>”&sdRange&“,”&start\u dtRange&”"您能否提供开始日期和结束日期示例范围?例如,假设日历开始日期为1/1/15,日历结束日期为12/31/15。我需要根据这两个日期测试用户输入的日期。因此,如果用户输入的开始日期为1/1/15,没有问题,但用户开始日期为1/1/14会导致错误。同样,用户结束15年2月1日是可以的,但16年2月1日是一个错误。最后,如果用户输入的开始日期晚于用户输入的结束日期,这也会导致一个错误。帕特里克,谢谢你!这让我更接近了,我想我可以让它工作。它仍然只是测试一个条件,碰巧公式中的条件有点复杂,但是是否有任何方法可以真正单独测试多个条件?理想情况下,我希望有一种IF语句,这样我就可以根据用户的开始日期是否早于日期范围的开始日期、在用户的结束日期之后、在日期范围的结束日期之后,以及在e用户的结束日期字段。使用内置数据验证,我认为您只能使用一个公式,每个单元格只能有一条错误消息。您还有其他可用选项。我可以想到的选项有:(1)一个VBA工作表更改事件来测试每个条件(这确实会减慢速度)(2)您可以添加一个自定义inputbox/userform,让用户在表单中输入值并进行测试。这里有一个指向文档的链接:我原以为可以通过将数据选项卡上Excel UI的验证与VBA代码验证相结合来实现这一点,但现在我意识到这两种方法影响的是同一件事,我只需要一种验证这是可能的。我用另一种方法编辑了上面的原始帖子,但它也不起作用。我是VBA新手,但没有编码,这似乎是对两种情况的一个相当简单的测试,如果无效,则可以防止用户离开。我希望我只是遗漏了一些东西。工作表更改事件
' 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