Add Weight/mass of first drawing view to title block

Add Weight/mass of first drawing view to title block

Shag_Bore
Advocate Advocate
731 Views
15 Replies
Message 1 of 16

Add Weight/mass of first drawing view to title block

Shag_Bore
Advocate
Advocate

Hello, I have been working on a rule to add the weight/mass of the first drawing view on each sheet of a .idw to the title block, via prompted entry. This may not be the best way, (open to ideas)

I have found a view rules (attached, not my own), first rule creates a custom iProperty of the mass of each LOD in the assembly.  The second rule allows me to copy those custom iProperties from source to drawing. 

 

So the values exist in the drawing file, but I can't get the rule to check if the drawing view matches the custom iProperty, if it does then return the weight/mass value. If it doesn't then return 0.

 

The rule is setup to:

-first check for the first view in each sheet(if applicable) 

-add Custom iProps to an Array

-ensure correct titleblock is active for prompted entry (typically only use one for now)

-**check first view on drawing sheet has matching Custom iProperty, if yes then return value

-input weight/mass value to 2nd prompted entry

 

I am not sure if I created the array correctly, and/or am matching the first view with custom iprop correctly. The rule operates without error, but it doesn't return any value to the 2nd prompted entry. I have another rule setup to also populate a prompted entry, it grabs the sheet name in the browser and populates the title block field. So maybe that prompted entry is interfering somehow?

 

'CHECK EACH SHEET FOR FIRST VIEW
Dim oEachSheet
Dim oFirstview
Dim oEachDocumentOffirstview
For Each oEachSheet In ThisApplication.ActiveDocument.Sheets
  oFirstview = oEachSheet.DrawingViews(1)
  oEachDocumentOffirstview = oFirstview.ReferencedDocumentDescriptor.ReferencedDocument 
  customPropertySet = oEachDocumentOffirstview.PropertySets.Item("Inventor User Defined Properties")
  MessageBox.Show("RULE CHECK 1", "Title")
'ADD CUSTOM iPROPS TO ARRAY
On Error Resume Next
Dim invDoc As Document : invDoc = ThisApplication.ActiveDocument
oCommandMgr = ThisApplication.CommandManager
Dim invDesignInfo As PropertySet
invDesignInfo = invDoc.PropertySets.Item("Design Tracking Properties")
Dim oList As New ArrayList
oList.Add("Design Tracking Properties:")
oList.Add("")
invDoc = ThisApplication.ActiveDocument
invDesignInfo = invDoc.PropertySets.Item("Design Tracking Properties")
Dim invPartNumberProperty As [Property]
For Each invPartNumberProperty In invDesignInfo ' iterate through the commands and write to file
	oList.Add(invPartNumberProperty.Name & " --> " & invPartNumberProperty.Value)
Next
oList.Add("")
oList.Add("Inventor User Defined Properties:")
oList.Add("")
invDesignInfo = invDoc.PropertySets.Item("Inventor User Defined Properties")
For Each UnoInvProp2 In invDesignInfo
	oList.Add(UnoInvProp2.Name & " --> " & UnoInvProp2.Value)
Next
'ENSURE CORRECT TITLEBLOCK IS ACTIVE WITH PROMPTED ENTRY
Dim oDrawDoc As Inventor.DrawingDocument = ThisApplication.ActiveDocument
Dim oTitleBlockDef As TitleBlockDefinition
oTitleBlockDef = oDrawDoc.TitleBlockDefinitions.Item("Teksign_Large")
oSheet = oDrawDoc.ActiveSheet
MessageBox.Show("RULE CHECK 2", "Title")
'IF DRAWING VIEW HAS MATCHING CUSTOM iPROP THEN ADD VALUE TO PROMPTED ENTRY "WEIGHT"
If customPropertySet = invDesignInfo Then
Weight = invPartNumberProperty.Value
'THIS IS SECOND PROPTED ENTRY IN TITLEBLOCK, FIRST PROMPTED ENTRY PUTS SHEET NAME IN TITLEBLOCK
Dim sPromptStrings(1) As Double 		
	sPromptStrings(1) = Weight 
    Dim stringYouNeed2 As String = Weight
	sPromptStrings(1) = stringYouNeed2 'if there is only one promped entry
	oTitleBlock = oSheet.AddTitleBlock(oTitleBlockDef, , sPromptStrings)
