too many results

too many results

cadman777
Advisor Advisor
472 Views
7 Replies
Message 1 of 8

too many results

cadman777
Advisor
Advisor

Hi All,

 

I was wondering if someone would be so kind as to help me with an issue I'm having with one of my rules.

The rule makes flatpatterns from all the sheetmetal parts in an assembly file.

The problem is, it sometimes makes multiple views of one part.

 

I found a rule found in this form (by Curtis W.) that finds the Total Quantity of a part based on it's MARK_NO. His rule the only one I found in here that can handle the assemblies that have the same problem as this rule I'm asking about. His QTY rule CORRECTLY finds the Total Quantity of each part (all parts, not just sheetmetal) in a top-level assembly. I believe the same problem lies in this flatpattern view rule. Here's his 'sweet' rule:

Class ThisRule
	Dim rDoc As Document, oDoc As Document
	Dim oQty As Integer

	'access top-level assembly BOM
	Sub Main()
		On Error Resume Next
		Dim oAssem As AssemblyDocument = ThisDoc.Document
		Dim oBOM As BOM = oAssem.ComponentDefinition.BOM

		oBOM.StructuredViewFirstLevelOnly = False
		oBOM.StructuredViewEnabled = True
		oBOM.PartsOnlyViewEnabled = True
		oBOM.SetPartNumberMergeSettings(True, )

		For Each oDoc In oAssem.AllReferencedDocuments
			'run subs on BOM
			oQty = 0
			If oDoc.DocumentType = 12291 Then Call ListItems(oBOM.BOMViews.Item(1).BOMRows, 0, oDoc) 'assembly
			If oDoc.DocumentType = 12290 Then Call ListItems(oBOM.BOMViews.Item(3).BOMRows, 0, oDoc) 'part
		Next
	End Sub

	'extract total quantity from top-level assembly and insert it into new iProperty "TotalQty"
	Sub ListItems(Rows As BOMRowsEnumerator, indent As Integer, oDoc As Document)
		
		For Each oBOMRow As BOMRow In Rows
			rDoc = oBOMRow.ComponentDefinitions.Item(1).Document
				
			If rDoc IsNot oDoc Then
			
				If Not oBOMRow.ChildRows Is Nothing Then
					Call ListItems(oBOMRow.ChildRows, indent + 1, oDoc)
				End If
			Else	
				oQty = oQty + oBOMRow.ItemQuantity
				i=1
				For Each kDoc In  oBOMRow.ComponentDefinitions					
					rDoc = oBOMRow.ComponentDefinitions.Item(i).Document
					rDoc.PropertySets("Inventor User Defined Properties").Item("TotalQty").Value = oQty
					i=i+1
				Next
			
			End If

		Next
	End Sub

End Class 

 

Here's how the model is built, which I believe causes the problems:

It's got multiple sub-assemblies with different part file names who share the same MARK_NO (in the BOM). So when the rule searches the BOM for every part according to its MARK_NO, it finds multiple occurrences of each MARK_NO in different sub-assemblies. So when it finds that particular MARK_NO in each sub-assembly, it creates a drg view. But if the top-level assembly does not have multiple sub-assemblies which contain parts sharing the same MARK_NO btw sub-assemblies, the rule works great.


I am hoping to find someone in here who can help me change the below code to filter through all sub-assemblies BEFORE the rule decides to create a drawing view for each part based on its MARK_NO.

 

'get list of part MARK_NO's to find every sheetmetal part for each view
	Dim MarkList As New ArrayList

	For Each rDoc As Document In AssyDoc.AllReferencedDocuments
		Try
			Dim oDef As SheetMetalComponentDefinition = rDoc.ComponentDefinition
			If oDef.HasFlatPattern = False Then 
				oDef.Unfold
				oDef.FlatPattern.ExitEdit
				rDoc.Close
			End If
	 		MarkList.Add(rDoc.PropertySets("Design Tracking Properties").Item("Stock Number").Value)
		Catch
		End Try
	Next

	MarkList.Sort()
	For Each item In MarkList
		For Each rDoc As Document In AssyDoc.AllReferencedDocuments
			If rDoc.PropertySets("Design Tracking Properties").Item("Stock Number").Value = item Then
				CreateViews(rDoc)
			End If
		Next
	Next

 

Thanx for considering my request!

