VBA IDE中长字符串的格式

时间:2018-03-19 19:46:34

标签: vba excel-vba encoding utf-8 excel

我正在编写一个带有VBA代码模块的宏,将其导出,将导出的文件读取为64位字符串,并将其作为常量保存在另一个VBA模块中(使用VBComponent.codeModule.InsertLines)。出于某种原因,我的64位字符串在IDE中每72个字符都有换行符(参见图像) Linebreak

由于某种原因,导出文件生成的字符串会执行此操作,但不会生成使用String(500,"a")生成的字符串。我想知道是否有人能够对这种行为提供任何见解,我希望整个表达式都在一行上。

Sub test() 'in a module named "testModule"
    exampleString = String(500, "a")
    ThisWorkbook.VBProject.VBComponents.Item("testModule").codeModule.InsertLines _
    2, "Const str As String = """ & exampleString & """"
End Sub

给出

Sub test() 'in a module named "testModule"
Const str As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    exampleString = String(500, "a")
    ThisWorkbook.VBProject.VBComponents.Item("testModule").codeModule.InsertLines _
    2, "Const str As String = """ & exampleString & """"
End Sub

exampleString = Base64EncodedModule()

导致图像中出现奇怪的行为。也许有一些非常明显的东西,我错过了,但是base64字符串看起来就像我可以输入的东西一样,所以我不知道它为什么会这样当我以编程方式将其写入codeModule时,将多行分开。

最低位代码

Function Base64EncodedModule() As String
    'export module
    Dim exportPath As String: exportPath = Environ("temp") & "\" & "tempModule.bas"
    ThisWorkbook.VBProject.VBComponents("Module1").Export exportPath
    'read file as bytes
    Dim inStream As Object: Set inStream = CreateObject("ADODB.Stream")
    inStream.Open
    inStream.Type = 1 'Binary file
    inStream.LoadFromFile exportPath
    'encode as base 64
    Dim objXML As MSXML2.DOMDocument
    Dim objNode As MSXML2.IXMLDOMElement

    Set objXML = New MSXML2.DOMDocument
    Set objNode = objXML.createElement("b64")

    objNode.DataType = "bin.base64"
    objNode.nodeTypedValue = inStream.Read() 'read bytes from file
    Base64EncodedModule = objNode.text

    Kill exportPath 'remove temp file
End Function

1 个答案:

答案 0 :(得分:3)

字符串为base64 encoded,根据编码算法,每n个4个字符块可包含行分隔符。这似乎就是这种情况。

因此,要么使用Replace删除换行符,要么使用解码/编码算法,不要像这样换行:

'
' Base 64 encoding '
'

Public Sub FromBase64(Text As String, Out() As Byte)
  Dim b64(0 To 255) As Byte, str() As Byte, i&, j&, v&, b0&, b1&, b2&, b3&
  Out = ""
  If Len(Text) Then Else Exit Sub

  str = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  For i = 2 To UBound(str) Step 2
    b64(str(i)) = i \ 2
  Next

  ReDim Out(0 To ((Len(Text) + 3) \ 4) * 3 - 1)
  str = Text & String$(2, 0)

  For i = 0 To UBound(str) - 7 Step 2
    b0 = b64(str(i))

    If b0 Then
      b1 = b64(str(i + 2))
      b2 = b64(str(i + 4))
      b3 = b64(str(i + 6))
      v = b0 * 262144 + b1 * 4096& + b2 * 64& + b3 - 266305
      Out(j) = v \ 65536
      Out(j + 1) = (v \ 256&) Mod 256
      Out(j + 2) = v Mod 256
      j = j + 3
      i = i + 6
    End If
  Next

  If b2 = 0 Then
    Out(j - 3) = (v + 65) \ 65536
    j = j - 2
  ElseIf b3 = 0 Then
    Out(j - 3) = (v + 1) \ 65536
    Out(j - 2) = ((v + 1) \ 256&) Mod 256
    j = j - 1
  End If

  ReDim Preserve Out(j - 1)
End Sub

Public Function ToBase64(data() As Byte) As String
  Dim b64(0 To 63) As Byte, str() As Byte, i&, j&, v&, n&
  n = UBound(data) - LBound(data) + 1
  If n Then Else Exit Function

  str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  For i = 0 To 127 Step 2
    b64(i \ 2) = str(i)
  Next

  ReDim str(0 To ((n + 2) \ 3) * 8 - 1)

  For i = LBound(data) To UBound(data) - (n Mod 3) Step 3
    v = data(i) * 65536 + data(i + 1) * 256& + data(i + 2)
    str(j) = b64(v \ 262144)
    str(j + 2) = b64((v \ 4096) Mod 64)
    str(j + 4) = b64((v \ 64) Mod 64)
    str(j + 6) = b64(v Mod 64)
    j = j + 8
  Next

  If n Mod 3 = 2 Then
    v = data(n - 2) * 256& + data(n - 1)
    str(j) = b64((v \ 1024&) Mod 64)
    str(j + 2) = b64((v \ 16) Mod 64)
    str(j + 4) = b64((v * 4) Mod 64)
    str(j + 6) = 61 ' = '
  ElseIf n Mod 3 = 1 Then
    v = data(n - 1)
    str(j) = b64(v \ 4 Mod 64)
    str(j + 2) = b64(v * 16 Mod 64)
    str(j + 4) = 61 ' = '
    str(j + 6) = 61 ' = '
  End If

  ToBase64 = str
End Function