65.9K
CodeProject 正在变化。 阅读更多。
Home

VBScript 读取二进制文件并将数据加载到 Excel - 老狗还有老把式

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (7投票s)

2010年1月19日

CC (ASA 2.5)

2分钟阅读

viewsIcon

40484

VBScript 可能已经过时且显得笨拙,但它仍然有一些快速而简单的技巧非常实用。

为什么要费心呢?

VBScript 的问题在于它丑陋、古老,但非常有用。我仍然会不时地使用这项古老的技术,并想分享一个例子,说明如果你想要一些“快速而简单的”解决方案时,它仍然可以用于哪些方面。以下是一个例子,展示了我们通常不与 VBScript 关联的几件事:读取二进制文件和将数据加载到 Excel 中。

读取二进制文件

VBScript 可以读取二进制文件,因为它可以使用 COM 对象,而 ADO 是 COM,并且可以读取二进制文件。这里有一个函数可以做到这一点

function GetGifComment(gifFilePath)
    dim inStream,buff,commentLen,commentStr,myIndex
    dim myByte,myByteValue,myCharacter

    set inStream=WScript.CreateObject("ADODB.Stream")

    inStream.Open
    inStream.type=1

    inStream.LoadFromFile gifFilePath 

    buff=inStream.Read()
    inStream.Close
 
    commentStr=""
    for myIndex = 1 to 6
      ' Extract 1 byte from the buffer
      myByte = MidB(buff,myIndex,1)
      ' Gets its numeric value
      myByteValue = AscB(myByte)
      ' Convert that numeric value into a character
      myCharacter  = Chr(myByteValue)
      ' Append that character to the string
      commentStr  = commentStr & myCharacter
    next
    GetGifComment = commentStr
end function

上述函数使用 ADODB.Stream 对象。我想这些对象是为将文件加载到数据库而设计的;但是,它们非常适合从 VBScript 读取小二进制文件。我怀疑整个文件都被读取到内存中,因此我不会尝试以这种方式加载巨大的文件。一旦文件在内存中,我们就可以通过其 read 方法在本地变量中获取其内容(同样,效率不高 - 但这不是重点)。一旦文件的内容在本地变量中,就可以使用内置函数 MidBAscBChr 进行检查。

应用

在下面的脚本中,我使用了 WScript.Shell 对象来访问 SpecialFolders 枚举,从而访问当前用户的桌面目录。然后,我可以使用 Scripting.FileSystemObject 在桌面上查找任何 GIF 文件。我还直接打开一个 Excel 实例并在其中创建一个新的工作簿。最后的技巧是查找桌面上任何 GIF 文件,并使用我的二进制文件技巧读取文件内部以获取 GIF 版本类型。文件名和版本随后列在 Excel 中。

Option Explicit
  Dim myShell, sendToFolder, myPicturesPath, myShortcut
  Dim fso,myFolder, myFile, fileName, comment, myExcel
  Dim myWorkbook, myRow, mySheet
  ' Find "My Pictures"
  Set myShell = CreateObject("WScript.Shell")
  myPicturesPath = myShell.SpecialFolders("Desktop")

  ' Open "My Pictures" as a folder so we can see
  ' which files are inside it
  Set fso=CreateObject("Scripting.FileSystemObject")
  Set myFolder=fso.GetFolder(myPicturesPath)

  ' Set Up Excel To receive The Data
  Set myExcel=CreateObject("Excel.Application")
  Set myWorkBook=myExcel.WorkBooks.Add
  Set mySheet=myWorkBook.Sheets(1)
  myRow=2
  mySheet.Cells(1,1).Value="Name"
  mySheet.Cells(1,2).Value="GIF Type"
  myExcel.Visible=TRUE

  ' Loop through each file found and see
  ' if its file extension is .gif
  ' If a file is a .gif file then call our function
  ' which opens it as a binary file and reads the 
  ' version label
  for each myFile in myFolder.Files
    fileName=myFile.name
      fileName=Lcase(fileName)
      if Right(fileName,4)=".gif" then
        ' Read the version label
        comment=GetGifComment(myFile.path)
        ' Place the data in the spreadsheet
        mySheet.Cells(myRow,1).Value=fileName
        mySheet.Cells(myRow,2).Value=comment
        ' Step down to the next Row
        myRow=myRow+1
                else
                WScript.echo fileName
      end if
  next

  ' Make the spreadsheet look a bit nicer
  With mySheet.Range("A1:B1").Font
    .FontStyle = "Bold"
    .Size = 12
  End With

  mySheet.Columns(1).Autofit
  mySheet.Columns(2).Autofit

  'Script ends here
 
  function GetGifComment(gifFilePath)
    dim inStream,buff,commentLen,commentStr,myIndex
    dim myByte,myByteValue,myCharacter

    set inStream=WScript.CreateObject("ADODB.Stream")

    inStream.Open
    inStream.type=1

    inStream.LoadFromFile gifFilePath 

    buff=inStream.Read()
    inStream.Close
 
    commentStr=""
    for myIndex = 1 to 6
      ' Extract 1 byte from the buffer
      myByte = MidB(buff,myIndex,1)
      ' Gets its numeric value
      myByteValue = AscB(myByte)
      ' Convert that numeric value into a character
      myCharacter  = Chr(myByteValue)
      ' Append that character to the string
      commentStr  = commentStr & myCharacter
    next
    GetGifComment = commentStr
  end function

结论

这个脚本本身真的很有用吗 - 我怀疑。但是,它的各个部分展示了脚本在那些令人讨厌的系统管理或数据管理任务中如何非常有用,而启动 Visual Studio 并编写完整的应用程序可能有些过头。我怀疑 PowerShell 也可以至少同样好地完成这些操作。也许这应该成为另一篇帖子的主题?

© . All rights reserved.