... Chris
Win 7 Pro 64 bit + IV 2010 Suite
ASUS X79 Deluxe
Intel i7 3820 4.4 O/C
64 Gig ADATA RAM
Nvidia Quadro M5000 8 Gig
3d Connexion Space Navigator
0 Likes
473 Views
7 Replies
Replies (7)
Message 2 of 8

WCrihfield
Mentor
Mentor

It looks like you just have to check the list to see if it already contains that Stock Number, before adding to the list, so you don't add the same one multiple times.

Like:

 

If MarkList.Contains(oThatStockNumber) Then
   'Don't add it to the list
Else
   MarkList.Add(oThatStockNumber)
End If

 

Or perhaps something more condensed like this:

Dim MarkList As New ArrayList
Dim oThatStockNumber As String = "SD12548"
If Not MarkList.Contains(oThatStockNumber) Then MarkList.Add(oThatStockNumber)

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 8

J-Camper
Advisor
Advisor

From what I'm understanding, you want to limit drawings to 1 per part file, regardless of how many times the part is placed in assembly/sub-assemblies, Correct?

 

If so I think you can change your ArrayList to a Dictionary and use the document's internal name as the Key.  I don't have the assembly to test on but I modified the code you posted as follows:

'get list of part MARK_NO's to find every sheetmetal part for each view
	Dim MarkList As New Dictionary(Of String, String) '(Key, Value)

	For Each rDoc As Document In ThisApplication.ActiveDocument.AllReferencedDocuments
		Try
			Dim oDef As SheetMetalComponentDefinition = rDoc.ComponentDefinition
			If oDef.HasFlatPattern = False Then 
				oDef.Unfold
				oDef.FlatPattern.ExitEdit
				rDoc.Close
			End If
	 		MarkList.Add(rDoc.InternalName,rDoc.PropertySets("Design Tracking Properties").Item("Stock Number").Value)
		Catch
		End Try
	Next
	
	'Arraylist .sort not a method of dictionary
	'MarkList.Sort()
	
	'sorting dictionary
	Dim sorted = From pair In MarkList
             Order By pair.Value
	MarkList = sorted.ToDictionary(Function(p) p.Key, Function(p) p.Value)
		
	For Each item In MarkList
		For Each rDoc As Document In ThisApplication.ActiveDocument.AllReferencedDocuments
			If rDoc.PropertySets("Design Tracking Properties").Item("Stock Number").Value = item.Value Then
				CreateViews(rDoc)
			End If
		Next
		'Testing = MessageBox.Show(item.Value, item.Key.ToString)
	Next

 

In a Dictionary object all Keys must be unique, so If we use the unique InternalName of documents, we shouldn't get duplicated parts.  Let me know if this helps, of if you have any questions.

0 Likes
Message 4 of 8

WCrihfield
Mentor
Mentor

@cadman777, @J-Camper 

It doesn't need to be that complex.

If you check the referenced document to make sure it is a Sheet Metal part, you shouldn't need the Try...Catch block.

And If you simply check to make sure that Stock Number hasn't already been added to the list, you don't really need to use a second block of code with the same loop in it.  If that Stock Number hasn't been added to the list before, you should both add it to the list, and make the drawing view.  If it has already been added to the list before, do nothing (don't add it to the list again, and don't make a drawing view).  Very simple.

See below:

 

 

Dim oADoc As AssemblyDocument = ThisAssembly.Document
Dim oList As New List(Of String)
Dim oSMDef As SheetMetalComponentDefinition
Dim oSN As String
For Each oRefDoc As Document In oADoc.AllReferencedDocuments
	If oRefDoc.PropertySets.Item("Design Tracking Properties").Item("Document SubType Name").Value = "Sheet Metal" Then
		oSMDef = oRefDoc.ComponentDefinition
		If oSMDef.HasFlatPattern = False Then 
			oSMDef.Unfold
			oSMDef.FlatPattern.ExitEdit
			oRefDoc.Close
		End If
		oSN = oRefDoc.PropertySets("Design Tracking Properties").Item("Stock Number").Value
		If Not oList.Contains(oSN) Then
			oList.Add(oSN)
			CreateViews(oRefDoc)
		End If
	End If
Next

 

 

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 8

cadman777
Advisor
Advisor

@J-Camper

 

Thanx for this code, I really appreciate it!

 