End If			
Next
MessageBox.Show("RULE CHECK 3", "Title")

 

Sean Farr
Product Designer at Teksign Inc.
Inventor 2016 SP1
Dell Precision 3660
i7-12700 @ 2.40GHz-4.90GHz
32GB DDR5 4400MHz RAM
NIVDIA RTX A2000 6GB
0 Likes
Accepted solutions (1)
732 Views
15 Replies
Replies (15)
Message 2 of 16

WCrihfield
Mentor
Mentor

Hi @Shag_Bore.  I only briefly scanned down through your comments and the code you posted, but I think I see something that may need to be addressed.  How many prompted entries are there total within your TitleBlock?  Near the end of your posted code, you are creating an Array to use as input for the PromptedEntries when adding the TitleBlock to the sheet.  For one, you are defining it as an Array of Doubles, not an Array of Strings, and it needs to be defined as an Array of Strings.  Next, that array should have exactly the same number of elements as there are PromptedEntries in your TitleBlock.  You may not necessarily need to fill in the values for all of them, but I believe the Array needs to be the exact right size.  You are specifying 1 as its Size, but since Array's are zero based (not 1 based), its first element is at (0), and its second element is at (1), so when you specify (1) as its size, you are making it have two elements, not one.  If there is only 1 PromptedEntry then the Array would be like declared like:

Dim oPrompedEntries(0) As String

oPrompedEntries(0) = "First Prompted Entry Value"

If there were two PromptedEntries, then it would be more like:

Dim oPrompedEntries(1) As String

oPrompedEntries(0) = "First Prompted Entry Value"

oPrompedEntries(1) = "Second Prompted Entry Value"

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 16

Shag_Bore
Advocate
Advocate

Hey @WCrihfield ,

thanks for taking a look, to be honest and as you can see from my posts, I have limited skillset regarding programming. 

 

I previously only had one prompted entry, it searches the documents for sheets, grabs the name, gets rid of the ":1, :2 etc..) and writes it to the prompted entry. The rule for that is here:

Dim oDrawDoc As Inventor.DrawingDocument = ThisApplication.ActiveDocument
' Obtain a reference to the desired border defintion.
Dim oTitleBlockDef As TitleBlockDefinition
oTitleBlockDef = oDrawDoc.TitleBlockDefinitions.Item("Teksign_Large")
Dim oSheet As Sheet
Dim oSheets as Sheets = oDrawDoc.sheets
'oSheet = oDrawDoc.ActiveSheet
For Each oSheet In oSheets
	' Check to see if the sheet already has a title block and delete it if it does.
	If Not oSheet.TitleBlock Is Nothing Then
	oSheet.TitleBlock.Delete()
	End If
	' This title block definition contains one prompted string input. An array
	' must be input that contains the strings for the prompted strings.
	Dim sPromptStrings(0) As String 'start counting by 0 !!!
	sPromptStrings(0) = oSheet.Name 'if there is only one promped entr
	' Add an instance of the title block definition to the sheet.
	Dim oTitleBlock As TitleBlock
	Dim positionOfDubbleDot As Integer = Strings.InStrRev(oSheet.Name, ":")
    Dim Length As Integer = Len(oSheet.Name)
    Dim stringYouNeed As String = Strings.Left(oSheet.Name, Length - (Length - positionOfDubbleDot) - 1)
	'Dim sPromptStrings(0) As String 'start counting by 0 !!!
	sPromptStrings(0) = stringYouNeed 'if there is only one promped entry
	oTitleBlock = oSheet.AddTitleBlock(oTitleBlockDef, , sPromptStrings)

Next

 

I have just noticed that this rule doesn't work once I had a second prompted entry field for the Weight value.

 

I am assuming it has to do with what you mentioned above, I will keep plugging away at it. I am sure what I am trying to do is possible, I just need to clear up my understanding of arrays and the syntax of calling out the prompted entries.

 

thanks!

 

Sean

