Как получить точную дату / время LastUpdated от объектов в Access?

Я пытаюсь получить дату LastUpdated из объектов Access, и иногда она возвращает значение 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;

или используя DAO из окна Immediate:

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

На панели навигации отображается правильная дата (если вы выбрали Просмотр по | Подробности)

и появляется в диалоге свойств объекта:

Я использую Access 2016 Office 365, 32-разрядный.

2 ответа

Решение

Проводя исследование во время написания этого вопроса, я обнаружил, что это известная ошибка давно (по крайней мере, Access 2007).

KB 299554: свойство LastUpdated объектов доступа к данным (DAO) возвращает неверные даты и время в базе данных Microsoft Access

К сожалению, Microsoft не исправила это, но есть и другой способ получить точную информацию.

Вот функция, которая будет извлекать правильную информацию (кроме модулей):

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 <https://codekabinett.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

Ну просто еще один небольшой комментарий к этой теме. Access - это хорошее многопользовательское приложение, но на самом деле оно не стремится стать студией управления для нескольких разработчиков... и это единственная причина, по которой вам нужно будет отмечать изменения в дизайне фиксированных объектов.

в большинстве случаев определенно не нужно, чтобы пользователи меняли объекты - и скомпилированный.accde - это все, что выпущено, поэтому у них нет такой возможности.

где пользовательская база обладает навыками для создания своих собственных запросов - часто лучше всего создать отдельный интерфейс для этой цели и не допускать его в область навигации объекта основного приложения.

Другие вопросы по тегам