Link to home
Start Free TrialLog in
Avatar of monkeybiz12345
monkeybiz12345

asked on

XML - syntax to reference all elements having matching values

Greetings Experts!

Working with vbscript and a limited (but growing, thanks to help received here!) knowledge of XML files, I'm trying to create a function that totals the quantities of materials issued to jobs by lot, bin, and serial number.  My XML file contains both material allocations (i.e. materials needed but not yet used) and material postings (i.e. specific information about materials that have been used).

In words, here’s what I’m trying to do:

For each material allocation, check to see whether the allocation has been completed. If it has not been completed, extract some information about the allocation from the XML and store it in a variable.  If it has been completed, look in the material postings and total up the quantities posted by lot, bin location, and serial number then store only those postings where the total quantity is not zero in the variable.

My latest attempt at this involved loading the material postings elements into an array and looping through that looking for lots that match the current lot and adding up the quantities. It kinda works but this will certainly take too long when my BOM has 500 items on it instead of 5 items.  Code shown here for context.


' create array of material postings
Dim arrMaterialPostings
arrMaterialPostings = BuildMaterialPostings(StockCodeSelection.CodeObject.Job)


Dim objDom, objAllocationsList, Counter, MyXML, objSerialNode, objBinNode, strBin, strSerial, EmptyXML
Dim objNodeList2, Counter2, strLot
Dim strStockCode, strAllocLine

 Set objDom = CreateObject("MSXML2.DOMDocument")
   
objDom.LoadXML(XMLOut)

 ' Look for all the MaterialAlloc elements
 Set objAllocationsList = objDom.SelectNodes ("//WipQuery/MaterialAlloc")

 MyXML = ""
 strBin = ""
 strSerial = ""
 strLot = ""

 If objAllocationsList.length > 0 then
    ' Loop through each of the MaterialAlloc elements

      For Counter = 0 To objAllocationsList.length - 1
          strLot = ""
          strSerial = ""
          strBin = ""

          strStockCode = objAllocationsList(Counter).SelectSingleNode("StockCode").Text
          strAllocLine = objAllocationsList(Counter).SelectSingleNode("Line").Text

          If objAllocationsList(Counter).SelectSingleNode("AllocCompleted").Text = "Y" Then
              ' material allocation has been completed. Look in the MaterialPostings nodes for
              ' the lot, bin, and serial.

              Dim MaxRows : MaxRows = Ubound(arrMaterialPostings, 2)

               dim LotQty, strLotSave, Counter3
               LotQty = 0

               For Counter2 = 0 to MaxRows
                  ' total the qty of materials issued by stock code, allocation line, and lot
                   If trim(arrMaterialPostings(0, Counter2)) = trim(strStockCode) And arrMaterialPostings(7, Counter2) = strAllocLine Then
                      ' we have a match on stock code and allocation line. Total up the qty of issues for each lot
                 
                       strLot = arrMaterialPostings(5, Counter2)
                        ' loop again
                        For Counter3 = 0 to MaxRows
                              If strLot = arrMaterialPostings(5, Counter3) Then
                                   LotQty = LotQty + arrMaterialPostings(2, Counter3)
                              
                                End If 
                         Next
               
                    End If 
               strLotSave = strLot
     Next    ' next material posting

        MyXML = MyXML & objAllocationsList(Counter).SelectSingleNode("StockCode").Text & Chr(255) &_
            objAllocationsList(Counter).SelectSingleNode("Rev").Text & Chr(255) &_
            strLot & Chr(255) &_
            strSerial & Chr(255) &_
            strLotQty & Chr(255) &_
            strBin & Chr(255) &_
            objAllocationsList(Counter).SelectSingleNode("Line").Text & Chr(255) &_
            objAllocationsList(Counter).SelectSingleNode("AllocCompleted").Text & vbCrLf

       Next
   End If

Open in new window



It seems like there must be a way to search only the data that meets a certain criteria and loop through that subset without looping through the entire list of material postings every time.  

I've attached a sample of the XML file data.  In the MaterialPostings nodes, you'll see three entries for stock code COMPONENT1.  Two of them, the ones for LOT100, total qty 0; the one for LOT400 totals qty 1.  I want to exclude LOT100, which totals to 0.

What is the syntax in vbscript to define “all the material postings elements where stock code = mystockcode and allocation line = myallocationline” ?  

Many thanks!
EE-2.XML
ASKER CERTIFIED SOLUTION
Avatar of Bill Prew
Bill Prew

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of monkeybiz12345
monkeybiz12345

ASKER

Thanks bp!  

Let's see if I can be a bit more clear...what I'm trying to do is get all of the material postings for each material allocation (found in the //Wip/MaterialPosting and //Wip/MaterialAlloc node lists respectively).  I'm going to display this data on screen in a list but I only want to see the material postings for the lots that were used on the job (i.e. the lots where the net quantity is a positive number).  A positive and negative quantity for a lot number indicates that the lot was issued but not used for some reason (un-issued and put back on the shelf).  

The value of mystockcode and myallocationline will come from the /MaterialAlloc/StockCode and /MaterialAlloc/Line elements. So, from the material allocation for COMPONENT1 from your screenshot above, mystockcode = COMPONENT1 and myallocationline = 00

The /MaterialPosting node list contains 3 postings for COMPONENT 1, line 00. They are:

LOT100    qty =  1
LOT100    qty =  -1
LOT400    qty =  1

From this list of material postings for COMPONENT1, line 00, I only want:
LOT400    qty = 1

I don't know which of the stock codes, if any,  may have had negative quantities issued so I have to check all the material postings for each allocation line.

Since the subset I want is in  /MaterialPosting It looks like I might be able to get what I need with this:

Set objMaterialPostingsForStockCodeList = objDom.SelectNodes ("//Wip/MaterialPosting[StockCode='COMPONENT1][AllocationLine='00']")

Will try this when back at the office tomorrow.


<edited to ensure that references to the XML here match the XML attached to the original question>
Well, instead of *headbreaking* reading the XML, what about transforming it to a csv file with the help of an xlst sheet ?
Next you'll be able to extract your desired data with an SQL query performed on the csv file.
The value of mystockcode and myallocationline will come from the /MaterialAllocations/StockCode and /MaterialAllocations/Line elements.
Trying to digest the latest author comments, but for the above sentence, I don't even see those nodes (with that exact name) in the sample XML?


»bp
This is what I was looking for.  It works just like I want it to.  Thanks for the help, bp!

Set objPostingsForStockCodeList = objDom.SelectNodes ("//Wip/MaterialPosting[StockCode='COMPONENT1][AllocationLine='00']")
You're right, bp.  My comment was confusing.  I've edited my comment so it hopefully won't confuse future readers.  Thanks for your help!
Thank you, Bill!