Sean Farr
Product Designer at Teksign Inc.
Inventor 2016 SP1
Dell Precision 3660
i7-12700 @ 2.40GHz-4.90GHz
32GB DDR5 4400MHz RAM
NIVDIA RTX A2000 6GB
0 Likes
Message 4 of 16

WCrihfield
Mentor
Mentor

One rule of thumb to keep in mind about all types of 'collection objects' is that if they are native to Inventor/Autodesk, then they are pretty much always 1-based (first item is Item(1)), but any collection type that is purely vb.net based, is pretty much always zero-based (first item is Item(0)).

Array, ArrayList, List(Of Something), Dictionary(Of Something, Something), are all vb.net, and all zero-based.

ObjectCollectionComponentOccurrencesSheetsPlanarSketches, and so on, are all Inventor API objects, and all 1-based.

There are way more of each type, but you get the point.  It took me quite a while to figure that stuff out too when I started into it.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 16

Shag_Bore
Advocate
Advocate

Thanks @WCrihfield,

 

I assume that I will need to have the Sheet Name and Weight prompted entries in the same rule?
I was initially was making them separate rules to populate each prompted entry field.

 

Any idea what area of the Autodesk Help site I could look through to figure out how to write 


If 'first drawing view'   =(same as?)    'Custom iProp name'     Then

'promptedentry2'   =   'Custom iProp Value'

 

Thanks!

 

Sean

Sean Farr
Product Designer at Teksign Inc.
Inventor 2016 SP1
Dell Precision 3660
i7-12700 @ 2.40GHz-4.90GHz
32GB DDR5 4400MHz RAM
NIVDIA RTX A2000 6GB
0 Likes
Message 6 of 16

WCrihfield
Mentor
Mentor

Hi @Shag_Bore.  I tried to make sense of your two existing iLogic rules, and combine them both into one.  One big detail I still do not understand though, is where is the 'Mass/Weight' iProperty information coming from?  You made it sound like it is a custom iProperty within the model document that the first view on each sheet should have within it.  But I do not know that the name of that custom iProperty is yet, and I do not see it in either of your iLogic rule codes posted above, or in your comments so far.  So, I just guessed that it is named "Weight".  If that is not correct, then you will have to change that name within the code, before trying to run it (Line 30).

The code is below.  But I am leaving for the day, right after posting this, so if I remember, I will check back tomorrow.

Sub Main
	Dim oDDoc As DrawingDocument = TryCast(ThisDoc.Document, Inventor.DrawingDocument)
	If oDDoc Is Nothing Then Return
	Dim oTBDefs As TitleBlockDefinitions = oDDoc.TitleBlockDefinitions
	Dim oTBDef As TitleBlockDefinition = Nothing
	For Each oTBD As TitleBlockDefinition In oTBDefs
		If oTBD.Name = "Teksign_Large" Then oTBDef = oTBD
	Next 'oTBD
	If oTBDef Is Nothing Then
		MsgBox("The specified TitleBlockDefinition could not be found.  Exiting rule.", vbCritical, "iLogic")
		Return 'exits this whole Sub routine
	End If
	Dim oSheets As Inventor.Sheets = oDDoc.Sheets
	Dim oSheet As Inventor.Sheet
	Dim oOriginallyActiveSheet As Inventor.Sheet = oDDoc.ActiveSheet
	Dim oViews As DrawingViews
	Dim oView As DrawingView
	Dim oViewDoc As Inventor.Document
	Dim oCustomProps As Inventor.PropertySet
	Dim oWeight As String
	Dim sSheetName As String
	Dim iSheetNumber As Integer
	For Each oSheet In oSheets
		oSheet.Activate
		If oSheet.DrawingViews.Count = 0 Then Continue For 'skip to next sheet
		oView = oViews.Item(1)
		oViewDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
		oCustomProps = oViewDoc.PropertySets.Item("Inventor User Defined Properties")
		'<<< here I am assuming that you have a 'custom' iProperty named "Weight" where that information is stored)
		oWeight = oCustomProps.Item("Weight").Value.ToString
		'split String into multiple Strings (String Array), using ":" as the split tool, then get the first String in that array
		sSheetName = oSheet.Name.Split(":").First
		'split String into multiple Strings (String Array), using ":" as the split tool, then get the last String in that array
		iSheetNumber = CInt(oSheet.Name.Split(":").Last) 'CInt() converts String to Integer
		If oSheet.TitleBlock IsNot Nothing Then oSheet.TitleBlock.Delete
		'simpler to create List first, add entries to it (number of entries does not matter, position does)
		Dim oPromptStringsList As New List(Of String)
		oPromptStringsList.Add(sSheetName)
		oPromptStringsList.Add(oWeight)
		'now convert the List into an Array, because we need an Array for TitleBlock
		Dim oPromptStringsArray() As String = oPromptStringsList.ToArray
		oSheet.AddTitleBlock(oTBDef, , oPromptStringsArray)
		oSheet.Update 'update the sheet, if necessary
	Next 'oSheet
	oOriginallyActiveSheet.Activate 'restore originally active sheet to active
	'update the drawing document, if needed
	If oDDoc.RequiresUpdate Then oDDoc.Update2(True)
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 7 of 16

