Populate Data Fields in table based on drop-down selection - InfoPath Dev
in

InfoPath Dev

Populate Data Fields in table based on drop-down selection

Last post 10-30-2014 03:15 PM by Hilary Stoupa. 12 replies.
Page 1 of 1 (13 items)
Sort Posts: Previous Next
  • 10-16-2014 07:02 AM

    Populate Data Fields in table based on drop-down selection

    Good Morning,

    I am creating an InfoPath form for my supervisors to submit their direct reports' production and hours on a weekly basis. It seems so simple but I have tried now for 2 weeks to find a codeless solution and cannot seem to find any detailed instructions on how to make my form work. 

    I have approximately 30 work units/departments.  I want each supervisor to be able to pull up the form, select their department code from a drop-down list, click a button ("Populate Unit"), and based on that selection in the drop-down field (my:selectedUnit)  each employee name within that department(along with other information) will appear in data fields within a repeating table. There will be other data fields next to their names so the supervisor can input the weekly production number and work hours for each employee. Once they fill it out they will submit the form to the main data source, an access table, "Weekly_Hours". The drop-down list items and employee information are retrieved from a secondary data source: an access table, "Workforce Details".   

    After trying for days I found some code that Hillary Stoupa posted a few years ago titled "How Do I Copy Repeating Data From an External Source into My Form?" and gave it a try but it didn't work so I exported my secondary source from a table to an XML ("Workforce") so it could mirror Hillary's example. SO CLOSE but there was one error that I am praying you can help me fix. I receive a *NullReferenceException error was unhandled by user code* error. Object reference not set to an instance of an object.
    Tips given:
    Use the "new" keyword to create an object instance (you may have tried to use an object without using the New keyword first, or tried to use an object whose value is set to null).
    Check to determine if the object is null before calling the method.

    I am using Infopath 2010. Should my code change somewhat since she used a different year? I tried to provide as much information below as I could :-?  Thank you for any help you can provide. This project deadline is quickly approaching.

    Schema

    MAIN

    myFields

       queryFields

       dataFields

           d:Weekly_Hours

       my:selectedUnit

    XML clip

    <?xml version="1.0" encoding="UTF-8" ?>

    - <Workforce>
    - <Workforce_x0020_Details>
    <ID>AAA111</ID>
    <Unit>MU</Unit>
    <L_x0020_Name>Stackhouse</L_x0020_Name>
    <F_x0020_Name>Sookie</F_x0020_Name>
    <Position>IN</Position>
    <Supervisor>A SMITH</Supervisor>
    <Loc>BonTemps</Loc>
    <Status>PT</Status>
    </Workforce_x0020_Details>
     
    UNDERLINED CODE IS WHERE NULL REFERENCE EXCEPTION ERROR IS POINTING TO
     

    using Microsoft.Office.InfoPath;
    using System;
    using System.Windows.Forms;
    using System.Xml;
    using System.Xml.XPath;
    using mshtml;

    namespace test
    {
        public partial class FormCode
        {
            // Member variables are not supported in browser-enabled forms.
            // Instead, write and read these values from the FormState
            // dictionary using code such as the following:
            //
            // private object _memberVariable
            // {
            //     get
            //     {
            //         return FormState["_memberVariable"];
            //     }
            //     set
            //     {
            //         FormState["_memberVariable"] = value;
            //     }
            // }

            // NOTE: The following procedure is required by Microsoft InfoPath.
            // It can be modified using Microsoft InfoPath.
            public void InternalStartup()
            {
                ((ButtonEvent)EventManager.ControlEvents["cmdPopulateUnit"]).Clicked += new ClickedEventHandler(cmdPopulateUnit_Clicked);
            }

            public void cmdPopulateUnit_Clicked(object sender, ClickedEventArgs e)
            {
                // Get the selected unit.
                string selectedUnit = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:selectedUnit", NamespaceManager).Value;

                // If no Unit was selected notify the user.
                if (selectedUnit.Equals(""))
                {
                    MessageBox.Show("Please select a Unit first.");
                    return;
                }

                // Get the list of workers per the selected unit.
                XPathNodeIterator Workforce = this.DataSources["Workforce"].CreateNavigator().Select("/Workforce/Workforce_x0020_Details[Unit = '" + selectedUnit + "']", NamespaceManager);

                // If nothing was found, then return; there will be no items to insert.
                if (Workforce.Count == 0)
                {
                    return;
                }

                //Get the worker insertion point.
                XPathNavigator workforceList = MainDataSource.CreateNavigator().SelectSingleNode("/dfs:myFields/dfs:dataFields/d:Weekly_Hours", NamespaceManager);

                //Add the rows to the main DOM.
                foreach (XPathNavigator Workforce_x0020_Details in Workforce)
                {
                    try
                    {
                        // Get this unit's values from the secondary DOM.
                        string lastname = Workforce_x0020_Details.SelectSingleNode("L_x0020_Name", NamespaceManager).Value;
                        string firstname = Workforce_x0020_Details.SelectSingleNode("F_x0020_Name", NamespaceManager).Value;
                        string position = Workforce_x0020_Details.SelectSingleNode("Position", NamespaceManager).Value;
                        string status = Workforce_x0020_Details.SelectSingleNode("Status", NamespaceManager).Value;

                        // Build a string representing a main DOM vehicle nodeset using the values from the secondary DOM.
                        string workforceXml = "<d:Weekly_Hours xmlns:my='http://schemas.microsoft.com/office/infopath/2003/ado/dataFields'>"
                                        + "<my:Last_Name>" + lastname + "</@Last_Name>"
                                        + "<my:First_Name>" + firstname + "</@First_Name>"
                                        + "<my:Position>" + position + "</@Position>"
                                        + "<my:Status>" + status + "</@Status>";


                        //Load new workforce string into a temporary XML document
                        XmlDocument tempDoc = new XmlDocument();
                        tempDoc.LoadXml(workforceXml);

                        // Insert the new record into the main DOM.
                        XPathNavigator newWorker = tempDoc.CreateNavigator().SelectSingleNode("d:Weekly_Hours", NamespaceManager);
                        workforceList.AppendChild(newWorker);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Could not insert other individual.\n\nError message:\n" + ex.Message);
                    }
                }
            }
        }
    } 

  • 10-28-2014 07:18 AM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    Good Morning,

    I really need help with this issue.  I still have not been able to locate a solution to my problem.  I think maybe I gave too much information and scared off any possible respondants.  Bottom line is that I need to create a drop down field and based on that selection, some data fields to my main source will be populated with information from my secondary source.  The user will input the remaining.  I used some code from Hillary and now I am getting a error: *NullReferenceException error was unhandled by user code* error. Object reference not set to an instance of an object.  Here is the code that the error is pointing to

    string selectedUnit = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:selectedUnit", NamespaceManager).Value;

    I would be truly, truly grateful for any quick assistance.  Thank you in advance. 

  • 10-28-2014 07:24 AM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    Generally, this would be because the XPath is incorrect. Did you right click selectedUnit in the data source task pane and select Copy XPath to make sure it was right?

    Hilary Stoupa

  • 10-28-2014 09:46 AM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    You were correct XPath should have been ("/dfs:myFields/my:selectedUnit"  This update got rid of the error.  Thank you so much! 

    Now during debugging I received a dialog button with the catch exception message "Could not insert other individual--Error message: 'd' is an undeclared namespace. Line 1, position 2.  Based on what you just said.  Could it be that when I am building my main DOM nodeset I dididn't list the entire XPath there either.  I put..

    string workforceXml ="<d:Weekly_Hours xmlns:my='http://schemas.microsoft.com/office/infopath/2003/ado/dataFields'>"

    The XPath for the Weekly_Hours section is /dfs:myFields/dfs:dataFields/d:Weekly_Hours. Do I need to list the entire XPath instead?

                                        

  • 10-28-2014 11:28 AM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    Ok. I am slowly walking this down and it occurred to me that I should change the xmlns:my='http://schemas.microsoft....... to    xmlns:d='http://......  I did that as well changed this section to look like this (see below).  Did I just make is worse? I changed the "my:" s to "d:" s.   The error I am now getting is Unexpected end of file has occurred. The following elements are not closed: d:Weekly_Hours. Line 1, position 207. I'm so lost.

    // Build a string representing a main DOM workforce nodeset using the values from the secondary DOM.

    string workforceXml = "<d:Weekly_Hours xmlns:d='http://schemas.microsoft.com/office/infopath/2003/ado/dataFields'>"

    + "<d:Last_Name>" + lastname + "</d:Last_Name>"

    +"<d:First_Name>" + firstname + "</d:First_Name>"

    +"<d:Position>" + position + "</d:Position>"                           

    +"<d:Status>" + position + "</d:Status>";

     

  • 10-28-2014 12:03 PM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    Are you trying to add a row to the main data source? Or to the secondary data source?

    Hilary Stoupa

  • 10-28-2014 02:57 PM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    Adding rows to the main source.  User selects department or unit number from the drop-down list (selectedUnit), clicks a button and all members in the unit are listed in the main sources data fields (unit #, last name, first name, position, and status) the other data fields are hrs worked, OT hrs, etc that are filled in by the user.  When user is finished they click submit and each row transmits to an access table(main source).

  • 10-28-2014 03:00 PM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    I think the issue is here:

    string workforceXml = "<d:Weekly_Hours xmlns:my='http://schemas.microsoft.com/office/infopath/2003/ado/dataFields'>"

    Is d:Weekly_Hours in your main data source?

    Hilary Stoupa

  • 10-28-2014 03:02 PM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    Sorry, I just really read this now. :)

    You need to add a closing </d:Weekly_Hours>

    So, after </d:Status> we'd need to add a </d:Weekly_Hours>

    Hilary Stoupa

  • 10-29-2014 11:14 AM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    Thank you! This worked.

    However I, of course, did receive other errors but I was able to figure them out. There is one new error that I am having trouble finding a solution to.  I am trying to talk out each line of code to figure out just what is trying to be accomplished. In your example I believe you were allowing the user to add a new vehicle to the "Sport's Car" category if they wanted to.  Since I only want the user to select their unit and have only their current unit members (and not add a new employee) populate the data fields with some info while they input other fields (hrs worked), do I need this line of code that you used?

    //Load new workforce string into a temporary XML document
    XmlDocument tempDoc = new XmlDocument();
    tempDoc.LoadXml(workforceXml);

    // Insert the new worker record into the main DOM.
    XPathNavigator newWorker = tempDoc.CreateNavigator().SelectSingleNode("/dfs:myFields/dfs:dataFields/d:Weekly_Hours", NamespaceManager);
    workforceList.AppendChild(newWorker);

    You can tell during debugging that it is trying to append all members of the unit but it keeps showing the error message "Value cannot be null Parameter name: newChild". The number of error msg boxes = number of members in the selected Unit. If I need it how can I adjust these lines of code to work correctly?  Thank you again for your endurance and willingness to work with me.

  • 10-29-2014 02:33 PM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    So - newWorker is not null? The error message makes it sound like it is. Isn't your new XML just "d:Weekly_Hours"? If you run the code in debug and check the outer XML for tempDoc after loading it, what is the outer XML?

    Hilary Stoupa

  • 10-30-2014 03:01 PM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    newWorker must be null. I'm sorry please forgive me.  I am a little lost by your references.  When you say my new XML are you referring to my Repeating group (d:Weekly_Hours) in my Main source because this iswhere the repeating table (with secondary info) will appear.  When you said XML before I thought you were speaking of my secondary source which happens to be an xml file. How do I check or where do I look for the outer XML for tempDoc? I am so sorry as you can tell I am a bit of a novice and still learning certain programming terms. Do I need to define newWorker somewhere in the code? 

  • 10-30-2014 03:15 PM In reply to

    Re: Populate Data Fields in table based on drop-down selection

    The code sample you posted:

    //Load new workforce string into a temporary XML document
    XmlDocument tempDoc = new XmlDocument();
    tempDoc.LoadXml(workforceXml);

    // Insert the new worker record into the main DOM.
    XPathNavigator newWorker = tempDoc.CreateNavigator().SelectSingleNode("/dfs:myFields/dfs:dataFields/d:Weekly_Hours", NamespaceManager);
    workforceList.AppendChild(newWorker);

    I'm saying the newWorker variable in the last line of code must be null to throw that error. When I say your new XML, I mean the tempDoc variable in your code. Do you know how to run your code in debug? http://www.infopathdev.com/blogs/hilary/archive/2009/09/27/debug-managed-code-in-vsta-for-the-accidental-programmer.aspx

    Hilary Stoupa

Page 1 of 1 (13 items)
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.