如何用vba读取复合文档的文件头?

复合文档二进制文件的文件头总是位于文件的起始位置,并且它的大小刚好是512个字节。

复合文档的文件头结构说明如下:

偏移量	字节大小	说明
0	8	复合文件的标识符,值为0xD0CF11E0A1B11AE1
8	16	当前文件的唯一标识符
24	2	复合文件格式的修订版本号
26	2	复合文件格式的版本号
28	2	字节序0xFEFF表示Little-Endian,0xFEFF表示Big-Endian
30	2	Sector大小指数,实际Sector大小=2^SectorShift
32	2	short-sector大小指数,实际short-sector大小=2^SSectorShift
34	10	保留字,10字节,没使用
44	4	SAT拥有的总的Sector数量
48	4	Directory stream的第一个Sector的SecID
52	4	保留字,没使用
56	4	标准stream的最小字节,如果stream小于这个值,则保存为short-streams
60	4	SSAT的第一个Sector的SecID,如果没有,则是-2(End of Chain SecID)
64	4	SSAT拥有的总的Sector数量
68	4	MSAT的第一个Sector的SecID。如果没有,则是-2(End of Chain SecID)
72	4	MSAT拥有的总的Sector数量
76	436	MSAT最先的109个SecID

根据这个文件头的结构说明,可以在vba中自定义如下的文件头结构类型:

Public Type CDFHeader                           ' 复合文件文件头结构
    CFID(7)                     As Byte         ' 复合文件的标识符,值为0xD0CF11E0A1B11AE1
    FID(15)                     As Byte         ' 当前文件的唯一标识符
    MinorVersion                As Integer      ' 复合文件格式的修订版本号
    MajorVersion                As Integer      ' 复合文件格式的版本号
    ByteOrder                   As Integer      ' 字节序0xFEFF表示Little-Endian,0xFEFF表示0xFFFE表示Big-Endian
    SectorShift                 As Integer      ' Sector大小指数,实际Sector大小=2^SectorShift
    SSectorShift                As Integer      ' short-sector大小指数,实际short-sector大小=2^SSectorShift
    Reserved(9)                 As Byte         ' 保留字,10字节,没使用
    TNSSAT                      As Long         ' SAT拥有的总的Sector数量
    DirSecStart                 As Long         ' Directory stream 的第一个Sector的SecID
    Reserved1                   As Long         ' 保留字,没使用
    MiniStreamSZ                As Long         ' 标准stream的最小字节,如果stream小于这个值,则保存为short-streams
    SSATStart                   As Long         ' SSAT的第一个Sector的SecID。如果没有,则是-2(End of Chain SecID)
    TNSSSAT                     As Long         ' SSAT拥有的总的Sector数量
    MASTStart                   As Long         ' MSAT的第一个Sector的SecID。如果没有,则是-2(End of Chain SecID)
    MASTCount                   As Long         ' MSAT拥有的总的Sector数量
    MAST(108)                   As Long         ' MSAT最先的109个SecID
End Type

然后用  Open 文件完整路径 For Binary Access Read As 文件号 语句读取文件头的字节内容到自定义类型中,代码如下:

Public Type CDFHeader ' 复合文件文件头结构
    CFID(7) As Byte ' 复合文件的标识符,值为0xD0CF11E0A1B11AE1
    FID(15) As Byte ' 当前文件的唯一标识符
    MinorVersion As Integer ' 复合文件格式的修订版本号
    MajorVersion As Integer ' 复合文件格式的版本号
    ByteOrder As Integer ' 字节序0xFEFF表示Little-Endian,0xFEFF表示0xFFFE表示Big-Endian
    SectorShift As Integer ' Sector大小指数,实际Sector大小=2^SectorShift
    SSectorShift As Integer ' short-sector大小指数,实际short-sector大小=2^SSectorShift
    Reserved(9) As Byte ' 保留字,10字节,没使用
    TNSSAT As Long ' SAT拥有的总的Sector数量
    DirSecStart As Long ' Directory stream 的第一个Sector的SecID
    Reserved1 As Long ' 保留字,没使用
    MiniStreamSZ As Long ' 标准stream的最小字节,如果stream小于这个值,则保存为short-streams
    SSATStart As Long ' SSAT的第一个Sector的SecID。如果没有,则是-2(End of Chain SecID)
    TNSSSAT As Long ' SSAT拥有的总的Sector数量
    MASTStart As Long ' MSAT的第一个Sector的SecID。如果没有,则是-2(End of Chain SecID)
    MASTCount As Long ' MSAT拥有的总的Sector数量
    MAST(108) As Long ' MSAT最先的109个SecID
End Type
Public CDH As CDFHeader
Sub GetCDFH()
    Dim sPath As String
    sPath = "c:\1.xls"
    Dim i As Byte
    i = VBA.FreeFile
    Open sPath For Binary Access Read As i
    Get i, , CDH
    Close
End Sub
       

发表评论