Shag_Bore
Advocate
Advocate

Hey @WCrihfield ,

 

I typically prefer to work with one assembly, and a few dozen view reps to get my desired drawing with multiple sheets.

 

For any view rep that I want a specific weight/mass for, I create a LOD with the same name as the view rep. Then I run the rule from post #1, that searches the assembly, creates a custom iprop with the same name as the LOD (view rep also) and the value is the weight/mass of that LOD.

 

I then have another rule that I can run in the drawing, it allows me to select the assembly file and then copies all custom iprops to the drawing. So all my weight/masses are in the drawing document as custom iprops. One problem here is I can't have a generic name, it will always be different. 

 

My approach to this was to grab all those custom iprops in the drawing, check to see if the first view on the drawing sheet matches one of the custom iprops, if it does, then populate the prompted entry field in the title block, leave blank if it doesn't or populate with the Master view weight/mass. (since the first view will have the same name as the custom iprop, or so I thought)

 

I may have misunderstood arrays, I found a rule here that creates an array using the Inventor User Defined Properties, I was hoping that I could then write a simple if then statement to see if the first view rep on the drawing sheet matches an item on the array, then populate the prompted entry field.

 

I tried using the same approach as I used for naming my drawing sheets, but instead of referencing the sheet names, use the custom iprops and populate. 

 

Hope this make some sort of sense now.

 

Thanks!

 

Sean Farr
Product Designer at Teksign Inc.
Inventor 2016 SP1
Dell Precision 3660
i7-12700 @ 2.40GHz-4.90GHz
32GB DDR5 4400MHz RAM
NIVDIA RTX A2000 6GB
0 Likes
Message 8 of 16

Shag_Bore
Advocate
Advocate

hey @WCrihfield ,

 

I just tried to run the rule you shared above and am coming up with "is not a member of 'System Array'. where it is trying to split the sheet number from the sheet name. I can't find much info on the split().first and split().last lines. Not sure how to correct this.
Thanks!

WEIGHT1.PNG

Sean Farr
Product Designer at Teksign Inc.
Inventor 2016 SP1
Dell Precision 3660
i7-12700 @ 2.40GHz-4.90GHz
32GB DDR5 4400MHz RAM
NIVDIA RTX A2000 6GB
0 Likes
Message 9 of 16

WCrihfield
Mentor
Mentor

Hi @Shag_Bore.  I obviously still did not fully understand all the details of the task when I posted that last code, but after reading your initial response after that code was posted, it makes more sense.  Still a bit much to wrap my head around, but I have a better understanding about what needs to be changed.  I will try to update my code sometime today, but am currently working on another code related project.  Judging by the text at the end of your posts, you are still using Inventor 2016, which means that you are actually using LODs (LevelOfDetailRepresentations) instead of ModelStates.  And it sounds like my code needs to check which LOD that drawing view is set to, then find the custom iProperty with the same name as that LOD, then get its value for the 'Weight' value to put into the TitleBlock's second PromptedEntry on that sheet.

 

