在VBA中,如何检查日期函数是否未传递任何值?

huangapple go评论69阅读模式
英文:

In VBA how to check no value is passed to a function using Dates?

问题

I wrote a function that returns the earlier of two dates as a date object.

Function ReturnEarlierDate(newDate, existingDate) As Date
    deltad = DateDiff("d", CDate(newDate), CDate(existingDate))
    If deltad > 0 Then
        ReturnEarlierDate = CDate(newDate)
    End If
    ReturnEarlierDate = CDate(existingDate)
End Function

I want the function to use the existingDate if only one parameter is passed and vice versa, only newDate if no existingDate is provided.

Sub Test()
    Dim arrayValues(2)
    arrayValues(1) = #10/10/2023#
    Debug.Print ReturnEarlierDate(arrayValues(1), arrayValues(0))
End Sub

The return value I want is 10/10/2023 and not 00:00:00.

英文:

I wrote a function that returns the earlier of two dates as a date object.

Function ReturnEarlierDate(newDate, existingDate) As Date
    deltad = DateDiff("d", CDate(newDate), CDate(existingDate))
    If deltad > 0 Then
        ReturnEarlierDate = CDate(newDate)
    End If
        ReturnEarlierDate = CDate(existingDate)
End Function

I want the function to use the existingDate, if only one parameter is passed and vice versa, only newDate if no existingDate is provided.

Sub Test()
    Dim arrayValues(2)
    arrayValues(1) = #10/10/2023#
    Debug.Print ReturnEarlierDate(arrayValues(1), arrayValues(0))
End Sub

The return value I want it 10/10/2023 and not 00:00:00

答案1

得分: 3

你的函数不是预期的两个Date参数,而是预期两个VariantVariant是一种占位符,表示“它可以是任何东西”。在你的情况下,你将日期作为第一个参数传递,第二个参数为空值。"Empty"表示Variant未初始化,简单地不包含任何内容。可以使用 IsEmpty 进行检查。

If IsEmpty(newDate) Then
    ReturnEarlierDate = CDate(existingDate)
ElseIf IsEmpty(existingDate) Then
    ReturnEarlierDate = CDate(newDate)
Else
    (...你的代码在这里)

虽然检查空值很容易,但你的函数存在一个更大的问题:它不检查两个参数是否真的是日期。如果其中一个参数是String,则会出现类型不匹配的运行时错误。

通过处理Date数据类型,你完全可以避免这个问题。唯一的缺点是不再能使用 IsEmpty 来检查参数是否为空(IsEmpty 仅适用于Variant)。在VBA(和Excel)中,日期被存储为数字(Double类型)。VBA中的数字初始化为值0,因此在函数中,你必须检查是否为0。注意在函数内不再需要使用 CDate

Function ReturnEarlierDate(newDate As Date, existingDate As Date) As Date
    If newDate = 0 Then
        ReturnEarlierDate = existingDate
    ElseIf existingDate = 0 Then
        ReturnEarlierDate = newDate
    ElseIf newDate < existingDate Then
        ReturnEarlierDate = newDate
    Else
        ReturnEarlierDate = existingDate
    End If
End Function

Sub Test()
    Dim arrayValues(2) As Date
    arrayValues(1) = #10/10/2023#
    Debug.Print ReturnEarlierDate(arrayValues(1), arrayValues(0))
End Sub

现在,该函数仅在两个日期都为空时返回0(00:00:00)。

英文:

Your function is not expecting 2 Dates as parameters, it is expecting 2 Variants. A Variant is a kind of placeholder saying "It can be everything". In your case you are passing a date as first and an empty value as second value. "Empty" means that a Variant was not initialized and simply doesn't hold anything. This can be checked with IsEmpty.

If IsEmpty(newDate) Then
    ReturnEarlierDate = CDate(existingDate)
ElseIf IsEmpty(existingDate) Then
    ReturnEarlierDate = CDate(newDate)
Else
    (...your code here)

While the check for empty is easy, you have a bigger issue with your function: It doesn't check if the two parameters are really dates. So if you would call it with one of the parameters being a String, you would get a type mismatch runtime error.

You could completely avoid that by dealing with datatype Date. The only drawback would be that it is no longer possible to check if one of the parameters is empty by using IsEmpty (emtpy is available only for Variants). Dates in VBA (and in Excel) are stored as numbers (of type Double). Numbers in VBA are initialized with value 0, so in your function, you have to check for 0. Note that there is no longer the need to use CDate inside the function.

Function ReturnEarlierDate(newDate As Date, existingDate As Date) As Date
    If newDate = 0 Then
        ReturnEarlierDate = existingDate
    ElseIf existingDate = 0 Then
        ReturnEarlierDate = newDate
    ElseIf newDate &lt; existingDate Then
        ReturnEarlierDate = newDate
    Else
        ReturnEarlierDate = existingDate
    End If
End Function

Sub Test()
    Dim arrayValues(2) As Date
    arrayValues(1) = #10/10/2023#
    Debug.Print ReturnEarlierDate(arrayValues(1), arrayValues(0))
End Sub

Now the function returns 0 (= 00:00:00) only if both dates where empty.

答案2

得分: 0

以下是翻译好的部分:

略微修改函数以检查所有可能的情况:

  1. 提供了两个日期。
  2. 提供了两个日期中的一个。
  3. 未提供日期(根据您的需求进行修改)。

如果两个日期都已提供,则函数返回一个“长整型”,因此日期返回类型不适合;最好将其保留为“Variant”。


要测试它:

Sub T()
    
    Dim arrayValues(2)
    arrayValues(1) = #10/10/2023#
    Debug.Print EarlierDate(arrayValues(1), arrayValues(0))
    
    '10/10/2023 
End Sub
英文:

Slightly amend the function to check all possible scenarios:

  1. Both dates supplied.
  2. One of the two dates supplied.
  3. No date supplied (amend to fit your needs).

If both dates have been supplied, the function returns a Long so the date return type is not appropriate; best to leave it as Variant.


Function EarlierDate(ByVal d1 As Date, ByVal d2 As Date) As Variant
    Select Case True
        Case d1 &gt; 0 And d2 &gt; 0:
            EarlierDate = DateDiff(&quot;d&quot;, d1, d2)
        Case d1 &gt; 0:
            EarlierDate = d1
        Case d2 &gt; 0:
            EarlierDate = d2
        Case Else:
            Err.Raise 1001, , &quot;No date supplied.&quot;
    End Select
End Function

To test it:

Sub T()

    Dim arrayValues(2)
    arrayValues(1) = #10/10/2023#
    Debug.Print EarlierDate(arrayValues(1), arrayValues(0))
    
    &#39;10/10/2023 
End Sub

答案3

得分: 0

由于日期基本上以数字值存储,您可以检查它们是否大于0。

Function ReturnEarlierDate(ByVal newDate As Date, ByVal existingDate As Date) As Date
    If newDate = 0 Then
        ReturnEarlierDate = existingDate
        Exit Function
    ElseIf existingDate = 0 Then
        ReturnEarlierDate = newDate
        Exit Function
    End If
    
    deltad = DateDiff("d", newDate, existingDate)
    If deltad > 0 Then
        ReturnEarlierDate = newDate
    Else
        ReturnEarlierDate = existingDate
    End If
End Function

Sub Test()
    Dim arrayValues(2) As Date
    arrayValues(1) = CDate(#10/10/2023#)
    Debug.Print ReturnEarlierDate(arrayValues(1), arrayValues(0))
End Sub

如果您希望函数仅接受一个参数,可以使用可选参数。

Function ReturnEarlierDate1(Optional ByVal newDate As Date, Optional ByVal existingDate As Date) As Date
    If IsMissing(newDate) Then
        ReturnEarlierDate1 = existingDate
        Exit Function
    ElseIf IsMissing(existingDate) = 0 Then
        ReturnEarlierDate1 = newDate
        Exit Function
    End If
    
    deltad = DateDiff("d", newDate, existingDate)
    If deltad > 0 Then
        ReturnEarlierDate1 = newDate
    Else
        ReturnEarlierDate1 = existingDate
    End If
End Function

Sub Test1()
    Dim arrayValues(2) As Date
    arrayValues(1) = CDate(#10/10/2023#)
    Debug.Print ReturnEarlierDate1(, arrayValues(1))
End Sub

有关日期数据类型的更多信息,请参阅Date Data Type (Visual Basic)

英文:

As dates are basically stored as numeric vales you can check if they are greater than 0.

Date Data Type (Visual Basic)

Function ReturnEarlierDate(ByVal newDate As Date, ByVal existingDate As Date) As Date
    If newDate = 0 Then
        ReturnEarlierDate = existingDate
        Exit Function
    ElseIf existingDate = 0 Then
        ReturnEarlierDate = newDate
        Exit Function
    End If
    
    deltad = DateDiff(&quot;d&quot;, newDate, existingDate)
    If deltad &gt; 0 Then
        ReturnEarlierDate = newDate
    Else
        ReturnEarlierDate = existingDate
    End If
End Function

Sub Test()
    Dim arrayValues(2) As Date
    arrayValues(1) = CDate(#10/10/2023#)
    Debug.Print ReturnEarlierDate(arrayValues(1), arrayValues(0))
End Sub

> I want the function to use the existingDate, if only one parameter is
> passed [...]

If you want the function to work with only one parameter passed, you can use Optional parameters.

Function ReturnEarlierDate1(Optional ByVal newDate As Date, Optional ByVal existingDate As Date) As Date
    If IsMissing(newDate) Then
        ReturnEarlierDate1 = existingDate
        Exit Function
    ElseIf IsMissing(existingDate) = 0 Then
        ReturnEarlierDate1 = newDate
        Exit Function
    End If
    
    deltad = DateDiff(&quot;d&quot;, newDate, existingDate)
    If deltad &gt; 0 Then
        ReturnEarlierDate1 = newDate
    Else
        ReturnEarlierDate1 = existingDate
    End If
End Function


Sub Test1()
    Dim arrayValues(2) As Date
    arrayValues(1) = CDate(#10/10/2023#)
    Debug.Print ReturnEarlierDate1(, arrayValues(1))
End Sub

huangapple
  • 本文由 发表于 2023年5月22日 19:05:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76305529.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定