首先,我不是专业人士,但我有几年的SSMS和MS-Access数据库经验。
目标:在调用公共函数时通过更新查询更新MS-Access表中的字段
问题:执行MS-Access查询时,该字段似乎更新为NULL值(这是通过首先使用文本字符串&#34更新此字段来识别的;测试&#34 ;;然后在执行查询后现在导致NULL值,用于表示" testing")。如果该字段已经为NULL,然后我执行查询,则该值保持为NULL。执行查询后,在查看VBA中的立即窗口时会有结果。
一些预期结果将在更新字段中:
0年0个月0周4天3小时11分8秒
0年0个月-1周11天21小时3分29秒
0年0个月-1周8天20小时51分42秒
0年0个月-1周12天19小时43分17秒
0年0个月0周0天0小时1分3秒
0年0个月0周0天2小时30分55秒
0年0个月0周0天2小时44分52秒
0年0个月1周0天1小时18分23秒
0年0个月0周9天19小时48分33秒
0年0个月-1周11天21小时6分49秒
正在使用公共函数的代码:
Public Function ElapsedTimeString(Interval As String, Date1 As Variant, Date2 As Variant, Optional ShowZero As Boolean = False) As Variant
'You must specify how you want the difference between two date/times to be calculated
'This is done by providing which string from ymwdhns (for years, months, weeks, days, hours, minutes and seconds)
'you want calculated.
'For example:
'Print Diff2Dates("y", #6/1/1998#, #6/26/2002#)
'4 years
'Print Diff2Dates("ymd", #6/1/1998#, #6/26/2002#)
'4 years 25 days
'Print Diff2Dates("ymd", #6/1/1998#, #6/26/2002#, True)
'4 years 0 months 25 days
'Print Diff2Dates("ymwd", #6/1/1998#, #6/26/2002#, True)
'4 years 0 months 3 weeks 4 days
'Print Diff2Dates("d", #6/1/1998#, #6/26/2002#)
'1486 days
'Print Diff2Dates("h", #1/25/2002 1:23:01 AM#, #1/26/2002 8:10:34 PM#)
'42 hours
'Print Diff2Dates("hns", #1/25/2002 1:23:01 AM#, #1/26/2002 8:10:34 PM#)
'42 hours 47 minutes 33 seconds
'Print Diff2Dates("dhns", #1/25/2002 1:23:01 AM#, #1/26/2002 8:10:34 PM#)
'1 day 18 hours 47 minutes 33 seconds
'Print Diff2Dates("ymd", #12/31/1999#, #1/1/2000#)
'1 Day
'Print Diff2Dates("ymd", #1/1/2000#, #12/31/1999#)
'-1 day
'Print Diff2Dates("ymd", #1/1/2000#, #1/2/2000#)
'1 Day
'Description: This function calculates the number of years,
' months, days, hours, minutes and seconds between
' two dates, as elapsed time.
'Inputs: Interval: Intervals to be displayed (a string)
' Date1: The lower date (see below)
' Date2: The higher date (see below)
' ShowZero: Boolean to select showing zero elements
'Outputs: On error: Null
' On no error: Variant containing the number of years,
' months, days, hours, minutes & seconds between
' the two dates, depending on the display interval
' selected.
' If Date1 is greater than Date2, the result will
' be a negative value.
' The function compensates for the lack of any intervals
' not listed. For example, if Interval lists "m", but
' not "y", the function adds the value of the year
' component to the month component.
' If ShowZero is True, and an output element is zero, it
' is displayed. However, if ShowZero is False or
' omitted, no zero-value elements are displayed.
' For example, with ShowZero = False, Interval = "ym",
' elements = 0 & 1 respectively, the output string
' will be "1 month" - not "0 years 1 month".
On Error GoTo Err_Diff2Dates
Dim booCalcYears As Boolean
Dim booCalcMonths As Boolean
Dim booCalcDays As Boolean
Dim booCalcHours As Boolean
Dim booCalcMinutes As Boolean
Dim booCalcSeconds As Boolean
Dim booCalcWeeks As Boolean
Dim booSwapped As Boolean
Dim dtTemp As Date
Dim intCounter As Integer
Dim lngDiffYears As Long
Dim lngDiffMonths As Long
Dim lngDiffDays As Long
Dim lngDiffHours As Long
Dim lngDiffMinutes As Long
Dim lngDiffSeconds As Long
Dim lngDiffWeeks As Long
Dim varTemp As Variant
Dim Diff2Dates As Variant
Const INTERVALS As String = "ymwdhns"
'Check that Interval contains only valid characters
Interval = LCase$(Interval)
For intCounter = 1 To Len(Interval)
If InStr(1, INTERVALS, Mid$(Interval, intCounter, 1)) = 0 Then
Exit Function
End If
Next intCounter
'Check that valid dates have been entered
If IsNull(Date1) Then Exit Function
If IsNull(Date2) Then Exit Function
If Not (IsDate(Date1)) Then Exit Function
If Not (IsDate(Date2)) Then Exit Function
'If necessary, swap the dates, to ensure that
'Date1 is lower than Date2
' If Date1 > Date2 Then
' dtTemp = Date1
' Date1 = Date2
' Date2 = dtTemp
' booSwapped = True
' End If
Diff2Dates = Null
varTemp = Null
'What intervals are supplied
booCalcYears = (InStr(1, Interval, "y") > 0)
booCalcMonths = (InStr(1, Interval, "m") > 0)
booCalcDays = (InStr(1, Interval, "d") > 0)
booCalcHours = (InStr(1, Interval, "h") > 0)
booCalcMinutes = (InStr(1, Interval, "n") > 0)
booCalcSeconds = (InStr(1, Interval, "s") > 0)
booCalcWeeks = (InStr(1, Interval, "w") > 0)
'Get the cumulative differences
If booCalcYears Then
lngDiffYears = Abs(DateDiff("yyyy", Date1, Date2)) - _
IIf(Format$(Date1, "mmddhhnnss") <= Format$(Date2, "mmddhhnnss"), 0, 1)
Date1 = DateAdd("yyyy", lngDiffYears, Date1)
End If
If booCalcMonths Then
lngDiffMonths = Abs(DateDiff("m", Date1, Date2)) - _
IIf(Format$(Date1, "ddhhnnss") <= Format$(Date2, "ddhhnnss"), 0, 1)
Date1 = DateAdd("m", lngDiffMonths, Date1)
End If
If booCalcWeeks Then
lngDiffWeeks = Abs(DateDiff("w", Date1, Date2)) - _
IIf(Format$(Date1, "hhnnss") <= Format$(Date2, "hhnnss"), 0, 1)
Date1 = DateAdd("ww", lngDiffWeeks, Date1)
End If
If booCalcDays Then
lngDiffDays = Abs(DateDiff("d", Date1, Date2)) - _
IIf(Format$(Date1, "hhnnss") <= Format$(Date2, "hhnnss"), 0, 1)
Date1 = DateAdd("d", lngDiffDays, Date1)
End If
If booCalcHours Then
lngDiffHours = Abs(DateDiff("h", Date1, Date2)) - _
IIf(Format$(Date1, "nnss") <= Format$(Date2, "nnss"), 0, 1)
Date1 = DateAdd("h", lngDiffHours, Date1)
End If
If booCalcMinutes Then
lngDiffMinutes = Abs(DateDiff("n", Date1, Date2)) - _
IIf(Format$(Date1, "ss") <= Format$(Date2, "ss"), 0, 1)
Date1 = DateAdd("n", lngDiffMinutes, Date1)
End If
If booCalcSeconds Then
lngDiffSeconds = Abs(DateDiff("s", Date1, Date2))
Date1 = DateAdd("s", lngDiffSeconds, Date1)
End If
If booCalcYears And (lngDiffYears > 0 Or ShowZero) Then
varTemp = lngDiffYears & IIf(lngDiffYears <> 1, " years", " year")
End If
If booCalcMonths And (lngDiffMonths > 0 Or ShowZero) Then
If booCalcMonths Then
varTemp = varTemp & IIf(IsNull(varTemp), Null, " ") & _
lngDiffMonths & IIf(lngDiffMonths <> 1, " months", " month")
End If
End If
If booCalcWeeks And (lngDiffWeeks > 0 Or ShowZero) Then
If booCalcWeeks Then
varTemp = varTemp & IIf(IsNull(varTemp), Null, " ") & _
lngDiffWeeks & IIf(lngDiffWeeks <> 1, " weeks", " week")
End If
End If
If booCalcDays And (lngDiffDays > 0 Or ShowZero) Then
If booCalcDays Then
varTemp = varTemp & IIf(IsNull(varTemp), Null, " ") & _
lngDiffDays & IIf(lngDiffDays <> 1, " days", " day")
End If
End If
If booCalcHours And (lngDiffHours > 0 Or ShowZero) Then
If booCalcHours Then
varTemp = varTemp & IIf(IsNull(varTemp), Null, " ") & _
lngDiffHours & IIf(lngDiffHours <> 1, " hours", " hour")
End If
End If
If booCalcMinutes And (lngDiffMinutes > 0 Or ShowZero) Then
If booCalcMinutes Then
varTemp = varTemp & IIf(IsNull(varTemp), Null, " ") & _
lngDiffMinutes & IIf(lngDiffMinutes <> 1, " minutes", " minute")
End If
End If
If booCalcSeconds And (lngDiffSeconds > 0 Or ShowZero) Then
If booCalcSeconds Then
varTemp = varTemp & IIf(IsNull(varTemp), Null, " ") & _
lngDiffSeconds & IIf(lngDiffSeconds <> 1, " seconds", " second")
End If
End If
' If booSwapped Then
' varTemp = "-" & varTemp
' End If
Diff2Dates = Trim$(varTemp)
Debug.Print varTemp
End_Diff2Dates:
Exit Function
Err_Diff2Dates:
Resume End_Diff2Dates
End Function
来自MS-Access更新查询的Gooey:
代码开始***************** UPDATE SupplyToMakeFinal SET SupplyToMakeFinal.TimeToMakeDaysHoursMinutesSeconds = ElapsedTimeString("ymwdhns",[SupplyLatestEndDate],[MakeLatestEndDate],True);
&#39; **************代码结束*****************
我尝试了数据类型Text和Memo,它们都有相同的结果。
对此事的任何帮助都将非常感激,因为我花了无数个小时研究并尝试了所有我能想到的无济于事。
如果我的帖子中没有包含您所需的全部帮助,我表示歉意;如果您需要我的任何其他信息,请告诉我。
答案 0 :(得分:2)
您的功能原则上有效,但似乎您重命名了它,但忘记将返回值设置为新的函数名称。
你计算
Diff2Dates = Trim$(varTemp)
Debug.Print varTemp
' The End
但是Diff2Dates
只是一个局部变量,你的函数是
Public Function ElapsedTimeString
永远不会分配 ElapsedTimeString
,因此该函数将始终返回NULL。
要么还原名称更改,要么在最后添加:
ElapsedTimeString = Diff2Dates
答案 1 :(得分:0)
你不能以这种方式数月,因为一个月可以有28到31天,也不能是几年,因为他们可以有365或366天。这就是你看到负数的原因。
所以使用下面这样的函数计算月数。从这里你可以计算年数(= Int(月/ 12))。将月份添加到开始日期,您可以从此日期到结束日期计算天数。几周只有七天。
Public Function Months( _
ByVal datDate1 As Date, _
ByVal datDate2 As Date, _
Optional ByVal booLinear As Boolean) _
As Integer
' Returns the difference in full months between datDate1 and datDate2.
'
' Calculates correctly for:
' negative differences
' leap years
' dates of 29. February
' date/time values with embedded time values
' negative date/time values (prior to 1899-12-29)
'
' Optionally returns negative counts rounded down to provide a
' linear sequence of month counts.
' For a given datDate1, if datDate2 is decreased stepwise one month from
' returning a positive count to returning a negative count, one or two
' occurrences of count zero will be returned.
' If booLinear is False, the sequence will be:
' 3, 2, 1, 0, 0, -1, -2
' If booLinear is True, the sequence will be:
' 3, 2, 1, 0, -1, -2, -3
'
' If booLinear is False, reversing datDate1 and datDate2 will return
' results of same absolute Value, only the sign will change.
' This behaviour mimics that of Fix().
' If booLinear is True, reversing datDate1 and datDate2 will return
' results where the negative count is offset by -1.
' This behaviour mimics that of Int().
' DateAdd() is used for check for month end of February as it correctly
' returns Feb. 28. when adding a count of months to dates of Feb. 29.
' when the resulting year is a common year.
'
' 2010-03-30. Cactus Data ApS, CPH.
Dim intDiff As Integer
Dim intSign As Integer
Dim intMonths As Integer
' Find difference in calendar months.
intMonths = DateDiff("m", datDate1, datDate2)
' For positive resp. negative intervals, check if the second date
' falls before, on, or after the crossing date for a 1 month period
' while at the same time correcting for February 29. of leap years.
If DateDiff("d", datDate1, datDate2) > 0 Then
intSign = Sgn(DateDiff("d", DateAdd("m", intMonths, datDate1), datDate2))
intDiff = Abs(intSign < 0)
Else
intSign = Sgn(DateDiff("d", DateAdd("m", -intMonths, datDate2), datDate1))
If intSign <> 0 Then
' Offset negative count of months to continuous sequence if requested.
intDiff = Abs(booLinear)
End If
intDiff = intDiff - Abs(intSign < 0)
End If
' Return count of months as count of full 1 month periods.
Months = intMonths - intDiff
End Function
尽管如此,以这种方式计算混合数月和数天的分辨率为一秒仍然没有多大意义。您可以获得真正计数的最接近的是 days-hours-minutes-seconds(-milliseconds)。