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

duplicate sheet and go to next member in base file using ilogic

raymaster
Contributor

duplicate sheet and go to next member in base file using ilogic

raymaster
Contributor
Contributor

Hello 

 

I have an ipt file with model states, I created a drawing sheet for one model state, using iLogic, I need to duplicate the drawing sheet and replace the base model with the next model state until i finish the 300 models.

 

while creating the new sheet I need to rename the sheet according to the model partnumber.

 

Thanx alot

0 Likes
Reply
357 Views
7 Replies
Replies (7)

WCrihfield
Mentor
Mentor

Hi @raymaster.  Have you ever used SheetFormats?  You could create (Link, Link) a SheetFormat object from the existing sheet with the model view already in it.  Then use Sheets.AddUsingSheetFormat to create each new sheet, and specify the 'model' you want to be in the view(s) on that new sheet.  Also, if the view is already referencing the correct model file, but wrong ModelState within that file, then we can change which ModelState the view is referencing using its DrawingView.SetActiveModelState method.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes

raymaster
Contributor
Contributor

yes I can do it manually, but it will be a monkey work for 300 pages.

thats why I tried to do it through iLogic, as the projects I do consist of more than 200 unit for a floor in 50+ floors' buildings, as for each unit I may have like 6 repetitive parts in different dimensions and model states.

 

so that I need this process automated.

 

Thanx

0 Likes

WCrihfield
Mentor
Mentor

Hi @raymaster.  What I was suggesting was also all code automation, to add to your existing code, to accomplish the added functionality you were looking for.  You said you already have some iLogic code in which you created a drawing sheet for a model with ModelStates, and want to duplicate that sheet for other ModelState versions of that model, and many other models.  I believe that one way you could accomplish that is by creating/using SheetFormats, but by code.  The links I included were for the Inventor API objects and methods involved in creating a new SheetFormat API object, and how to use that SheetFormat to create the next sheet in your drawing.  That method includes supplying a new name for the new sheet, and supplying either a Document object or (FullFileName or FullDocumentName) for 'the model' you want to be represented in the views of the new sheet, and other settings.  However, when reviewing the available settings for the method that creates a new sheet based on a SheetFormat, I did not see a specific setting for specifying ModelState.  If the supplied Document object was already set to the ModelState you want, that might work...or, you could also ensure that the FullDocumentName you supply includes that name of the ModelState at its end (FullDocumentName = FullFileName & "<ModelStateName>").  If you do not, or can not specify the ModelState in one of those two ways, then I mentioned a way that you can change which ModelState an individual DrawingView is set to by code.  This is all just one possible code process plan at this point.  If you think this sounds like a direction you would like to go with your project, then maybe we could help you further develop your existing code in this direction.  The alternative code process would be a bit more granular, creating each new sheet using the regular Sheets.Add() method, then creating each individual view on the new sheet using one of the available DrawingViews.Add type methods.  Using the SheetFormat route just seems a bit simpler, because the SheetFormat already knows the sheet size, orientation, Border, TitleBlock, certain settings, and already includes the views, which the reference model for can easily be changed right when creating the sheet.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

raymaster
Contributor
Contributor

thanks @WCrihfield  this is exactly what I was looking for, but I could not find the right API object to change the "model state" within the base "view".

the functions I look for:

1. duplicate the current sheet 

2. change the "model state" within the existing "view"

3. update the name of the sheet upon the partnumber like so:

	Dim drwDoc As Inventor.DrawingDocument = ThisDrawing.Document
	Dim drwSht As Inventor.Sheet
	
	For Each drwSht In drwDoc.Sheets
		Dim dRef As Inventor.Document = drwSht.DrawingViews.Item(1).ReferencedDocumentDescriptor.ReferencedDocument
		Dim pNum As String = dRef.PropertySets.Item(3).Item( "part number").Value
		drwSht.Name = pNum
	Next

 

 

0 Likes

WCrihfield
Mentor
Mentor

OK.  Those first two steps listed can definitely be tricky.

There is a Sheet.CopyTo() method, which sounds like it should be the right one to use, but it can only be used to copy the sheet to another drawing document, not for copying the sheet within the same drawing document.  It says so right in its online documentation.  That is why I assumed that the only other two options for copying the sheet are to create a SheetFormat based on the existing sheet (even if just a temporary one, that we can delete again later), then use that SheetFormat we just created to create a new sheet exactly the same as the existing one.  Otherwise we would have to create the next sheet the longer way.  The thought does come to mind to use a second, temporary drawing document, copy the sheet to it, then copy it back to the original drawing, but I do not recall if I have tried that idea before, and it may require a bit more system resources/processing/memory.  

 

The DrawingView object has a property named ActiveModelState, which may seem like the way to go, but the problem is that it is a ReadOnly property.  So we can check it, but cant change its value directly.  However, the DrawingView object also has a method (DrawingView.SetActiveModelState) just for setting its value, which also has a couple other optional setting you can specify, such as if you want to update any PartsList that may be based on that view, and if you want to keep any overrides.  I do not know exactly why it is set-up that way, only that this is the way it must be done.  Also, I think this method may only work on 'Base Views', and may not work on other types of view like projected, because they are controlled by the view they are projected from.  It also says that this method will fail if the reference to the model is 'unresolved'.  It does seem like I may have heard of some awkward behavior in this area though, but I can not remember the details, since I do not do a lot of in-depth drawing side automation where I work.

 

If I get a chance later, I may attempt to create some code for this task, test it, and get back with you.  I've got to deal with some other stuff at the moment though.  Sometimes I spread myself too thin across multiple projects (multi-tasking).

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Michiel.Valcke
Advisor
Advisor

Sorry to hijack your post @raymaster 

I was facing a similar issue, but the suggestion of @WCrihfield got me to a working result. The next issue I'm facing is that this method is not copying dimensions that are already placed on the first sheet :disappointed_face: If that could also be done, it would be perfect.

It takes an .idw and uses the single sheet present as a temporary sheetformat. Then it steps through the model states and creates new sheets with names equal to the model states and it changes the model state in the base view for each new sheet created. I also still have to figure out a clean way to skip the [Primary] model state.

 

EDIT: a simple solution to skip the Primary model state is to start counting at 2 at line 27

 

 

' iLogic Rule: Duplicate Sheets for Model States
' This rule duplicates an existing sheet for each model state in the referenced part/assembly,
' updates the base view to match the corresponding model state, and renames the sheet.

' Get the active document (assumes it is a .idw file)
Dim oDrawingDoc As DrawingDocument = ThisApplication.ActiveDocument

' Get the first sheet (this will serve as the template for duplication)
Dim oTemplateSheet As Sheet = oDrawingDoc.Sheets.Item(1)
Dim oSheetFormats As SheetFormats = oDrawingDoc.SheetFormats
Dim oTempSheetFormat As SheetFormat = oSheetFormats.Add(oTemplateSheet,"Geo-IT Temp SheetFormat")

' Get the referenced model from the base view on the template sheet
Dim oBaseView As DrawingView = oTemplateSheet.DrawingViews.Item(1)
Dim oReferencedModel As Document = oBaseView.ReferencedDocumentDescriptor.ReferencedDocument

' Get the model states from the referenced model
Dim oModelStates As ModelStates = oReferencedModel.ComponentDefinition.ModelStates

' Ensure the model states collection is not empty
If oModelStates.Count = 0 Then
    MessageBox.Show("No model states found in the referenced model.", "Error")
    Return
End If

' Loop through the model states and create a sheet for each
For i As Integer = 1 To oModelStates.Count
    Dim oModelState As ModelState = oModelStates.Item(i)
    
    ' Create a new sheet by duplicating the template sheet, reference the model and change the name
    Dim oNewSheet As Sheet = oDrawingDoc.Sheets.AddUsingSheetFormat(oTempSheetFormat,oReferencedModel,oModelState.Name)
    
    ' Update the base view on the new sheet to reference the corresponding model state
    Dim oNewBaseView As DrawingView = oNewSheet.DrawingViews.Item(1)
    oNewBaseView.SetActiveModelState(oModelState.Name)
Next

 'Remove the temp sheet format
 oTempSheetFormat.Delete()

 

 

 

 

 

0 Likes

WCrihfield
Mentor
Mentor

There is actually another way to do this which will preserve all your dimensions and such.  I'm not sure why I did not mention this in any of my earlier posts here.  It seems like I have shown this method in a few other places in the forum before.  Anyways, it uses the basic Copy/Paste system, combined with simulating some user inter face actions, such as selecting the active sheet, executing a command (copy), unselecting that sheet, then executing another command (paste).  It includes some Inventor API code, but is a mix of using API and simulating user interface actions, so it will only work when that drawing is currently the 'active' document (currently fully visible on your screen at that moment).  I even took it another step further and turned it into a separate Function routine, which will then retrieve and return the newly created copy of the active sheet for you.  It is still not 'perfect', but pretty close.  Of course it could still be developed further, such as adding the option to rename the new sheet, and/or repositioning the new sheet to a specific location, instead of just at the end of all existing sheets.  As it is right now, the name of the new sheet will always start with "Copy of ", then the name of the original sheet, but with the new index number at the very end, because we can not control that index number.  Also, if the active sheet (when you run the rule) contains views which have 'parent' views on another sheet, then it will show a small dialog telling you that the parent view must be copied along with the child view, due to the child view being dependent on the parent view, with only an OK button, so it will not copy that sheet.

 

Below is that code example:

