投稿者 るきお  (社会人) 投稿日時 2023/11/12 22:54:12
Excelの32ビット版と64ビット版でVBAにどういう差異があるのか理解していませんが、

> (Highを32bit左シフト)+ Low でいいと思うのですが、VBAでのコーディングがわかりません。
私はこういうビット演算が苦手なので、こういう系はByte型にして、地道にしたからかけ算して足していきます。
この考え方は32ビットでも64ビットでも同じです。

なので、fileSizeの部分はこのようにByteの配列にしてしまって、
fileSizeHigh(3) As Byte
fileSizeLow(3) As Byte


取得したあとで、これをこんな感じで計算します。
fileSizeB = CDec(data.fileSizeLow(0))
fileSizeB = fileSizeB + data.fileSizeLow(1) * 256
fileSizeB = fileSizeB + data.fileSizeLow(2) * 256 ^ 2
fileSizeB = fileSizeB + data.fileSizeLow(3) * 256 ^ 3



かっこよくビット演算すればもっとスマートに行けるとは思いますが…。

参考に64ビット版ではありますが、動作確認したコードを載せておきます。約60GBのファイルでサイズを取得できることを確認しました。
ひさしぶりにExcel VBAを書きました。知らない間に LongLong などという型ができていたんですね。が、これは32ビット版にはないようだったので、一応ここはVariant(Decimal)にしておきました。

Private Const MAX_PATH As Long = 260

Private Declare PtrSafe Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" _
    (ByVal lpFileName As LongPtr, _
     ByRef FindData As WIN32_FIND_DATAW) As LongPtr

Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATAW
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    
    fileSizeHigh(3) As Byte
    fileSizeLow(3) As Byte
    
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName(MAX_PATH * 2 - 1) As Byte
    cAlternateFileName(14 * 2 - 1) As Byte
    dwFileType As Long
    dwCreatorType As Long
    wFinderFlags As Integer
End Type

Public Sub FindFirstFileTest()

    Dim data As WIN32_FIND_DATAW
   
    Dim fileName As String
    fileName = "C:\VM\Windows7.vhd"
    
    Call FindFirstFile(StrPtr(fileName), data)
    
    Dim fileSizeB As Variant
    
    fileSizeB = CDec(data.fileSizeLow(0))
    fileSizeB = fileSizeB + data.fileSizeLow(1) * 256
    fileSizeB = fileSizeB + data.fileSizeLow(2) * 256 ^ 2
    fileSizeB = fileSizeB + data.fileSizeLow(3) * 256 ^ 3
    fileSizeB = fileSizeB + data.fileSizeHigh(0) * 256 ^ 4
    fileSizeB = fileSizeB + data.fileSizeHigh(1) * 256 ^ 5
    fileSizeB = fileSizeB + data.fileSizeHigh(2) * 256 ^ 6
    fileSizeB = fileSizeB + data.fileSizeHigh(3) * 256 ^ 7
    
    Dim fileSizeKB As Variant
    fileSizeKB = CDec(fileSizeB) / 1024
    
    Debug.Print fileSizeKB

End Sub