As for the Array.First and Array.Last items not being recognized...I know that they seem to work OK for me, but if they are not working for you, there is another very similar way I could have done those two lines.  It is true that those are not 'direct' members of the System.Array Class, but they are methods (Functions) of the Enumerable Class (Enumerable.First() & Enumerable.Last()), but somehow they just seem to work for me, even if I am working with an Array.

Anyways, instead of

 

sSheetName = oSheet.Name.Split(":").First

 

...I you could use this (below) instead, which is just as simple.  The (0) at the end gets the first element in the Array.

 

sSheetName = oSheet.Name.Split(":")(0)

 

And instead of this:

 

iSheetNumber = CInt(oSheet.Name.Split(":").Last)

 

...we could use this (below) instead.  Again, the (1) is getting the second element in the Array.

However, this assumes that there is only 1 ":" character in the name of your sheet (the one the system adds in), otherwise it might get the wrong element.

 

iSheetNumber = CInt(oSheet.Name.Split(":")(1))

 

 

Edit:  Also, in the code example you provided a Link to, they are using an ArrayList object, not a regular System.Array type object.  The System.Array object is more strict, and a bit more difficult to work with, because they are a 'fixed size', while the ArrayList object is not fixed size.  When creating an Array from scratch, you must either specify how many elements it has, then fill in the values of each of its elements in later lines of code, Or you must not specify its size, then set all of its values directly in that line of code that creates it...one or the other.  And if you have already specified its size, but want/need to change its size later, you must use specific lines of code to resize it as needed later.  When using the ArrayList, you do not need to specify its size, and can just add elements to it as you go.  They are different objects though, so you can not always use one type where the other type is being requested.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 16

WCrihfield
Mentor
Mentor
Accepted solution

Hi @Shag_Bore.  Here is an edited version of my previously posted code.  In this version I changed the line of code getting the sheet name, like I mentioned in my last response, and just deleted the line of code getting the sheet's number, because it is not being used for anything, to void the errors.  I am also now checking the active DVR (DesignViewRepresentation) name, and the active LOD (LevelOfDetailRepresentation) name of the first view on each sheet.  It sounded to me like the view's LOD name was the important detail that we want to use here, but it sounded like it should also match the name of the view's DVR, so...  I think there is always a value for the view's DVR, but I am not sure if there will always be a value for the view's LOD.  So, I am checking if the view's LOD name is empty first, then checking if it matches the view's DVR, as mentioned in your last response.  If it is not empty, and they match, then I attempt to set the value of the 'oWeight' variable based on the value of a custom iProperty within that view's model, with the same name as that view's LOD.  If the view's LOD name is empty, or it does not match the name of that view's DVR, then it does not assign any value to the 'oWeight' variable (leaves its value an empty String).  I also got rid of the List(Of String) type variable, and the 'ToArray' conversion line that I had in my last response, because it sounds like they just added more confusion than enlightenment.  I replaced that stuff with a regular, simple Array type variable, which is what the 'AddTitleBlock' method is looking for anyways.  I hope I got the details correct this time.  If not, and you or someone else does not figure it out over the weekend, I will try to remember to revisit this on Monday, if I have time.

