Question

Need help with VBA MSXML2 DOMDocument syntax to modify Infopath xml form root element data.

Asked by: benpope

Hello Experts,

From within an existing Access form  and using VBA, I need to be able to modify and save data in an Infopath xml form.  From what I have researched so far, I think I should be able to programmatically load an xml document and have the ability to read or modify any of the xml data components through the DOMdocument object.  I have be able to figure out how to load an existing xml document and save it under a different name thereby creating a new document.  But I have not been able to figure out how to modify the data contained in the loaded xml document's root element.  So far I have not found a good reference on the syntax to do that.  

In my test example, the Infopath xml document is linked to my Access back-end data tables and has four data fields.  They are Request (number), Description (text), Fab area, (text), and Accept (Boolean).  I want to load an existing Infopath xml form, modify it to contain the open Access form's data set, and then save the Infopath xml form with a new name.  Can someone tell me if this is possible or help with the syntax to do this?

Thanks, and please advise.
Ben

Private Sub btnCreateInfopathForm_Click()
Dim strNewFormName as string
strNewFormName = me.Request.value
Dim xmldoc As MSXML2.DOMDocument
Set xmldoc = New MSXML2.DOMDocument
xmldoc.Load ("C:\TEMP\infopath tests\Form1.xml") 'load an existing Infopath form linked to underlying Access DB 
 
'xmldoc. need syntax to manipulate xml document root element data to match currently open Access form fields
 
