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.
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.