如何从Access中的对象获取准确的LastUpdated日期/时间?

时间:2019-07-18 22:31:44

标签: vba ms-access access-vba

我试图从Access对象中检索 LastUpdated 日期,有时它返回的是DateCreated值。

我在查询 MSysObjects 时看到相同的结果:

SELECT MSysObjects.Name, 
    Switch([Type]=5,'Query',[Type]=-32768,'Form',[Type]=-32764,'Report',[Type]=-32766,'Macro',[Type]=-32761,'Module') AS ObjectType, 
    MSysObjects.DateUpdate 
FROM MSysObjects
WHERE (((Left$([Name],1))<>'~') AND ((MSysObjects.Type) In (5,-32768,-32764,-32766,-32761)))
ORDER BY MSysObjects.DateUpdate DESC;

Query Result

或在“即时”窗口中使用 DAO

? CurrentDb.Containers("Forms").Documents("frm_POC_Assignment_Override").LastUpdated

Immediate Window

正确的日期显示在导航窗格中(如果选择查看方式|详细信息)

Navigation Pane

并出现在对象属性对话框中:

Object Property Dialog

我正在使用32位Access 2016 Office 365。

2 个答案:

答案 0 :(得分:2)

在撰写问题时进行研究时,我发现这是很久以前的一个已知错误(至少是Access 2007)。

KB 299554: The Data Access Objects (DAO) LastUpdated property returns incorrect dates/times in Microsoft Access database

虽然微软没有修复它令人失望,但是还有另一种获取准确信息的方法。

这是一个可以检索正确信息的功能(模块除外):

Public Function fGetObjectModifiedDate(Object_Name As String, Object_Type As Integer) As Variant
' Get the correct Modified Date of the passed object.  MSysObjects and DAO are not accurate for all object types.

' Based on a tip from: Philipp Stiefel <pstiefel@ivercy.com>
' Getting the last modified date with this line of code does indeed return incorrect results.
'   ? CurrentDb.Containers("Forms").Documents("Form1").LastUpdated
'
' But, that is not what we use to receive the last modified date, except for queries, where the above line is working correctly.
' What we use instead is:
'   ? CurrentProject.AllForms("Form1").DateModified

    Select Case Object_Type
        Case 5 ' Query
            fGetObjectModifiedDate = CurrentDb.QueryDefs(Object_Name).LastUpdated
        Case -32768 ' Form
            fGetObjectModifiedDate = CurrentProject.AllForms(Object_Name).DateModified
'            fGetObjectModifiedDate = CurrentDb.Containers("Forms").Documents(Object_Name).LastUpdated
        Case -32764 ' Report
            fGetObjectModifiedDate = CurrentProject.AllReports(Object_Name).DateModified
        Case -32766 ' Macro
            fGetObjectModifiedDate = CurrentProject.AllMacros(Object_Name).DateModified
        Case -32761 ' Module
            ' This will report the date that *ANY* module was last saved.
            ' The CurrentDb.Containers method and MSysObjects will report the date created.
            fGetObjectModifiedDate = CurrentProject.AllModules(Object_Name).DateModified
        Case Else
            ' Do nothing.  Return Null.
    End Select

End Function

如果要在SQL中调用此函数,建议您在选择所有对象之前进行过滤,否则会很慢。

SELECT MSysObjects.Name, 
    Switch([Type]=5,'Query',[Type]=-32768,'Form',[Type]=-32764,'Report',[Type]=-32766,'Macro',[Type]=-32761,'Module') AS [Object Type], 
    MSysObjects.DateUpdate, 
    fGetObjectModifiedDate([Name],[Type]) AS DateModified
FROM MSysObjects
WHERE (((MSysObjects.Name) Like "frm_POC_Assign*") 
AND ((Left$([Name],1))<>'~') AND ((MSysObjects.Type) In (5,-32768,-32764,-32766,-32761)))
ORDER BY MSysObjects.Name

Query Result

答案 1 :(得分:1)

对此主题的另一条简短评论。 Access是一个很好的多用户应用程序,但并没有真正成为一个多开发人员管理工作室。...这是您需要为固定对象设计更改加上时间戳的唯一原因。

在大多数情况下,绝对不希望用户更改对象-并且已编译的.accde已全部发布,因此他们没有这种能力。

用户群具有制作自己的查询的技能-通常最好为此专门设置一个单独的前端,并将其置于主应用程序的对象导航窗格之外。