xmldoc.Save ("C:\TEMP\infopath tests\" & strNewFormName & ".xml") 'save modified file to known location
Set xmldoc = Nothing 'clear xmldoc parameters
end sub

                                  
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

Select allOpen in new window

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-08-21 at 06:16:18ID24671234
Tags

VBA

,

Access

,

Infopath

,

MSXML2

,

DOMDocument

Topics

Extensible Markup Language (XML)

,

Infopath

,

Access Coding/Macros

Participating Experts
1
Points
250
Comments
14

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. FreeThreadedDOMDocument vs. DOMDocument
    How would I know if I need to use FreeThreadedDOMDocument or DOMDocument? I know one needs to use FreeThreadedDOMDocument in a multi-threaded environment, but can someone give me examples to when to use each? I'm using VB6. Thanks.
  2. XML object creation and manipulation in VBA
    Hi, I am a newbie trying to create an process an XML in excel VBA. I would just be picking up values from cells and creating an XML. I tried googling/msdning to get a hold of the reference methods and how to use them. I found code snippets which use a DOM document to create ...
  3. How to parse an XML file using VBA
    Hi, I'm trying to load an Excel Worksheet with a bunch of info that resides in an xml file. the xml file is in the same path as the workbook and it's called "sample.xml". I haven't used any xml parser libraries in VBA so any help would be appreciated.
  4. How do I parse a values from a XML DOMDocument
    Greetings, I am working with Micrsoft Visual Basic for Applications (VBA) and calling a service that returns an XML document of type DOMDocument with the following schema: <Reply> <HRESULT></HRESULT> <STATUS></STATUS> <UserName>&...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: PhilAIPosted on 2009-08-21 at 22:31:19ID: 25157486

Here's a function to help you loop through the nodes within an XML.

You can update the text in a node by simply use the text property of a IXMLDOMNode object.

Let me know if you require further assistance.

Public Sub XMLTest()
 
Dim strNewFormName As String
strNewFormName = Me.Request.Value
 
Dim xmldoc As MSXML2.DOMDocument
Set xmldoc = New MSXML2.DOMDocument
Call xmldoc.Load("C:\Users\Phil Millington-Hore\Documents\Programming\Visual Basic\ADL\Golds\DelOptiChaR\XML\2002_01.xml")  'load an existing Infopath form linked to underlying Access DB
 
'xmldoc. need syntax to manipulate xml document root element data to match currently open Access form fields
Call XmlReader(xmldoc.DocumentElement)
 
If Len(Dir("C:\PhilAI\test.xml")) > 0 Then Call Kill("C:\PhilAI\test.xml")
Call xmldoc.Save("C:\PhilAI\test.xml")  'save modified file to known location
Set xmldoc = Nothing 'clear xmldoc parameters
 
End Sub
 
Public Function XmlReader(ByRef domRoot As Object) As Object
 
Dim currentNode As IXMLDOMNode
Dim rootNode As IXMLDOMNode
 
On Error GoTo ERR_HANDLER
 
If TypeOf domRoot Is IXMLDOMNode Then
    Set rootNode = domRoot
Else
    GoTo PROCEDURE_EXIT
End If
 
For Each currentNode In rootNode.ChildNodes
    Debug.Print currentNode.nodeName
    If currentNode.ChildNodes.Length > 0 Then
        Set XmlReader = XmlReader(currentNode)
    End If
Next
 
PROCEDURE_EXIT:
Set currentNode = Nothing
Set rootNode = Nothing
 
Exit Function
 
ERR_HANDLER:
Debug.Print "Error #" & Err.Number & ": " & Err.Description
Resume
Resume PROCEDURE_EXIT
 
End Function

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:

Select allOpen in new window

 

by: PhilAIPosted on 2009-08-21 at 22:33:05ID: 25157490

A few tweaks...

Option Explicit
 
Public Sub XMLTest()
 
Dim strNewFormName As String
strNewFormName = Me.Request.Value
 
Dim xmldoc As MSXML2.DOMDocument
Set xmldoc = New MSXML2.DOMDocument
Call xmldoc.Load("C:\Users\Phil Millington-Hore\Documents\Programming\Visual Basic\ADL\Golds\DelOptiChaR\XML\2002_01.xml")  'load an existing Infopath form linked to underlying Access DB
 
'xmldoc. need syntax to manipulate xml document root element data to match currently open Access form fields
Call XmlReader(xmldoc.DocumentElement)
 
If Len(Dir("C:\PhilAI\test.xml")) > 0 Then Call Kill("C:\PhilAI\test.xml")
Call xmldoc.Save("C:\PhilAI\test.xml")  'save modified file to known location
Set xmldoc = Nothing 'clear xmldoc parameters
 
End Sub
 
Public Sub XmlReader(ByRef domRoot As Object)
 
Dim currentNode As IXMLDOMNode
Dim rootNode As IXMLDOMNode
 
On Error GoTo ERR_HANDLER
 
If TypeOf domRoot Is IXMLDOMNode Then
    Set rootNode = domRoot
Else
    GoTo PROCEDURE_EXIT
End If
 
For Each currentNode In rootNode.ChildNodes
    Debug.Print currentNode.nodeName
    If currentNode.ChildNodes.Length > 0 Then
        Call XmlReader(currentNode)
    End If
Next
 
PROCEDURE_EXIT:
Set currentNode = Nothing
Set rootNode = Nothing
 
Exit Sub
 
ERR_HANDLER:
Debug.Print "Error #" & Err.Number & ": " & Err.Description
Resume PROCEDURE_EXIT
 
End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:

Select allOpen in new window

 

by: benpopePosted on 2009-08-24 at 06:26:05ID: 25168039

Thanks for the help PhilAI.

I give this a try as soon as I have some time.  It looks like it should do the trick. I still need to figure out exactly how to reset the XML file text field to match the current Access form field values.  Can you provide a sample of what that string would look like?  Once I have the XML doc loaded and have the nodes using XLMreader, how do get to the text property of a IXMLDOMNode obj and reset the value.  I'm thinking that I need to end up with somthing like "xmldoc.documentelements.something.somthing.node.text = me.AccessFormField.value" to call out the changes to each node's text in the XML file.

Cheers,
Ben



 

by: PhilAIPosted on 2009-08-24 at 06:37:04ID: 25168145

You could amend XmlReader to... see code attached

Without knowing exactly what your inputs and outputs are, I have provided a fairly generic example. You may be able to improve all this by using XPath and selecting a specific node:
http://msdn.microsoft.com/en-http://msdn.microsoft.com/en-us/library/microsoft.office.interop.infopath.semitrust.ixmldomnode.selectsinglenode.aspx

If you know the structure of the XML and exactly where the node is that you want to update, then using selectSingleNode would be much faster than looping through the entire XML (as my sample code does).

Public Sub UpdateInforpathXml(ByRef domRoot As Object)
 
Dim currentNode As IXMLDOMNode
Dim rootNode As IXMLDOMNode
 
On Error GoTo ERR_HANDLER
 
If TypeOf domRoot Is IXMLDOMNode Then
    Set rootNode = domRoot
Else
    GoTo PROCEDURE_EXIT
End If
 
For Each currentNode In rootNode.ChildNodes
    Select Case currentNode.nodeName
	Case "[AnXmlNodeName]"
		currentNode.text = Me.[AnAccessFormField].Value
	Case "[AnotherXmlNodeName]"
		currentNode.text = Me.[AnotherAccessFormField].Value
	End Select
 
    If currentNode.ChildNodes.Length > 0 Then
        Call UpdateInforpathXml(currentNode)
    End If
Next
 
PROCEDURE_EXIT:
Set currentNode = Nothing
Set rootNode = Nothing
 
Exit Sub
 
ERR_HANDLER:
Debug.Print "Error #" & Err.Number & ": " & Err.Description
Resume PROCEDURE_EXIT
 
End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:

Select allOpen in new window

 

by: benpopePosted on 2009-08-25 at 14:14:55ID: 25182338

I appreciate picking your brain PhilAI, I'm getting closer.

The troubel I'm having is that I can't grab the node level of data in an Infopath form that I am trying to get to.  Running the xmlReader routine results in;

dfs:queryFields
q:tblWrkRqst
dfs:dataFields
d:tblWrkRqstdfs:queryFields
q:tblWrkRqst
dfs:dataFields
d:tblWrkRqst
xdado:originalData
xml
s:Schema
s:ElementType
s:AttributeType
s:datatype
s:AttributeType
s:datatype
s:AttributeType
s:datatype
s:AttributeType
s:datatype
s:extends
rs:data
tblWrkRqst

I'm not getting down to the node level that actually has the data that needs to change.  I think this is because of the schema that Infopath uses to establish the data hierarchy.  Looking at the xml source code of my test Infopath form the schema looks different than the basic examples I've researched.  I'm guessing this is due to the Inforpath form being linked to an Access DB backend.  I can see the text data  in two places in the raw xml code.  I expect I would need to change this in both places before saving the modifed file.

I've attached the actual text xml code below for reference.

It looks to me like the actual text data is packaged under one child data node contained in a table in the Infopath form.  I like the xmldoc.selectSingleNode method, but can't get the sytax correct to access the specific data items I want to change.  Seems like if I can drill down to the correct named data element in the node that I should be able to change it.

Thanks, and please advise.
Ben
 

<?xml version="1.0" encoding="UTF-8"?><?mso-infoPathSolution solutionVersion="1.0.0.15" productVersion="12.0.0" PIVersion="1.0.0.0" href="file:///C:\Documents%20and%20Settings\qzsj4g\My%20Documents\test3.xsn" name="urn:schemas-microsoft-com:office:infopath:test3:-dataFormSolution" initialView="View 1" ?><?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?><dfs:myFields xmlns:q="http://schemas.microsoft.com/office/infopath/2003/ado/queryFields" xmlns:d="http://schemas.microsoft.com/office/infopath/2003/ado/dataFields" xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-08-17T16:50:44" xmlns:xdado="http://schemas.microsoft.com/office/infopath/2003/adomapping" xml:lang="en-us">
<dfs:dataFields>
<d:tblWrkRqst request="3" description="testing" fab_area="jobshop" accept="False" xdado:OEltUe="0"/>
</dfs:dataFields>
<xdado:originalData IdCount="1"><xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"><s:Schema id="RowsetSchema"><s:ElementType content="eltOnly" rs:updatable="true" name="tblWrkRqst"><s:AttributeType rs:number="1" rs:maydefer="true" rs:writeunknown="true" rs:basetable="tblWrkRqst" rs:basecolumn="request" rs:keycolumn="true" rs:autoincrement="true" name="request"><s:datatype dt:type="int" dt:maxLength="4" rs:precision="10" rs:fixedlength="true"/></s:AttributeType><s:AttributeType rs:number="2" rs:nullable="true" rs:maydefer="true" rs:writeunknown="true" rs:basetable="tblWrkRqst" rs:basecolumn="description" name="description"><s:datatype dt:type="string" dt:maxLength="50"/></s:AttributeType><s:AttributeType rs:number="3" rs:nullable="true" rs:maydefer="true" rs:writeunknown="true" rs:basetable="tblWrkRqst" rs:basecolumn="fab area" name="fab_area"><s:datatype dt:type="string" dt:maxLength="50"/></s:AttributeType><s:AttributeType rs:number="4" rs:maydefer="true" rs:writeunknown="true" rs:basetable="tblWrkRqst" rs:basecolumn="accept" name="accept"><s:datatype dt:type="boolean" dt:maxLength="2" rs:fixedlength="true"/></s:AttributeType><s:extends type="rs:rowbase"/></s:ElementType></s:Schema><rs:data><tblWrkRqst request="3" description="testing" fab_area="jobshop" accept="False" xdado:OEltUe="0"/></rs:data></xml></xdado:originalData></dfs:myFields>
                                              
1:
2:
3:
4:
5:

Select allOpen in new window

 

by: PhilAIPosted on 2009-08-25 at 22:18:38ID: 25184594

Tell me exactly what you want to change. The code I gave you only traverses the nodes and not the attributes. To do that you can use the following...

As for using selectSingleNode, it needs to be the path to the node, and then you can access the attribute from that node. So, for example...
xmldoc.documentElement.selectSingleNode("/dfs:myFields/xdado:originalData/xml/s:Schema")
...will get you the node of the <s:Schema id="RowsetSchema">

This should help you figure it out.

Option Explicit
 
Public Sub XMLTest()
 
Dim strNewFormName As String
'strNewFormName = Me.Request.Value
 
Dim xmldoc As MSXML2.DOMDocument
Set xmldoc = New MSXML2.DOMDocument
Call xmldoc.Load("C:\Users\Phil Millington-Hore\Documents\Programming\Visual Basic\ADL\Golds\DelOptiChaR\XML\2002_01.xml")  'load an existing Infopath form linked to underlying Access DB
 
'xmldoc. need syntax to manipulate xml document root element data to match currently open Access form fields
Call XmlReader(xmldoc.DocumentElement)
 
If Len(Dir("C:\PhilAI\test.xml")) > 0 Then Call Kill("C:\PhilAI\test.xml")
Call xmldoc.Save("C:\PhilAI\test.xml")  'save modified file to known location
Set xmldoc = Nothing 'clear xmldoc parameters
 
End Sub
 
Public Sub XmlReader(ByRef domRoot As Object)
 
Dim I As Integer
Dim currentAttribute As IXMLDOMNode
Dim currentNode As IXMLDOMNode
Dim rootNode As IXMLDOMNode
 
On Error GoTo ERR_HANDLER
 
If TypeOf domRoot Is IXMLDOMNode Then
    Set rootNode = domRoot
Else
    GoTo PROCEDURE_EXIT
End If
 
For Each currentNode In rootNode.ChildNodes
    Debug.Print currentNode.nodeName
    If Not currentNode.Attributes Is Nothing Then
        If currentNode.Attributes.Length > 0 Then
            For I = 0 To currentNode.Attributes.Length - 1
                Set currentAttribute = currentNode.Attributes.Item(I)
                Debug.Print currentAttribute.nodeName
            Next
        End If
    End If
    
    If currentNode.ChildNodes.Length > 0 Then
        Call XmlReader(currentNode)
    End If
Next
 
PROCEDURE_EXIT:
Set currentAttribute = Nothing
Set currentNode = Nothing
Set rootNode = Nothing
 
Exit Sub
 
ERR_HANDLER:
Debug.Print "Error #" & Err.Number & ": " & Err.Description
Resume PROCEDURE_EXIT
 
End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:

Select allOpen in new window

 

by: benpopePosted on 2009-08-26 at 09:30:12ID: 25189557

OK PhilAI, with your help I did find a solution that does work.

The whole trouble was that I needed to get down to and be able to manipulate the attribute level of where the text data was stored in the Infopath XML code.  I liked the selectsinglenode method as it should execute faster than a loop through case method, but I could not get that to work.  Probably would, but I never did get the syntax fully figured out.  For the selectsinglenode method I found out that I needed to declare all the associated namespaces.  I did that and still could not grab the final attribute that I was looking for as Access kept returning an object error.

The loop though method was easier to coded and does work.  I used a combination of your suggestions to get to the attribute level and added a couple of bits to the select case and to handle a boolean value in a checkbox.  Now I can load a base Infopath form in the background from Access, change the data to the current Access form data, automatically save and publish the Infopath form to Sharepoint, automatically start the Sharepoint workflow, and use the Infopath form with workflow to collect data in the Access backend datatables.   This has a lot of potential to automate and help several of our current business processes.  Now that I have proven out that it works, I can start to develop the actual applications and forms.

The working solution is below.

Cheers,
Ben

Private Sub btnInfopathForm_Click()
Dim strFormName As String
Dim strWorkRequest As String
strWorkRequest = Me.Request.value
strFormName = "Work Request" & "-" & strWorkRequest 'Define new form name
Dim objIP As Object
 
Set objIP = CreateObject("InfoPath.Application")
Dim xmldoc As MSXML2.DOMDocument
Set xmldoc = New MSXML2.DOMDocument
xmldoc.Load ("C:\TEMP\infopath tests\WRtest1.xml") 'load base form
Call UpdateInfoPathXml(xmldoc.documentElement) 'modify base form attribute data to match open form data
xmldoc.Save ("C:\TEMP\infopath tests\" & strFormName & ".xml") 'save modified xml file to known location
Set xmldoc = Nothing 'clear xmldoc parameters
End Sub
 
Public Sub UpdateInfoPathXml(ByRef domRoot As Object)
Dim currentNode As IXMLDOMNode
Dim rootNode As IXMLDOMNode
On Error GoTo ERR_HANDLER
 
If TypeOf domRoot Is IXMLDOMNode Then
    Set rootNode = domRoot
Else
    GoTo PROCEDURE_EXIT
End If
 
Dim varNodeName
For Each currentNode In rootNode.childNodes
If Not currentNode.Attributes Is Nothing Then
        If currentNode.Attributes.length > 0 Then
            For I = 0 To currentNode.Attributes.length - 1
                Set currentAttribute = currentNode.Attributes.Item(I)
                varNodeName = currentAttribute.nodeName
                Select Case varNodeName
                Case "request"
                    currentAttribute.Text = Me.[Request].value
                Case "description"
                    currentAttribute.Text = Me.[description].value
                Case "accept" 'boolean value
                    If Me.[Accept].value = 0 Then
                        currentAttribute.Text = "False"
                        Else
                        currentAttribute.Text = "True"
                    End If
                Case "fab_Area"
                    currentAttribute.Text = Me.[fab_area].value
                End Select
                Next
            End If
        End If
     If currentNode.childNodes.length > 0 Then
        Call UpdateInfoPathXml(currentNode)
    End If
Next
 
PROCEDURE_EXIT:
Set currentAttribute = Nothing
Set currentNode = Nothing
Set rootNode = Nothing
 
Exit Sub
 
ERR_HANDLER:
Debug.Print "Error #" & Err.Number & ": " & Err.description
Resume PROCEDURE_EXIT
 
End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:

Select allOpen in new window

 

by: PhilAIPosted on 2009-08-26 at 10:54:23ID: 25190346

I am surprised you could not get the XPath to work as I tested the example I posted above with your XML file: xmldoc.documentElement.selectSingleNode("/dfs:myFields/xdado:originalData/xml/s:Schema")

Glad I helped you find your answer, and I think you should try and get the selectSingleNode technique to work. If I wasn't losing my Internet tonight due to moving house then I would help you out, but I don't come back online for at least 2 weeks :o(

 

by: benpopePosted on 2009-08-26 at 11:31:50ID: 31618820

Thanks agian for help PhilAI,
Bummer on the Internet, I'd be in withdrawal.  I'm sure that the selectsinglenode would work with the right declarations and syntax to get down to the appropriate elements.  But I'm still learning how the whole xml hierarchy and Xpath structure works.  In the meantime, the loop through method seems to do just fine.  That will get me going.  

I'll indicate two of the soutions you offered as accepted to close out this question.  Combined they were a workable solution.
Cheers,
Ben

 

by: PhilAIPosted on 2009-09-01 at 00:22:34ID: 25229183

Try this out...

Option Explicit
 
Public Sub btnInfopathForm_Click()
 
'Dim objIP As Object
Dim strFormName As String
Dim strWorkRequest As String
 
strWorkRequest = Me.Request.Value
strFormName = "Work Request" & "-" & strWorkRequest 'Define new form name
 
'Set objIP = CreateObject("InfoPath.Application")
Dim xmldoc As MSXML2.DOMDocument
Set xmldoc = New MSXML2.DOMDocument
 
Call xmldoc.Load("C:\TEMP\infopath tests\WRtest1.xml")  'load base form
'Call UpdateInfoPathXml(xmldoc.DocumentElement) 'modify base form attribute data to match open form data
Call UpdateWorkRequest(xmldoc) 'modify base form attribute data to match open form data
Call xmldoc.Save("C:\TEMP\infopath tests\" & strFormName & ".xml")  'save modified xml file to known location
 
Set xmldoc = Nothing 'clear xmldoc parameters
'Set objIP = Nothing
 
End Sub
 
Public Sub UpdateWorkRequest(ByRef domRoot As Object)
 
Dim currentAttribute As IXMLDOMNode
Dim currentNode As IXMLDOMNode
 
With domRoot.DocumentElement
    ' Request
    Set currentNode = .SelectSingleNode("/dfs:myFields/dfs:dataFields/d:tblWrkRqst")
    Set currentAttribute = currentNode.Attributes.getNamedItem("request")
    currentAttribute.text = Me.[Request].Value
    Set currentNode = .SelectSingleNode("/dfs:myFields/xdado:originalData/xml/rs:data/tblWrkRqst")
    Set currentAttribute = currentNode.Attributes.getNamedItem("request")
    currentAttribute.text = Me.[Request].Value
    ' Description
    Set currentNode = .SelectSingleNode("/dfs:myFields/dfs:dataFields/d:tblWrkRqst")
    Set currentAttribute = currentNode.Attributes.getNamedItem("description")
    currentAttribute.text = Me.[Description].Value
    Set currentNode = .SelectSingleNode("/dfs:myFields/xdado:originalData/xml/rs:data/tblWrkRqst")
    Set currentAttribute = currentNode.Attributes.getNamedItem("description")
    currentAttribute.text = Me.[Description].Value
    ' Accept
    Set currentNode = .SelectSingleNode("/dfs:myFields/dfs:dataFields/d:tblWrkRqst")
    Set currentAttribute = currentNode.Attributes.getNamedItem("accept")
    currentAttribute.text = CStr(CBool(Me.[Accept].Value))
    Set currentNode = .SelectSingleNode("/dfs:myFields/xdado:originalData/xml/rs:data/tblWrkRqst")
    Set currentAttribute = currentNode.Attributes.getNamedItem("accept")
    currentAttribute.text = CStr(CBool(Me.[Accept].Value))
    ' FAB area
    Set currentNode = .SelectSingleNode("/dfs:myFields/dfs:dataFields/d:tblWrkRqst")
    Set currentAttribute = currentNode.Attributes.getNamedItem("fab_area")
    currentAttribute.text = Me.[fab_area].Value
    Set currentNode = .SelectSingleNode("/dfs:myFields/xdado:originalData/xml/rs:data/tblWrkRqst")
    Set currentAttribute = currentNode.Attributes.getNamedItem("fab_area")
    currentAttribute.text = Me.[fab_area].Value
End With
 
Set currentAttribute = Nothing
Set currentNode = Nothing
 
End Sub
 
 
Public Sub UpdateInfoPathXml(ByRef domRoot As Object)
 
Dim rootNode As IXMLDOMNode
On Error GoTo ERR_HANDLER
 
If TypeOf domRoot Is IXMLDOMNode Then
    Set rootNode = domRoot
Else
    GoTo PROCEDURE_EXIT
End If
 
Dim varNodeName
For Each currentNode In rootNode.ChildNodes
If Not currentNode.Attributes Is Nothing Then
        If currentNode.Attributes.Length > 0 Then
            For I = 0 To currentNode.Attributes.Length - 1
                Set currentAttribute = currentNode.Attributes.Item(I)
                varNodeName = currentAttribute.nodeName
                Select Case varNodeName
                Case "request"
                    currentAttribute.text = Me.[Request].Value
                Case "description"
                    currentAttribute.text = Me.[Description].Value
                Case "accept" 'boolean value
                    If Me.[Accept].Value = 0 Then
                        currentAttribute.text = "False"
                        Else
                        currentAttribute.text = "True"
                    End If
                Case "fab_Area"
                    currentAttribute.text = Me.[fab_area].Value
                End Select
                Next
            End If
        End If
     If currentNode.ChildNodes.Length > 0 Then
        Call UpdateInfoPathXml(currentNode)
    End If
Next
 
PROCEDURE_EXIT:
Set currentAttribute = Nothing
Set currentNode = Nothing
Set rootNode = Nothing
 
Exit Sub
 
ERR_HANDLER:
Debug.Print "Error #" & Err.Number & ": " & Err.Description
Resume PROCEDURE_EXIT
 
End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:

Select allOpen in new window

 

by: benpopePosted on 2009-09-01 at 12:19:10ID: 25234951

Thanks for the follow-up code suggestion PhilAI.  I want to try this out as soon as I have chance.  However, it will have to wait a few days as my developmental priorities have been rearranged for me by my managers.  But It does look like a more efficient method that I will have to try.

Cheers,
Ben

 

by: benpopePosted on 2009-09-09 at 12:11:43ID: 25294519

PhilIA, your select single node solution is more efficient and does work.  I did have to modify the above code as noted below for to fully specify the tree to the desired data node.  One small typo to correct for those that read this thread later and need to know the syntax.  Had to add the missing "d:".  I think you were just testing me, but it is forcing me to learn this XML stuff.  I think I understand how the XML tree works much better now.

Replaced in all occurrences:
Set currentNode = .SelectSingleNode("/dfs:myFields/xdado:originalData/xml/rs:data/tblWrkRqst")
with
Set currentNode = .SelectSingleNode("/dfs:myFields/xdado:originalData/xml/rs:data/d:tblWrkRqst")

Thanks for the assistance.
Ben

 

by: benpopePosted on 2009-09-09 at 13:00:47ID: 25294982

Still learning PhilAI,
The above code ammendments are needed only if I'm modifying a form's data that is only based on data fields.  If I have query fields included as in my original sample, the corrent syntax is as your code provided above.   I can see the differences and how to get into the XML tree structure this by looking directly at the XML source code.

Cheers,
Ben

 

by: benpopePosted on 2009-09-10 at 04:17:29ID: 25299058

PhilAI,

I thought about this some more and came up with a final simpler solution based on your selectsinglenode  method to accomplish the objective.  I only really need to set the Infopath forms' query field (one node) to make this work.

To make a new Infopath form from an open Access form.
1:  Create an Infopath template with the data connection data fields back to the Access database.  To make an Infopath form that you can submit, it must be based on table not a querry.   Make the Infopath form run the query action on open based on the data's primary key,
2: Make and save a base Infopath form from the Infopath template.
3: Use xlmdoc from Access VBA to open and modify the base Infopath form's primary key look-up data, then save the form to a new name.
4: When the new infopath form is opened, it automatically runs the query action and fills in any other fields tied to the access data.

Thanks again for the help,
Ben

Private Sub btnCreateInfopathForm_Click()
Dim strFormName As String
Dim strWorkRequest As String
strWorkRequest = Me.Request.value
strFormName = "Work Request" & "-" & strWorkRequest 'Define new form name
Dim xmldoc As MSXML2.DOMDocument
Set xmldoc = New MSXML2.DOMDocument
xmldoc.Load ("C:\infopath tests\BaseTemplate.xml") 'load base form
Call CreateInfopathWorkRequest(xmldoc) 'modify base form attribute data to match open form data
xmldoc.Save ("C:\infopath tests\" & strFormName & ".xml") 'save modified xml file to known location
Set xmldoc = Nothing 'clear xmldoc parameters
End Sub
 
Private Sub CreateInfopathWorkRequest(ByRef domRoot As Object)
Dim currentattribute As IXMLDOMNode
Dim currentNode As IXMLDOMNode
With domRoot.documentElement
    '  set Request Number as the querry field to reference when Infopath opens automatically queries data connection
    Set currentNode = .selectSingleNode("/dfs:myFields/dfs:queryFields/q:tblWorkRequest")
    Set currentattribute = currentNode.Attributes.getNamedItem("Request")
    currentattribute.Text = Me.[Request].value
End With
Set currentattribute = Nothing
Set currentNode = Nothing
 
End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:

Select allOpen in new window

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...