Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.
WCrihfield
in reply to: Jakob_Hamburg

Hi @Jakob_Hamburg.  This morning, I just read through your replies since my last reply.  That is a lot of good information, so thank you.  It is also a lot to process and think about.  It is often difficult for me (and others in my position, seeking to help others on the forum) to determine how much coding experience you may already have, or how much you may already know about all the related concepts involved, from a code based point of view, so it is difficult to know how much I/we may need to explain.

 

In general, executing a 'command' (ControlDefinition) (as opposed to using an API method) will always 'act upon' whichever Document that happens to be 'active' (visibly showing on your screen at that exact moment), no matter which Document reference your code may be currently working with at that moment in time, because there is no way to tell the command which document you want it to act upon.  Because of this, it is generally not a good idea to execute commands from code that may be running remotely, in response to events happening.  Because events can happen to (or because of) documents that are not currently 'active', which can trigger the code to run, but the command would be acting upon the currently active document, instead of the one in the background which actually triggered the event.

 

Using proper/correct/reliable Document references, and ways to refer to specific documents, within your code that is going to be ran remotely, by events, is extremely important.  It can be difficult to understand how all the available/possible ways to refer to a document work at first.  And the iLogic add-in offers us a lot of seemingly simple tools that seem to be very simple to use.  However, one thing that is fairly common with most iLogic tools is the 'lack' of a specific Document reference being involved anywhere.  This leaves us wandering...which Document will this piece of code be 'focused' on when it runs?...and how can I be absolutely sure that it will be working on the specific Document I want it to be working on in various situations?  Because of those uncertainties, I often revert back to using the main Inventor API tools, instead of the tools that are unique to the iLogic API.  When using the Inventor API way of doing things, you must step up or down the API object model structure, which is very logical and predictable, and one of those steps is pretty much always a specific Document object, making that reference pretty clear.  There are some relatively new, more advanced ways to specify which document some of the uniquely iLogic tools will focus their attention on, in more reliable ways, but that is a whole other discussion.  I do still use the 'ThisApplication.ActiveDocument' code phrase in some very specific situations, where I need to make sure that my code is only working on the document that is currently, visibly showing on the screen.  But I use the iLogic code phrase 'ThisDoc.Document' far more, and in far more types of situations than the other phrase, because it is very dynamic, and I now understand a lot more about how it works in several different types of situations than I used to, based on years of experience.  The rules/code it very likely not working correctly when being ran remotely (by your add-in) because it is trying to work on the wrong document.  I generally tell folks to 'get' their reference to a document that the code should be focused on set to a single variable once, either at, or near the start of the rule, then make absolutely sure that every other line of code after that within the whole rule, is using that same exact variable (one way or another) when accessing, reading, or writing to that document, in any way.  So of you have a variable like 'oDoc' that has already had its value set to a Document, then do not use terms like ThisDoc, or ActiveSheet, or ThisDrawing, or ActiveDocument, or ActiveEditDocument, or any others after that point, because one/some of those other terms may be pointing to a different Document than your 'oDoc' variable is set to.

 

Here is an alternate version of your code that you can try out:

Sub Main
	Dim oDrawingDoc As Inventor.DrawingDocument = ThisDoc.Document
	Dim oSheets As Inventor.Sheets = oDrawingDoc.Sheets
	Dim oActiveSheet As Inventor.Sheet = oDrawingDoc.ActiveSheet
	Dim sOriginalTitleBlockName As String = "company_name Title block"
	Dim sOriginalBorderName As String
	'Checks if there is a Title Block on the Active Sheet
	If oActiveSheet.TitleBlock Is Nothing Then
		MessageBox.Show("Please Insert a Title Block on this Sheet!")
		Exit Sub
	ElseIf oActiveSheet.TitleBlock.Name <> sOriginalTitleBlockName Then
		MessageBox.Show("This drawing has an unknown title block")
		Exit Sub
	End If

	'Gets the Name of the Border Currently in the Drawing to Insert at the end of this code 
	Try
		sOriginalBorderName = oActiveSheet.Border.Name
	Catch
		MessageBox.Show("No border exists", "Title")
		Exit Sub
	End Try

	'Delete all TitleBlocks & Borders from all sheets
	For Each oSheet As Inventor.Sheet In oSheets
		oSheet.Activate
		If Not oSheet.TitleBlock Is Nothing Then
			oSheet.TitleBlock.Delete
		End If
		If Not oSheet.Border Is Nothing Then
			oSheet.Border.Delete
		End If
	Next oSheet
	'delete all unreferenced TitleBlockDefinitions
	For Each oTBDef As TitleBlockDefinition In oDrawingDoc.TitleBlockDefinitions
		If Not oTBDef.IsReferenced Then oTBDef.Delete
	Next oTBDef
	'delete all unreferenced BorderDefinitions
	For Each oBDef As BorderDefinition In oDrawingDoc.BorderDefinitions
		If (Not oBDef.IsDefault) AndAlso (Not oBDef.IsReferenced) Then
			oBDef.Delete()
		End If
	Next oBDef
	'open drawing template (invisibly - in the background)
	Dim sTemplate As String = "C:\WS_company_name\Templates\Standard.idw"
	Dim oTemplate As DrawingDocument = ThisApplication.Documents.Open(sTemplate, False)
	'copy BorderDefinitions from template to this drawing
	Dim oNewBDef As BorderDefinition = Nothing
	Dim oBDefNames() As String = {"A0", "A1", "A2", "A3", "A4"}
	For Each oTempBDef As BorderDefinition In oTemplate.BorderDefinitions
		For Each sBDefName As String In oBDefNames
			If oTempBDef.Name = sBDefName Then
				If sBDefName = sOriginalBorderName Then
					oNewBDef = oTempBDef.CopyTo(oDrawingDoc)
				Else
					oTempBDef.CopyTo(oDrawingDoc)
				End If
			End If
		Next sBDefName
	Next oTempBDef
	'copy TitleBlockDefinitions from template to this drawing
	Dim oNewTBDef As TitleBlockDefinition = Nothing
	For Each oTempTBDef As TitleBlockDefinition In oTemplate.TitleBlockDefinitions
		If oTempTBDef.Name = sOriginalTitleBlockName Then
			oNewTBDef = oTempTBDef.CopyTo(oDrawingDoc)
		End If
	Next oTempTBDef
	oTemplate.Close(True) 'True means skip save
	'add Borders & TitleBlocks back to all sheets
	For Each oSheet As Inventor.Sheet In oSheets
		oSheet.Activate
		Try
			oSheet.AddBorder(oNewBDef)
		Catch
			'what to do if adding Border fails
		End Try
		Try
			oSheet.AddTitleBlock(oNewTBDef)
		Catch
			'what to do if adding TitleBlock fails
		End Try
	Next oSheet
	'MsgBox(oBorderName)
	oActiveSheet.Activate 'activate originally active sheet again
	'MsgBox("test: rule UpdateDrwRecources is executed now")
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) :thumbs_up:.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)