Sub Main
	Dim oDDoc As DrawingDocument = TryCast(ThisDoc.Document, Inventor.DrawingDocument)
	If oDDoc Is Nothing Then Return
	Dim oTBDefs As TitleBlockDefinitions = oDDoc.TitleBlockDefinitions
	Dim oTBDef As TitleBlockDefinition = Nothing
	For Each oTBD As TitleBlockDefinition In oTBDefs
		If oTBD.Name = "Teksign_Large" Then oTBDef = oTBD
	Next 'oTBD
	If oTBDef Is Nothing Then
		MsgBox("The specified TitleBlockDefinition could not be found.  Exiting rule.", vbCritical, "iLogic")
		Return 'exits this whole Sub routine
	End If
	Dim oSheets As Inventor.Sheets = oDDoc.Sheets
	Dim oSheet As Inventor.Sheet
	Dim oOriginallyActiveSheet As Inventor.Sheet = oDDoc.ActiveSheet
	Dim oViews As DrawingViews, oView As DrawingView
	Dim oViewDoc As Inventor.Document
	Dim oCustomProps As Inventor.PropertySet
	Dim oWeight As String = ""
	Dim sSheetName As String = ""
	Dim iSheetNumber As Integer = 0
	For Each oSheet In oSheets
		sSheetName = "" 'reset per sheet
		iSheetNumber = 0 'reset per sheet
		oWeight = "" 'reset per sheet
		If oSheet.DrawingViews.Count = 0 Then Continue For 'skip to next sheet
		oSheet.Activate
		oView = oViews.Item(1)
		Dim sViewRepName As String = oView.DesignViewRepresentation
		Dim sLODName As String = oView.ActiveLevelOfDetailRepresentation
		'if this view's LOD name is not empty, and matches this view's DVR name, then
		If sLODName <> "" AndAlso sLODName.ToUpper = sViewRepName.ToUpper Then
			'get the custom iProperty with the same name as the LOD name of this view
			oViewDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
			Try 'try to set the value of oWeight from a custom iProperty with the same name as this view's LOD
				oWeight = oViewDoc.PropertySets.Item("Inventor User Defined Properties").Item(sLODName).Value
			Catch
			End Try
		Else 'view's LOD name empty, or view's LOD name does not match view's DVR name
			'oWeight = ""
		End If
		'split String into multiple Strings (String Array), using ":" as the split tool, then get the first String in that array
		sSheetName = oSheet.Name.Split(":")(0)
		If oSheet.TitleBlock IsNot Nothing Then oSheet.TitleBlock.Delete
		'create the Array of Strings, with 2 elements (position zero, and position 1)
		Dim oPromptStrings(1) As String
		'do not use oPromptStrings.Item(0) with an Array, just oPromptStrings(0)
		oPromptStrings(0) = sSheetName
		oPromptStrings(1) = oWeight
		oSheet.AddTitleBlock(oTBDef, , oPromptStrings)
		oSheet.Update 'update the sheet, if necessary
	Next 'oSheet
	oOriginallyActiveSheet.Activate 'restore originally active sheet to active
	'update the drawing document, if needed
	If oDDoc.RequiresUpdate Then oDDoc.Update2(True)
End Sub

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 11 of 16

Shag_Bore
Advocate
Advocate

Good Morning @WCrihfield ,

 

I just tried running your rule now and it come up with an error,

 

WEIGHT2.PNGWEIGHT3.PNG 

How come the this particular error doesn't a line number to refer to in the rule?

 

Thanks!

 

Sean

Sean Farr
Product Designer at Teksign Inc.
Inventor 2016 SP1
Dell Precision 3660
i7-12700 @ 2.40GHz-4.90GHz
32GB DDR5 4400MHz RAM
NIVDIA RTX A2000 6GB
0 Likes
Message 12 of 16

WCrihfield
Mentor
Mentor

Hi @Shag_Bore.  I am not sure why the error did not indicate what line it happened on, but I think I see where it is encountering the problem.  On Line 28, I am using the variable 'oViews' to get the first view from, but I have not assigned a value to that variable yet in that loop.  I must have accidentally deleted that line or something.  To fix it, I would put:

 

oViews = oSheet.DrawingViews

 

...at Line 26.  Then this line:

 

If oSheet.DrawingViews.Count = 0 Then Continue For 'skip to next sheet

 

...would get moved down a line, and changed to be like this:

 

If oViews.Count = 0 Then Continue For

 

After that point, the sheet gets activated, then it gets the first view, but now the 'oViews' variable has had a value set to it, as originally planned.  This is the kind of mistake I usually try to avoid by testing code before posting it, but none of my drawings are set-up like yours, and none of my TitleBlockDefinitions contain any PromptedEntries, so it would not have been fast or easy to test on my end.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 13 of 16

Shag_Bore
Advocate
Advocate

Hey @WCrihfield 

 

I tried updating the your rule with the suggestions but still couldn't get it to fly. However using your rule as a template, I did manage to get this rule below to function correctly. I am not sure how bulletproof it is. Haven't had any errors pop up yet. I even added a third prompted entry to update the drawing scale of the first view.