From what I'm understanding, you want to limit drawings to 1 per part file, regardless of how many times the part is placed in assembly/sub-assemblies, Correct?

 

Unfortunately that's not what I need to do. The problem is, different discrete parts share the same MARK_NO.

So WC's solution is more like what I was thinking, which is to compile a list of parts and then send that list to the code that makes flatpatterns in an idw file.

 

Cheers ...

... Chris
Win 7 Pro 64 bit + IV 2010 Suite
ASUS X79 Deluxe
Intel i7 3820 4.4 O/C
64 Gig ADATA RAM
Nvidia Quadro M5000 8 Gig
3d Connexion Space Navigator
0 Likes
Message 6 of 8

cadman777
Advisor
Advisor

WC,

Thanx for your code, it works!

Your idea is exactly what I had in mind, I just don't yet know how to do it (but hopefully will in the future).

There's only one thing it un-did in my original code.
The original code laid down the part views in alpha-numeric order.

This code lays them down in random order.

Is there a simple fix for this?

After puzzling over it for a bit, would there a way to sort the list alpha-numerically before sending it view-making code? I figure the code would go somewhere in this area (like before/after the oList.Add(oSN)?):

oSN = oRefDoc.PropertySets("Design Tracking Properties").Item("Stock Number").Value
		If Not oList.Contains(oSN) Then
			oList.Add(oSN)
			CreateViews(oRefDoc)

 

... Chris
Win 7 Pro 64 bit + IV 2010 Suite
ASUS X79 Deluxe
Intel i7 3820 4.4 O/C
64 Gig ADATA RAM
Nvidia Quadro M5000 8 Gig
3d Connexion Space Navigator
0 Likes
Message 7 of 8

WCrihfield
Mentor
Mentor

You're right, my code didn't maintain the sorting Sub.  I didn't know it was important to create the views in alphabetical order.  Here's the updated code, and finishes making the list first, then sorts it, then runs your CreateViews() Sub.

 

Dim oADoc As AssemblyDocument = ThisAssembly.Document
Dim oList As New List(Of String)
Dim oSMDef As SheetMetalComponentDefinition
Dim oSN As String
For Each oRefDoc As Document In oADoc.AllReferencedDocuments
	If oRefDoc.PropertySets.Item("Design Tracking Properties").Item("Document SubType Name").Value = "Sheet Metal" Then
		oSMDef = oRefDoc.ComponentDefinition
		If oSMDef.HasFlatPattern = False Then 
			oSMDef.Unfold
			oSMDef.FlatPattern.ExitEdit
			oRefDoc.Close
		End If
		oSN = oRefDoc.PropertySets("Design Tracking Properties").Item("Stock Number").Value
		If Not oList.Contains(oSN) Then oList.Add(oSN)
	End If
Next
oList.Sort
For Each oSN In oList
	CreateViews(oRefDoc)
Next

I can already see that last part where I'm calling your custom Sub, isn't going to work the way I just posted it.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 8

WCrihfield
Mentor
Mentor

Since you needed the views to be made in alphabetical order, turns out using a Dictionary wasn't a bad idea after all.

Here's my revised code:

 

Dim oADoc As AssemblyDocument = ThisAssembly.Document
Dim oPairs As New Dictionary(Of Document,String)
Dim oSMDef As SheetMetalComponentDefinition
Dim oSN As String
For Each oRefDoc As Document In oADoc.AllReferencedDocuments
	If oRefDoc.PropertySets.Item("Design Tracking Properties").Item("Document SubType Name").Value = "Sheet Metal" Then
		oSMDef = oRefDoc.ComponentDefinition
		If oSMDef.HasFlatPattern = False Then 
			oSMDef.Unfold
			oSMDef.FlatPattern.ExitEdit
			oRefDoc.Close
		End If
		oSN = oRefDoc.PropertySets("Design Tracking Properties").Item("Stock Number").Value
		If Not oPairs.ContainsValue(oSN) Then 	oPairs.Add(oRefDoc,oSN)
	End If
Next

Dim oSNs As New List(Of String)
oSNs = oPairs.Values.ToList(Of String)
oSNs.Sort
For i = 1 To oSNs.Count
	For Each oPair As KeyValuePair(Of Document, String) In oPairs
		If oPair.Value = oSNs(i) Then
			CreateViews(oPair.Key)
		End If
	Next
Next

 

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes