如何获取文件的最后修改时间(毫秒级)?

3

我正在尝试从一个文件夹中获取一些文件的日期和时间(最后修改时间)。我已经成功获取了日期、小时/分钟/秒数,但无法获取毫秒

我已经尝试过以所有可能的方式格式化列。对于毫秒,我只得到0

到目前为止,我的代码做了以下工作:

  • 用户选择一个文件夹

  • 代码在A列中显示所有找到的文件名,在B列中显示日期、小时、分钟和秒数(最后修改日期/时间)

我应该如何修改当前的代码以获取毫秒?

这是我的代码:

Private Function GetAllFiles(ByVal strPath As String, _
    ByVal intRow As Integer, ByRef objFSO As Object) As Integer
    Dim objFolder As Object
    Dim objFile As Object
    Dim i As Integer
    i = intRow - ROW_FIRST + 1
    Set objFolder = objFSO.GetFolder(strPath)
    For Each objFile In objFolder.Files
        'print file name
        Cells(i + ROW_FIRST + 2, 1) = objFile.Name
        'print file path
        Cells(i + ROW_FIRST + 2, 2) = objFile.DateLastModified
        i = i + 1
    Next objFile
    GetAllFiles = i + ROW_FIRST - 1
End Function

好的,我也是。我会整理一个答案……但是在此之前,我可以先问一下,你打算用这个做什么,为什么需要那么详细的粒度?(另外,VBA的Date类型只有1秒的分辨率,所以它将需要使用不同的数据类型。)你将如何使用它可能会影响答案。 - ashleedawg
简而言之,这是关于对扫描或拆分的文档(PDF)进行排序的问题。我已经编写了重命名代码。问题在于,当我将一个PDF拆分成100页时,它们会变成“part 1 2 3 4 5”等等。VBA获取最后修改日期并根据此日期进行排序。但如果它们具有相同的创建时间和秒数,它无法正确排序。因此,我需要毫秒级别的时间(资源管理器可以正确排序)。我本来可以找到其他解决方案(从“part 1 2 3”中提取数字),但这段代码还要对来自扫描仪等其他类型的PDF进行排序和显示毫秒级时间将是完美的。 - MisterA
我的英文远非完美。所以,VBA读取文件夹内容。在Excel中获取文件夹中文件的最后修改日期。按照日期的时、分、秒对它们进行排序。从那一点开始,另一段VBA代码接管,为这些文件插入来自另一个表格的“新名称”。这些新名称已经按照扫描文档的顺序或PDF中显示的顺序排列好了。顺序必须匹配。 - MisterA
嗯,好的,有点奇怪的要求。你说得对,从文件名中提取数字会更容易(一行代码对比100行)。但是你看到毫秒数了吗?你怎么知道Windows是按照它来排序的呢? - ashleedawg
我们去聊天吧 - ashleedawg
显示剩余4条评论
1个回答

4
以下模块将使用Windows API调用检索Windows文件的创建时间、修改时间或访问时间,包括毫秒。

但必须注意可能存在一些潜在问题。其中一个重要问题是VBA Date数据类型的分辨率为1秒,因此日期时间需要以字符串形式返回,或者存储在不同的数据类型中(Currency是正确的大小)。

Option Explicit

Declare Function GetFileTime Lib "kernel32.dll" (ByVal hFile As Long, _
    lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, _
    lpLastWriteTime As FILETIME) As Long

Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" _
    (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
    ByVal dwShareMode As Long, lpSecurityAttributes As Any, _
    ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
    ByVal hTemplateFile As Long) As Long

Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long

Declare Function FileTimeToSystemTime Lib "kernel32.dll" _
    (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long

Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type


Const GENERIC_READ = &H80000000
Const GENERIC_WRITE = &H40000000
Const FILE_SHARE_READ = &H1
Const FILE_SHARE_WRITE = &H2
Const CREATE_ALWAYS = 2
Const CREATE_NEW = 1
Const OPEN_ALWAYS = 4
Const OPEN_EXISTING = 3
Const TRUNCATE_EXISTING = 5
Const FILE_ATTRIBUTE_ARCHIVE = &H20
Const FILE_ATTRIBUTE_HIDDEN = &H2
Const FILE_ATTRIBUTE_NORMAL = &H80
Const FILE_ATTRIBUTE_READONLY = &H1
Const FILE_ATTRIBUTE_SYSTEM = &H4
Const FILE_FLAG_DELETE_ON_CLOSE = &H4000000
Const FILE_FLAG_NO_BUFFERING = &H20000000
Const FILE_FLAG_OVERLAPPED = &H40000000
Const FILE_FLAG_POSIX_SEMANTICS = &H1000000
Const FILE_FLAG_RANDOM_ACCESS = &H10000000
Const FILE_FLAG_SEQUENTIAL_SCAN = &H8000000
Const FILE_FLAG_WRITE_THROUGH = &H80000000

Function GetDateValue(fName As String) As String
'returns UTC (GMT) file time for specified file

    Dim hFile As Long ' handle to the opened file
    Dim ctime As FILETIME ' receives time of creation
    Dim atime As FILETIME ' receives time of last access
    Dim mtime As FILETIME ' receives time of last modification
    Dim Thetime As SYSTEMTIME ' used to manipulate the time
    Dim retval As Long ' return value

    hFile = CreateFile(fName, GENERIC_READ, FILE_SHARE_READ, _
        ByVal CLng(0), OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0)

    retval = GetFileTime(hFile, ctime, atime, mtime)

    'Choose which date to return: creation, modify or access date
    'retval = FileTimeToSystemTime(ctime, Thetime) 'extract creation datetime
    retval = FileTimeToSystemTime(mtime, Thetime) 'extract modified datetime
    'retval = FileTimeToSystemTime(atime, Thetime) 'extract accessed datetime

    retval = CloseHandle(hFile)

    With Thetime
        GetDateValue = .wYear & Format(.wMonth, "\-00") & _
            Format(.wDay, "\-00") & " " & Format(.wHour, "00") & _
            Format(.wMinute, "\:00") & Format(.wSecond, "\:00") & _
            Format(.wSecond, "\.000")
    End With
End Function

Sub test()
    MsgBox GetDateValue("c:\logfile.txt") 
    'returns a string like "2018-03-31 16:13:52.052"
End Sub

我只是将这个代码粘贴在这里,它并不完美,但它可用并可以根据您的个人需求进行调整。请注意,您需要手动取消注释 datetime 的哪一行以返回该函数的时间。

在将此用于任何重要事项之前,请确保阅读相关资料,因为依赖于您的文件系统等因素会有限制。例如,NTFS通常会在您“认为”文件已经完成写入后结束写入...最长可能延迟1小时。


更多信息:


WSeconds是用于表示毫秒的地方。 - Markos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接