Sub Main     
Dim oDDoc As DrawingDocument = TryCast(ThisDoc.Document, Inventor.DrawingDocument)     
If oDDoc Is Nothing Then Return          
Dim oTBDefs As TitleBlockDefinitions = oDDoc.TitleBlockDefinitions     
Dim oTBDef As TitleBlockDefinition = Nothing          
For Each oTBD As TitleBlockDefinition In oTBDefs         
If oTBD.Name = "Teksign_Large" Then             
oTBDef = oTBD         
End If     
Next 'oTBD          
If oTBDef Is Nothing Then         
MsgBox("The specified TitleBlockDefinition could not be found. Exiting rule.", vbCritical, "iLogic")         
Return 'exits this whole Sub routine     
End If          
Dim oSheets As Inventor.Sheets = oDDoc.Sheets     
Dim oSheet As Inventor.Sheet     
Dim oOriginallyActiveSheet As Inventor.Sheet = oDDoc.ActiveSheet          
For Each oSheet In oSheets         
If oSheet.DrawingViews.Count = 0 Then Continue For 'skip to next sheet                  
oSheet.Activate                  
Dim oViews As DrawingViews = oSheet.DrawingViews         
Dim oView As DrawingView = oViews.Item(1)         
Dim sSheetName As String = oSheet.Name.Split(":")(0)                  
Dim oCustomProps As Inventor.PropertySet = oView.ReferencedDocumentDescriptor.ReferencedDocument.PropertySets.Item("Inventor User Defined Properties")         
Dim oWeight As String = ""         
Dim oScale As String = ""          
If oView.ActiveDesignViewRepresentation <> "" Then             
Try                 
oWeight = oCustomProps.Item(oView.ActiveDesignViewRepresentation).Value             
Catch ex As Exception             
End Try         
End If                  
' Check if the first drawing view has a scale defined         
If oView.Scale <> 0 Then             
oScale = oView.ScaleString         
End If                  
If oSheet.TitleBlock IsNot Nothing Then             
oSheet.TitleBlock.Delete         
End If                  
Dim oPromptStrings(2) As String         
oPromptStrings(0) = sSheetName         
oPromptStrings(1) = oWeight         
oPromptStrings(2) = oScale                  
oSheet.AddTitleBlock(oTBDef, , oPromptStrings)         
oSheet.Update 'update the sheet, if necessary     
Next 'oSheet          
oOriginallyActiveSheet.Activate 'restore originally active sheet to active 
End Sub

 

One thing I am still trying to do it when I add a new sheet to the drawing, The prompted entries dialog box pops up. I found this post here stating how to use VBA to stop it, but I am not sure how to tie in with the working rule above, or if it is even possible.

 

'Before running this code, add reference to
' "Microsoft XML, v6.0" in this VBA project
Function GetPromptedEntryNames(sk As Sketch) As String()
  On Error Resume Next
  Dim names() As String
  Dim tb As TextBox
  For Each tb In sk.TextBoxes
    Dim xml As DOMDocument
    Set xml = New DOMDocument
    ' FormattedText might not be available on
    ' all TextBox, that's why using
    ' error handling
    Call xml.loadXML(tb.FormattedText)
        
    ' Look for prompted entry
    Dim node As IXMLDOMNode
    Set node = xml.selectSingleNode("Prompt")
    If Not node Is Nothing Then
      If (Not names) = -1 Then
        ReDim names(0) As String
      Else
        ReDim Preserve names(UBound(names) + 1) As String
      End If
      
      names(UBound(names)) = node.text
    End If
  Next
  On Error GoTo 0
  
  GetPromptedEntryNames = names
End Function

Sub SetValueBasedOnName(strings() As String)
  Dim i As Integer
  For i = 0 To UBound(strings)
    Dim s As String: s = strings(i)
    If s = "MyBorderPrompt" Or s = "MyTitlePrompt" Then
      strings(i) = "My Value"
    Else
      strings(i) = "Dunno"
    End If
  Next
End Sub

