- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello.
I have a problem with an ilogic that is called from an add-inn.
We are using an add-inn (not made by me) that executes an ilogic named "start" when the inventor file is saved.
doc = ThisDoc.Document
oDoc = ThisApplication.ActiveDocument
Dim docType As DocumentTypeEnum = doc.DocumentType
' docSubType As String = doc.SubType
Dim docSubType As String = oDoc.SubType
Select Case docType
Case DocumentTypeEnum.kAssemblyDocumentObject
'IAM
iLogicVb.RunExternalRule("MassProperty")
iLogicVb.RunExternalRule("DisplayName")
Case DocumentTypeEnum.kDrawingDocumentObject
'idw/dwg
'iLogicVb.RunExternalRule("DisplayName")
iLogicVb.RunExternalRule("Mass Drawing")
iLogicVb.RunExternalRule("UpdateDrwResources")
'iLogicVb.RunExternalRule("update_drawing_rcsrcs_for_new_drw")
Case DocumentTypeEnum.kPartDocumentObject
'ipt
iLogicVb.RunExternalRule("DisplayName")
iLogicVb.RunExternalRule("MassProperty")
iLogicVb.RunExternalRule("MaterialGrade")
If docSubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}"
'Sheet Metal
iLogicVb.RunExternalRule("SheetMetalExtents")
Else If docSubType = "{4D29B490-49B2-11D0-93C3-7E0706000000}"
' "Vanlig" part
iLogicVb.RunExternalRule("PartExtents")
End If
End Select
In case it is a drawing the ilogic "Start" fires up an iLogic named "UpdateDrwRecources".
When I execute the ilogic "Start" through our add-inn (by saving the drawing) the iLogic "UpdateDrwRecources" will be found and executed but not in a sufficient way. I can see by using message boxes in that iLogic "UpdateDrwRecources" that it is executed but it is also supposed to delete drawing borders and replace those with latest from the drawing template...which is not happening.
But when I execute the iLogic "Start" manually from the external iLogic tab, everything is working as supposed.
Is it possible that certain operations within the iLogic (like deleting borders) is not possible when executed initially by the ad-inn?
(I know it is a quite nested logic and could be probably done in better way but here it is set-up like this at the moment.)
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi @Jakob_Hamburg. When you say these iLogic rules get ran "at save", do you mean 'before' or 'after' the save? If these things are being done to the drawing 'after' the save, then those changes will not be saved. So, if your drawing gets closed after that, then those changes would get lost. This is one reason that it is usually recommended to make changes to documents before they save, rather than after they save.
Also, why are you using two different code phrases to set the values of two different variables at the start of the rule, but not 'declaring' either variable (using 'Dim' or similar), and not specifying that they will be 'Document' type variables? Then you are using one variable for checking DocumentType, while using the other variable when checking SubType. In some situations, those two code phrases can return different documents.
Also, I would suggest that you use a slightly different method for running your rules.
Instead of using this method: ILowLevelSupport.RunExternalRule Method (String) [iLogicVb.RunExternalRule(sExternalRuleName)], you should try using the very similar IiLogicAutomation.RunExternalRule Method [iLogicVb.Automation.RunExternalRule(oDoc, sExternalRuleName)], which allows you to specify a Document object for the external rule to focus on. This method gives us an extra step of control. However, your external rule must be set-up properly to be able to recognize that Document specification, in order for it to work properly. That usually means using the 'ThisDoc.Doument' code phrase to acquire/specify which Document you want your rule focused on, instead of the 'ThisApplication.ActiveDocument' code phrase.
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi @WCrihfield.
Thank you very much for your explanations.
I am running these iLogic "before" save.
You are totally right with the mess in my iLogic rules...(I inherited those rules and try not touch too much since they are running..but only running until I have to make some modification due to new requirements.)
I updated the iLogic "Start" but that is not the cause of the problem, I think.
'Dim oDoc As Document = ThisDoc.Document
Dim oDoc As Document = ThisApplication.ActiveDocument
Dim docType As DocumentTypeEnum = oDoc.DocumentType
' docSubType As String = doc.SubType
Dim docSubType As String = oDoc.SubType
Select Case docType
Case DocumentTypeEnum.kAssemblyDocumentObject
'IAM
iLogicVb.RunExternalRule("MassProperty")
iLogicVb.RunExternalRule("DisplayName")
Case DocumentTypeEnum.kDrawingDocumentObject
'idw/dwg
'iLogicVb.RunExternalRule("DisplayName")
iLogicVb.RunExternalRule("Mass Drawing")
iLogicVb.Automation.RunExternalRule(oDoc,"UpdateDrwResources")
'iLogicVb.RunExternalRule("update_drawing_rcsrcs_for_new_drw")
Case DocumentTypeEnum.kPartDocumentObject
'ipt
iLogicVb.RunExternalRule("DisplayName")
iLogicVb.RunExternalRule("MassProperty")
iLogicVb.RunExternalRule("MaterialGrade")
If docSubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}"
'Sheet Metal
iLogicVb.RunExternalRule("SheetMetalExtents")
Else If docSubType = "{4D29B490-49B2-11D0-93C3-7E0706000000}"
' "Vanlig" part
iLogicVb.RunExternalRule("PartExtents")
End If
End Select
The ilogic "Start" fires up an iLogic named "UpdateDrwRecources". And that "UpdateDrwRecources" is working differntly based on how it is executed.
We have an add-in that executes "before save" the ilogic "Start". When the (external) ilogic is executed manually instead by "run rule" it acts as it should.
(I will describe the behaviour in a few minutes)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
The problem is in the iLogic named "UpdateDrwRecources".
The rule basically deletes all drawing recourses and afterward adds/replaces them by the ones from the drawing template.
When the rule is executed from the add-inn the deleting of existing borders (for example) is not working.
This screenshot shows the add-inn to execute the ilogic "Start"
When I outcomment the last step of the iLogic "UpdateDrwRecources" in which new drawing recources are added, I can see that the deleting is not happening, if the rule is executed initially by the add-inn (via ilogic Start in between):
(the rule itself is running if executed by add-inn, I could check that with message boxes)
sorry for the messy code:
Sub main
'List of Variables
Dim oDrawingDoc As Inventor.DrawingDocument
Dim oSheetNumber As Integer
Dim oActiveSheetNumber As Integer
Dim oActiveSheetName As String
Dim oSheet As Sheet
Dim oSourceTitleBlockDef As TitleBlockDefinition
Dim oNewTitleBlockDef As TitleBlockDefinition
Dim oBorderName As String
'Selects this document
'oDrawingDoc = ThisApplication.ActiveDocument
oDrawingDoc = ThisDoc.Document
'Checks if there is a Title Block on the Active Sheet
'oDrawingDoc = ThisApplication.ActiveDocument
If oDrawingDoc.ActiveSheet.TitleBlock Is Nothing Then
MessageBox.Show ("Please Insert a Title Block on this Sheet!")
Exit Sub
End If
'Gets the Name of the Active Sheet to Activate it at the end of the Code
oActiveSheetName = ActiveSheet.Name
'Gets the Name of the Title Block Currently in the Drawing to Insert at the end of this code
oSheet = oDrawingDoc.ActiveSheet
If (oSheet.TitleBlock.Name = "company_name Title block") Then
oTitleBlockName = "company_name Title block"
Else:
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
oBorderName = oSheet.Border.Name
Catch
MessageBox.Show("No border exists", "Title")
Exit Sub
End Try
'Deletes ALL of the Title Blocks Shown in the Drawing
For oSheetNumber = 1 To oDrawingDoc.Sheets.Count
oDrawingDoc.Sheets(oSheetNumber).Activate
If Not oDrawingDoc.ActiveSheet.TitleBlock Is Nothing Then
oDrawingDoc.ActiveSheet.TitleBlock.Delete
End If
Next oSheetNumber
'MessageBox.Show (oActiveSheetName & vbCr & oTitleBlockName)
Dim oTitle As TitleBlockDefinition
Dim oTitleBlock As TitleBlock
For Each oTitle In oDrawingDoc.TitleBlockDefinitions
If oTitle.IsReferenced = False Then
oTitle.Delete
End If
Next
'Deletes ALL of the Borders Shown in the Drawing
For oSheetNumber = 1 To oDrawingDoc.Sheets.Count
oDrawingDoc.Sheets(oSheetNumber).Activate
If Not oDrawingDoc.ActiveSheet.Border Is Nothing Then
oDrawingDoc.ActiveSheet.Border.Delete
End If
Next oSheetNumber
'Clear drawing resources
If oCurrentPane = "Vault" Then
ThisApplication.ActiveDocument.BrowserPanes.Item("Model").Activate
End If
'delete sheet formats
Dim oDoc As DrawingDocument
oDoc = ThisApplication.ActiveEditDocument
Dim oPane As BrowserPane
oPane = oDoc.BrowserPanes.ActivePane
Dim oDocNode As BrowserNode
oDocNode = oPane.TopNode
Dim oDrawingResourceNode As BrowserNode
oDrawingResourceNode = oDocNode.BrowserNodes.Item("Drawing Resources")
Dim oTitleBlocksNode As BrowserNode
oTitleBlocksNode = oDrawingResourceNode.BrowserNodes.Item("Sheet Formats")
Dim oBordersNode As BrowserNode
oBordersNode = oDrawingResourceNode.BrowserNodes.Item("Borders")
Dim oTitleBlocks As BrowserNode
oTitleBlocks = oDrawingResourceNode.BrowserNodes.Item("Title Blocks")
Dim oNode As BrowserNode
For Each oNode In oTitleBlocksNode.BrowserNodes'oDocNode.BrowserNodes
' If the node is visible and expanded, collapse it.
If oNode.Visible = True And oNode.Expanded = False Then
oNode.Expanded = True
End If
Next
For Each oNode In oBordersNode.BrowserNodes'oDocNode.BrowserNodes
' If the node is visible and expanded, collapse it.
If oNode.Visible = True And oNode.Expanded = False Then
oNode.Expanded = True
End If
Next
For Each oNode In oTitleBlocks.BrowserNodes'oDocNode.BrowserNodes
' If the node is visible and expanded, collapse it.
If oNode.Visible = True And oNode.Expanded = False Then
oNode.Expanded = True
End If
Next
Dim oSheetFormatNode As BrowserNode
For Each oSheetFormatNode In oTitleBlocksNode.BrowserNodes
' Select the node in the browser.
oSheetFormatNode.DoSelect
' Execute the delete command.
ThisApplication.CommandManager.ControlDefinitions.Item("AppDeleteCmd").Execute
Next
'Dim oBordersNode As BrowserNode
For Each oBordersNode In oBordersNode.BrowserNodes
' Select the node in the browser.
oBordersNode.DoSelect
' Execute the delete command.
ThisApplication.CommandManager.ControlDefinitions.Item("AppDeleteCmd").Execute
Next
For Each oTitleBlocks In oTitleBlocks.BrowserNodes
' Select the node in the browser.
oTitleBlocks.DoSelect
' Execute the delete command.
ThisApplication.CommandManager.ControlDefinitions.Item("AppDeleteCmd").Execute
Next
'Adds the Title Blocks from the Template File
ThisDrawing.ResourceFileName = "C:\WS_company_name\Templates\Standard.idw"
ThisDrawing.KeepExtraResources = True
'ActiveSheet.TitleBlock = "company_name Title block"
'ActiveSheet.Border = oBorderName
'Add Borders
ActiveSheet.Border = "A1"
ActiveSheet.Border = "A2"
ActiveSheet.Border = "A3"
ActiveSheet.Border = "A4"
ActiveSheet.Border = "A0"
''Adds the Same Title Block as in the initial drawing
''due to the fact that we use different title blocks for different sub-companies we do not bring in the title block from the template anymore
For oSheetNumber = 1 To oDrawingDoc.Sheets.Count
oDrawingDoc.Sheets(oSheetNumber).Activate
ActiveSheet.TitleBlock = oTitleBlockName
ActiveSheet.Border = oBorderName
Next oSheetNumber
'MsgBox(oBorderName)
''Activates the Sheet by Full Name
ActiveSheet = ThisDrawing.Sheet(oActiveSheetName)
'MsgBox("test: rule UpdateDrwRecources is executed now")
End Sub
I cannot figure out if there is a limitation to execute the delete command
' Execute the delete command. ThisApplication.CommandManager.ControlDefinitions.Item("AppDeleteCmd").Execute Next
or if my code is not clear enough and it is unclear in which document the deleting should happen.
As I said, when the iLogic "Start" and through that the iLogic "UpdateDrwRecources" is run manually everything is working.
Do you have an advice for me?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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)
.
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi @WCrihfield ,
Thank you so much for your good explanation.
Thank you for your code.
Unfortunately the rule cannot delete all the borders.
in the above code it says:
'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
The problem seems to be that those borders are "referenced" and therefore cannot be deleted.
I do not quite understand, why those borders are referenced since they are not on the sheets (because your code deletes the borders on the sheets in line 31).
Is it, that Inventor has not realized that they have been deleted and that is why they are still referenced?
(Autodesk help says: A border definition is referenced whenever it is used on a sheet. A referenced border definition cannot be deleted.)
Since the rule cannot delete the borders it adds "copy of..".
Do you know how to delete the initial borders in the drawing recourses?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
sorry..I think your code is fine.
I see why the borders are referenced. It is because my drawing template has sheet formats in it.
Those somehow keep the borders referenced.
I should get those deleted first. (But have to figure out why they are there in the first place.)
I added a piece of code in your code above (after line 33). now it is working.
I added:
'delete all sheet formats For Each oSFDef As SheetFormat In oDrawingDoc.SheetFormats oSFDef.Delete Next 'delete all unreferenced TitleBlockDefinitions