VBA code to decode Base64 Infopath attachment from a form. - InfoPath Dev
in

InfoPath Dev

Use our Google Custom Search for best site search results.

VBA code to decode Base64 Infopath attachment from a form.

Last post 09-06-2016 10:31 AM by Leandro Figueira. 2 replies.
Page 1 of 1 (3 items)
Sort Posts: Previous Next
  • 12-24-2008 01:51 AM

    • Skarn
    • Top 50 Contributor
      Male
    • Joined on 04-20-2008
    • Australia
    • Posts 198

    VBA code to decode Base64 Infopath attachment from a form.

    Hi,

    I have put together an example function which is VBA and I have used in my VBA applications. It seems to (I haven't done extensive testing) decode infopath attachment fields from an Infopath xml form successfully. I use Infopath 2003 and Microsoft Office 2003 Professional

     I don't use this code inside form templates themselves, I use in programs like Microsoft Access - but maybe with this you can adapt to your need.

    In Microsoft Access under the Visual Basic editor, I first had to go to Tools menu -> references and tick to add Microsoft XML v2.0 as a reference.

    Then make a new code module and paste the code into it in it's entirety

    Then use the extractAttachment(strFileName, strXPath, strOutputFolder) function to save a file which is the attachment from the Infopath form specified.

    You will need to specify the xPath to the field in strXPath.

    I have commented to the code as best I can to show understanding of what it is doing and how it works. I had to deduce the function by reading numerous posts around the net to try and work out a working method - all seemed to be in C or other languages and were outside my scope to use - but finally after much experimenting and inching closer and closer to the answer te below code is made. I learnt about byte arrays and binary file creation as well as getting access to the XML object model through VBA.

     I think this will be useful for many. Good luck!

    'Infopath file attachment extraction Module
    'by Ryan Marshall
    '
    'compiled from numerous web sources and trial and error to make a functional extraction routine.
    'Methods:
    '   extractAttachment(strFormFileName,strXPath,strOutputFolder)
    '   strFormFileName = filepath to form to extract attachment from
    '   strXPath = xPath expression to field which to extract attachment from (single Node only)
    '   strOutputFolder = folderpath to folder where to save extracted attachment to (with terminating "\")

    'Custom data types
    'for Byte array to Long (number) conversion
    Private Type LongByteType
        b1 As Byte
        b2 As Byte
        b3 As Byte
        b4 As Byte
    End Type

    Private Type LongType
        l As Long
    End Type

    Private LongRec As LongByteType
    Private MyLong As LongType
    Public Sub extractAttachment(strFileName, strXPath, strOutputFolder)
        Dim iFile As Integer                'binary file number index
        Dim oNode As IXMLDOMNode            'base64 data node from form field
        Dim nodeValue() As Byte             'full byte array of base64 data
        Dim fileContent() As Byte           'byte array of file data only
        Dim arrFileNameSize(4) As Byte      'byte array of file size only
        Dim arrFileName() As Byte           'byte array of filename only
        Dim arrFileData() As Byte
        Dim oDoc As DOMDocument             'XML document object to load form into
       
        'create XML document in memory
        Set oDoc = New DOMDocument
        'load form into XML document in memory
        If oDoc.Load(strFileName) = True Then
            If Not (oDoc Is Nothing) Then
                'read attachment node value to oNode object
                Set oNode = oDoc.documentElement.selectSingleNode(strXPath)
                'typecast the node to base64 as Infopath doesn't do this in node definition
                oNode.DataType = "bin.base64"
                'convert base64 node value to binary and store in nodeValue byte array
                nodeValue = oNode.nodeTypedValue
               
                'read filesize from byte position 20 (4 bytes) to byte array
                For i = 20 To 24
                    arrFileNameSize(i - 20) = nodeValue(i)
                Next
               
                'convert filesize byte array to actual file length (and multiply by 2 to get length in bytes)
                fileNameSize = ByteArraytoLong(arrFileNameSize) * 2
               
                'now we know how many bytes the filename is read in filename bytes in filename byte array
                '(filename starts at 24 and goes for filesize*2 bytes)
                ReDim arrFileName(fileNameSize - 1)
                For i = 24 To 23 + fileNameSize
                    arrFileName(i - 24) = nodeValue(i)
                Next
               
                'convert filename byte array to filename string (vba takes care of typecasting here)
                strFileName = Trim(arrFileName)
               
                'calculate filecontent byte length (equals full byte size of field - header data (default and filename))
                headerLength = 24 + fileNameSize
                fileDataLength = UBound(nodeValue) - headerLength
               
                'now make room in fileData byte array equal to this size
                ReDim arrFileData(fileDataLength)
                'store the byte data for the file in the fileData byte array
                For i = headerLength To UBound(nodeValue)
                    arrFileData(i - headerLength) = nodeValue(i)
                Next
               
                'open up output binary file
                iFile = FreeFile()
                strOutputFileName = strOutputFolder & strFileName
                Open strOutputFileName For Binary Access Write As iFile
               
                'output entire fileContent byte array to file
                Put iFile, , arrFileData
                Close iFile
            End If
        End If
    End Sub

    'Byte array to Long conversion function using custom Types
    Public Function ByteArraytoLong(pArray As Variant) As Long
        LongRec.b1 = pArray(0)
        LongRec.b2 = pArray(1)
        LongRec.b3 = pArray(2)
        LongRec.b4 = pArray(3)
       
        LSet MyLong = LongRec
       
        ByteArraytoLong = MyLong.l
    End Function

  • 01-26-2016 02:05 PM In reply to

    Re: VBA code to decode Base64 Infopath attachment from a form.

     Hello,

    I'm trying to extract attachments from InfoPath forms (xml files), base64 string and was trying to use this, but I'm not much of a coder so need some assistance if possible.  Does this work with Office 2013 dev tools (word)?  I tried using PowerShell but for some reason the decode isn't working so I found this code... thanks in advance.

  • 09-06-2016 10:31 AM In reply to

    Re: VBA code to decode Base64 Infopath attachment from a form.

    Please , you could decode a base64 file InfoPath XML form?
Page 1 of 1 (3 items)
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.