Sub AddNewSheet()
  Dim dwg As DrawingDocument
  Set dwg = ThisApplication.ActiveDocument
  
  Dim sh As Sheet
  Set sh = dwg.ActiveSheet
  
  ' Arrays for the Prompted Entry's
  Dim psTB() As String
  Dim psB() As String
  
  psTB = GetPromptedEntryNames(sh.TitleBlock.Definition.Sketch)
  psB = GetPromptedEntryNames(sh.Border.Definition.Sketch)
  
  ' Fill them with values based on our logic
  Call SetValueBasedOnName(psTB)
  Call SetValueBasedOnName(psB)
  
  ' Create a new format based on active sheet
  Dim sf As SheetFormat
  Set sf = dwg.SheetFormats.Add(sh, "Mine")
  
  ' Create a new sheet
  Dim s As Sheet
  Set s = dwg.Sheets.AddUsingSheetFormat( _
    sf, , "My sheet", , psTB, psB)
  
  ' If you don't want to keep the format you can delete it
  Call sf.Delete
End Sub

 

Thanks for all you help!

 

Sean

Sean Farr
Product Designer at Teksign Inc.
Inventor 2016 SP1
Dell Precision 3660
i7-12700 @ 2.40GHz-4.90GHz
32GB DDR5 4400MHz RAM
NIVDIA RTX A2000 6GB
0 Likes
Message 14 of 16

WCrihfield
Mentor
Mentor

Hi @Shag_Bore.  What they are doing on that linked topic is somewhat advanced, working directly with XML code system, which I have very little experience with.  Plus, although they are pretty similar, VBA code and iLogic code do not always mix well, because VBA is an older, and slightly different branch of the VB coding system than what iLogic uses.  I believe all you would need to change in your case is a single setting, in one of two possible ways.  When you have your rule code open in the iLogic rule editor, go to the Options tab, and put a check in the checkbox next to the option named "Silent Operation".  The scope of that setting is just that one iLogic rule.  That setting helps to avoid most pop-up dialogs while the code is running.  There is also an application level setting, in case you plan on running the code outside of iLogic (ThisApplication.SilentOperation).  But using the application level setting is more dangerous, because if set to True somewhere in your code, you MUST make sure it gets set back to False, even if your code errors out before it finishes its task.  Some folks use a Try...Catch...Finally statement, setting it to True in the Try portion, and set it to False in the Finally portion of that statement, because the Finally portion always runs, even if there is no error being handled by a Catch section.

 

An example of using the application level setting might be like the following, but I strongly suggest the iLogic rule level setting instead.

Try
	ThisApplication.SilentOperation = True
	oSheet.AddTitleBlock(oTBDef, , oPromptStrings)
Catch
	'what to do if that fails
Finally 'something that will always run, even if no error
	ThisApplication.SilentOperation = False
End Try

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 15 of 16

Shag_Bore
Advocate
Advocate

Hey @WCrihfield ,

 

I tried the silent operation checkbox and it didn't change much. Your example of the try/catch/end try is a little advanced for me right to try and incorporate it into my working rule. 

 

thanks for your guidance, having the drawing sheet, weight and scale populate into the titleblock automatically now is going to be a good time saver for me.

 

Cheers!

 

 

Sean Farr
Product Designer at Teksign Inc.
Inventor 2016 SP1
Dell Precision 3660
i7-12700 @ 2.40GHz-4.90GHz
32GB DDR5 4400MHz RAM
NIVDIA RTX A2000 6GB
0 Likes
Message 16 of 16

WCrihfield
Mentor
Mentor

Hi @Shag_Bore.  There may be another way, depending on the situation.  If you do not really need to replace (delete the title block, then add one again), then we could just find the existing prompted entries in the existing title block, and replace their current values with different ones.  It is not super simple, but not super complicated either, and does not really require knowing XML coding either.  The TitleBlock API object has two methods (TitleBlock.GetResultText and TitleBlock.SetPromptResultText) for interacting with prompted entries, but both methods require you to 'input' the Inventor.TextBox API object, from within the TitleBlockDefinition.Sketch, that holds the prompted entry.  That requires digging into that sketch's TextBoxes collection, and iterating through them.  Not all TextBoxes can be used that way, because not all of them represent a prompted entry.  That's where the complication is.  I have written code before for iterating those TextBoxes and prompting the user with a simple InputBox for each prompted entry it encounters, one by one, and posted them here on the forum before, and some others have done similar codes before on the forum too.  Just mentioning that alternate way of doing something similar to what you are doing, in case it may be useful to you.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)