Преобразование big-endian в little-endian и наоборот в VBA - PullRequest
2 голосов
/ 19 апреля 2010

Моя машина имеет порядок байтов (порядок байтов Intel). Мне нужно прочитать двоичный файл, содержащий 16-разрядные целочисленные данные со знаком в порядке байтов Motorola / IEEE ("big-endian"), затем выполнить некоторые вычисления и, наконец, записать полученные данные integer в двоичный файл с прямым порядком байтов.

Как мне сделать вышеупомянутое в VBA, то есть преобразовать big-endian в little-endian и наоборот?

Причина в том, что я обрабатываю НАСА Топографическая миссия Shuttle Radar данные ( формат файла HGT ).

Ответы [ 3 ]

2 голосов
/ 19 апреля 2010

Используя простую побитовую логику.

Public Function SwapBytes(ByVal i As Integer) As Integer
  Dim b1 As Byte, b2 As Byte

  b1 = i And &HFF

  If i And &H8000 Then
    b2 = ((i And &H7F00) / 256) Or &H80
  Else
    b2 = (i And &HFF00) / 256
  End If

  If b1 And &H80 Then
    SwapBytes = (b1 And &H7F) * 256 Or b2 Or &H8000
  Else
    SwapBytes = b1 * 256 Or b2
  End If

End Function

Ну, не все так просто из-за ограничений VBA. Тем не менее, я считаю, что это будет гораздо быстрее, чем дважды вызывать функцию CopyMemory.

0 голосов
/ 22 апреля 2018

Вот простое преобразование ASCII:

Открытая функция SwapLong (данные как долго), как долго

Const Sz As Integer = 3
Dim Bytes(Sz) As Byte
Dim n As Integer
Dim HexStr As String
Dim SwpStr As String

HexStr = Right("00000000" + Hex(Data), 2 * (Sz + 1))
SwpStr = vbNullString

For n = 0 To Sz
    SwpStr = SwpStr + Mid(HexStr, (Sz - n) * 2 + 1, 2)
Next n

SwapLong = CLng("&h" + SwpStr)

Конечная функция

Открытая функция SwapInt (данные как целое число) Как целое число

Const Sz As Integer = 1
Dim Bytes(Sz) As Byte
Dim n As Integer
Dim HexStr As String
Dim SwpStr As String

HexStr = Right("0000" + Hex(Data), 2 * (Sz + 1))
SwpStr = vbNullString

For n = 0 To Sz
    SwpStr = SwpStr + Mid(HexStr, (Sz - n) * 2 + 1, 2)
Next n

SwapInt = CInt("&h" + SwpStr)

Функция завершения

0 голосов
/ 19 апреля 2010

Вот подпрограмма, с которой вы можете начать:

Public Sub ProcessData()
  Dim inputFileName As String
  Dim outputFileName As String
  Dim wordCount As Integer
  Dim i As Integer
  Dim msb As Byte
  Dim lsb As Byte
  Dim unsignedWord As Long
  Dim word As Integer

  inputFileName = "C:\Input.bin"
  outputFileName = "C:\Output.bin"

  wordCount = FileLen(inputFileName) / 2

  Open inputFileName For Binary Access Read As #1
  Open outputFileName For Binary Access Write As #2

  For i = 1 To wordCount
    Get #1, , msb
    Get #1, , lsb

    unsignedWord = CLng(msb) * 256 + lsb
    If unsignedWord > 32768 Then
      word = -CInt(65536 - unsignedWord)
    Else
      word = CInt(unsignedWord)
    End If

    ' Do something with each word.
    word = -word

    If word < 0 Then
      unsignedWord = 65536 + word
    Else
      unsignedWord = word
    End If
    msb = CByte(unsignedWord / 256)
    lsb = CByte(unsignedWord Mod 256)

    Put #2, , msb
    Put #2, , lsb
  Next

  Close #1
  Close #2
End Sub
...