4 Replies Latest reply on Feb 9, 2016 11:55 AM by Joe Walton

    How to read items from a material database?

    Andreas Killer

      I'm developing a macro to create SLDLFP files from our component list (in Excel).

       

      Creating the SLDLFP files, edit the sketch, set new dimension values, etc. is no problem, but the material part is not nice.

       

      In our custom SW material database we have many materials with extended names, so I have e.g. to use this to set the material properly:

       

      Set swApp = Application.SldWorks

      Set swPart = swApp.ActiveDoc

      swPart.SetMaterialPropertyName2 "Standard", "K:/Software/Solidworks/Vorlagen/Materialien.sldmat", "1.4404 (X2CrNiMo17-12-2)"

       

      In our Excel list only the part "1.4404" is available, but SetMaterialPropertyName2 needs the extended name.

       

      I've seen that I can get the material databases with swApp.GetMaterialDatabases

       

      I wonder if there is a way to read all materials (items) from a database (into a collection or Array)?

       

      Then I could search for the material from our Excel file in all items and get the extended Name.

       

      Regards, Andreas.

        • Re: How to read items from a material database?
          Swapnil Dhake

          Hi Andreas,

           

          I could not understand your issue. But if you just wish to see the material database in excel, you can simply drag it in excel.

          (Excel puts all properties column wise)

            • Re: How to read items from a material database?
              Andreas Killer

              The issue is that this doesn't work:

              swPart.SetMaterialPropertyName2 "Standard", "K:/Software/Solidworks/Vorlagen/Materialien.sldmat", "1.4404"

              swPart.SetMaterialPropertyName2 "Standard", "K:/Software/Solidworks/Vorlagen/Materialien.sldmat", "3.0505"

               

              I must use this:

              swPart.SetMaterialPropertyName2 "Standard", "K:/Software/Solidworks/Vorlagen/Materialien.sldmat", "1.4404 (X2CrNiMo17-12-2)"

               

              Or I have to use this:

              swPart.SetMaterialPropertyName2 "Standard", "C:/Program Files/SolidWorks Corp/SOLIDWORKS (2)/lang/german/sldmaterials/SolidWorks DIN Materials.sldmat", "3.0505 (EN-AW 3105)"

               

              I don't want to copy/drag/open all the SW material databases into Excel first.

              I want to search for "1.4404" resp. "3.0505" in the SW material databases with a macro.

               

              Andreas.

            • Re: How to read items from a material database?
              Joe Walton

              Andreas Killer,

                   I have just gone through this last week.  Took me a day and a half to get it correct.  From everything I've read the material database is an XML file and you need to parse it as such.  Lots of people said it couldn't be done, but I kept digging and it works for me.  Here is what I have, hope it helps you.  My code is in VBA.

               

                   Here is what my material database looks like: (copy your material database and rename it from .sldmat to .xml)

               

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

              -<mstns:materials version="2008.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sldcolorswatch="http://www.solidworks.com/sldcolorswatch" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:mstns="http://www.solidworks.com/sldmaterials">

              -<curves id="curve0">

                   <point y="1.0" x="1.0"/>

                   <point y="1.0" x="2.0"/>

                   <point y="1.0" x="3.0"/>

              </curves>

              -<classification name="ALUMINUM">

                   -<material name="0.012 ALUMINUM">

                        -<shaders>

                        ...

                        -<swatchcolor RGB="6d757e">

                        ...

                        -<physicalproperties>

                        ...

                   </material>

                   -<material name="0.020 PERF. ALUMINUM">

               

                   classification name is the sub section of the database

                   material name is the material in each sub section of the database

               

                   This is how I currently have it set up.  I have Aluminum, Steel, Wood, Plastic classifications and materials in each that are applied to the models. This is a very large file with many materials I just wanted to show how mine is set up so it will hopefully explain the code better.

               

                   Now for the fun part.  I pulled this together from several sources and manipulated it to my needs. I only activate this function if the Model is a part file. You may have to do a check for a part file so you don't run into an error on an assembly file.

               

              Sub addMaterialList()

                  Dim materialArray() As String

                  Dim xmlDoc As Object

                  Dim xmlRoot As Object

                  Dim xmlTemplate As Object

                  Dim xmlTemplate2 As Object

                  Dim xmlAttributes As Object

                  Dim xmlAttributes2 As Object

                  Dim xmlName As Object

                  Dim xmlName2 As Object

                  Dim xmlChildren As Object

                  Dim xmlChild As Object

                  Dim b As Integer

                     

                  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

                  xmlDoc.async = False

                  xmlDoc.validateOnParse = False

                  xmlDoc.Load ("XXXX")  'XXXX = exact location of your sldmat file. Ex: C:\Solidworls\material database.sldmat

                  Set xmlRoot = xmlDoc.DocumentElement

                  Set xmlChildren = xmlRoot.ChildNodes

                  b = 0     'Keeps track of material count and is declared in the array size below

                 

                  For Each xmlTemplate In xmlChildren

                      If xmlTemplate.nodeName = "classification" Then     'This line searches for nodes of the XML and grabs only "classification" as noted above in the XML file example. Ex: Aluminum.

                          Set xmlAttributes = xmlTemplate.Attributes

                          Set xmlName = xmlAttributes.getNamedItem("name") 'This line reads the classification name Ex: Aluminum

                          'Debug.Print xmlName.text   'If you needed these names, you would add it to an Array here.

                          Set xmlChild = xmlTemplate.ChildNodes

                          For Each xmlTemplate2 In xmlChild

                              If xmlTemplate2.nodeName = "material" Then       'Just like classification, this filters out the materials.

                                  ReDim Preserve materialArray(b)     'This line reconfigures the materialArray to the count of "b" which is incremented each time.

                                  Set xmlAttributes2 = xmlTemplate2.Attributes

                                  Set xmlName2 = xmlAttributes2.getNamedItem("name")     'This line reads the material name. Ex: 0.012" Aluminum

                                  'Debug.Print xmlName2.text

                                  materialArray(b) = xmlName2.text     'This line adds the material name to the materialArray.

                                  b = b + 1

                              End If

                          Next xmlTemplate2

                      End If

                  Next xmlTemplate

                 

                  'Sort Array, does exactly what it says. Sorts Alphabetically.  Numbers are first. This doesn't have to be done.

                  Dim strTemp As String

                  Dim i As Long

                  Dim j As Long

                  Dim lngMin As Long

                  Dim lngMax As Long

                  lngMin = LBound(materialArray)

                  lngMax = UBound(materialArray)

                  'Debug.Print "=" & lngMax

                  For i = lngMin To lngMax - 1

                      For j = i + 1 To lngMax

                          If materialArray(i) > materialArray(j) Then

                              strTemp = materialArray(i)

                              materialArray(i) = materialArray(j)

                              materialArray(j) = strTemp

                          End If

                      Next j

                  Next i

               

                  'Add Materials to both pulldowns - Here I add my materials to both a configuration specific and global material pulldown. You can iterate though the array and place the values anywhere you wish.

                  Dim Index As Integer

                  For Index = 0 To lngMax

                      'Debug.Print (materialArray(Index))

                      txtMatl.AddItem (materialArray(Index))     ' My personal location for the materials.

                      txtGMatl.AddItem (materialArray(Index))     'My 2nd personal location for the same materials.

                  Next

              End Sub

               

               

                   Once you get the pulldown filled or whichever you are using, then you can set your material accordingly. You can uncomment the Debug.Prints and comment over the materialArray(b) = xmlName2.text just to see if the code will cycle properly through your material database.  This code may not be perfect and could probably use some cleaning up, but it works for my material database.  Hope it helps.