英文:
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
参数,而是预期两个Variant
。Variant
是一种占位符,表示“它可以是任何东西”。在你的情况下,你将日期作为第一个参数传递,第二个参数为空值。"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 Date
s as parameters, it is expecting 2 Variant
s. 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 < 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
以下是翻译好的部分:
略微修改函数以检查所有可能的情况:
- 提供了两个日期。
- 提供了两个日期中的一个。
- 未提供日期(根据您的需求进行修改)。
如果两个日期都已提供,则函数返回一个“长整型”,因此日期返回类型不适合;最好将其保留为“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:
- Both dates supplied.
- One of the two dates supplied.
- 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 > 0 And d2 > 0:
EarlierDate = DateDiff("d", d1, d2)
Case d1 > 0:
EarlierDate = d1
Case d2 > 0:
EarlierDate = d2
Case Else:
Err.Raise 1001, , "No date supplied."
End Select
End Function
To test it:
Sub T()
Dim arrayValues(2)
arrayValues(1) = #10/10/2023#
Debug.Print EarlierDate(arrayValues(1), arrayValues(0))
'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.
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
> 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("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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论