Sub Main
	Dim oInvApp As Inventor.Application = ThisApplication
	Dim oDDoc As DrawingDocument = TryCast(oInvApp.ActiveDocument, DrawingDocument)
	If oDDoc Is Nothing Then Return
	Dim oSheet As Inventor.Sheet = oDDoc.ActiveSheet
	Dim oNewCopySheet As Inventor.Sheet = CopySheet(oSheet)
	Logger.Info("New Sheet's Name = " & oNewCopySheet.Name)
End Sub

Function CopySheet(oSheet As Inventor.Sheet) As Inventor.Sheet
	If oSheet Is Nothing Then Return Nothing
	Dim oDDoc As DrawingDocument = oSheet.Parent
	Dim oInvApp As Inventor.Application = oSheet.Application
	If oDDoc.Views.Count = 0 OrElse oDDoc IsNot oInvApp.ActiveDocument Then
		Try 'it must be the 'active' document (visibly showing on your screen)
			oDDoc = oInvApp.Documents.Open(oDDoc.FullDocumentName, True)
			oDDoc.Activate()
		Catch : End Try
	End If
	Dim oCmdMgr As CommandManager = oInvApp.CommandManager
	Dim oCDs As ControlDefinitions = oCmdMgr.ControlDefinitions
	oCmdMgr.DoSelect(oSheet)
	oCDs.Item("AppCopyCmd").Execute()
	oCmdMgr.DoUnSelect(oSheet)
	oCDs.Item("AppPasteCmd").Execute()
	Dim oNewSheet As Inventor.Sheet = oDDoc.Sheets.Item(oDDoc.Sheets.Count)
	Return oNewSheet
End Function

One possible further developed version of that custom Function might look something like this:

Sub Main
	Dim oInvApp As Inventor.Application = ThisApplication
	Dim oDDoc As DrawingDocument = TryCast(oInvApp.ActiveDocument, DrawingDocument)
	If oDDoc Is Nothing Then Return
	Dim oSheet As Inventor.Sheet = oDDoc.ActiveSheet
	
	'<<< if just copying one sheet, expect one Sheet to get returned >>>
	'Dim oNewSheet As Inventor.Sheet = CopySheet(oSheet, 1)
	'Logger.Info("New Sheet's Name = " & oNewSheet.Name)
	
	'OR
	'<<< if creating multiple copies, expect an array of Sheet to be returned >>>
	Dim oNewCopies() As Inventor.Sheet = CopySheet(oSheet, 2, "Sheet 3", "Sheet 4")
	
	Logger.Info("New Sheet Names:")
	For Each oNewCopy In oNewCopies
		Logger.Info(oNewCopy.Name)
	Next
End Sub

Function CopySheet(ByVal oSheet As Inventor.Sheet, _
	iNumberOfCopies As Integer, _
	ByVal ParamArray NewSheetNames() As String) As Object
	If oSheet Is Nothing Then Return Nothing
	If iNumberOfCopies < 1 Then Return Nothing
	Dim bMultipleCopies As Boolean = (iNumberOfCopies > 1)
	Dim bNamesProvided As Boolean = ((NewSheetNames IsNot Nothing) AndAlso (NewSheetNames.Length > 0))
	Dim oDDoc As DrawingDocument = oSheet.Parent
	Dim oInvApp As Inventor.Application = oSheet.Application
	If oDDoc.Views.Count = 0 OrElse oDDoc IsNot oInvApp.ActiveDocument Then
		Try 'it must be the 'active' document (visibly showing on your screen)
			oDDoc = oInvApp.Documents.Open(oDDoc.FullDocumentName, True)
			oDDoc.Activate()
		Catch : End Try
	End If
	Dim oCmdMgr As CommandManager = oInvApp.CommandManager
	Dim oCDs As ControlDefinitions = oCmdMgr.ControlDefinitions
	Dim oCopyCmd As ControlDefinition = oCDs.Item("AppCopyCmd")
	Dim oPasteCmd As ControlDefinition = oCDs.Item("AppPasteCmd")
	Dim oNewSheet As Inventor.Sheet = Nothing
	Dim oNewSheets As List(Of Inventor.Sheet)
	If bMultipleCopies Then oNewSheets = New List(Of Inventor.Sheet) 'initialize it
	For i As Integer = 1 To iNumberOfCopies
		oCmdMgr.DoSelect(oSheet)
		oCopyCmd.Execute()
		oCmdMgr.DoUnSelect(oSheet)
		oPasteCmd.Execute()
		oNewSheet = oDDoc.Sheets.Item(oDDoc.Sheets.Count)
		If bNamesProvided Then
			Try
				oNewSheet.Name = NewSheetNames(i - 1)
			Catch e As Exception
				Logger.Error(e.ToString)
			End Try
		End If
		If bMultipleCopies Then oNewSheets.Add(oNewSheet)
	Next
	If bMultipleCopies Then Return oNewSheets.ToArray
	Return oNewSheet
End Function

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)