CATScript Delete all unused Details

Purpose

This CATScript macro for Catia can be used to delete all unused details which are currently available in one of the available detail sheet(s).

An unused detail hereby is a detail which is not referenced in any of the available drawing views in a CATDrawing.

Usage of the macro

The macro can be used as is, no pre-configuration is needed.

Make sure to back-up your drawing before using this macro.

It is save to use the macro as there is no “file save” operation in place.

So, after macro execution, it is still possible with undo in Catia to roll-back any possible changes performed my the macro.

' -----------------------------------------------------------------------------
' --- DeleteUnusedDetails.CATScript --
' -----------------------------------------------------------------------------
' (c) 2020, Johann Oberdorfer - Engineering Support | CAD | Software
'     johann.oberdorfer [at] gmail.com
'     www.johann-oberdorfer.eu
' -----------------------------------------------------------------------------
' This source file is distributed under the BSD license.
'   This program is distributed in the hope that it will be useful,
'   but WITHOUT ANY WARRANTY; without even the implied warranty of
'   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
'   See the BSD License for more details.
' -----------------------------------------------------------------------------
' -----------------------------------------------------------------------------
'
' Purpose:
'
'   This macro can be used to delete all unused details which are currently
'   available in the detail sheet(s). An unused detail hereby is not referenced
'   in any of the available drawing views in a CATDrawing.
'
' Credits:
'   Thanks to: http://www.tech-ecke.de/index_quereinstieg.htm
'                     ?/catscript/diverse_codeschnipsel.htm
'   where I could find some good inspiration and as well
'   a similar code snippet
'
' -----------------------------------------------------------------------------
' Revision history:
' 20-12-05: Hans, V0.1 initial release
' -----------------------------------------------------------------------------
' Option Explicit
Language = "VBSCRIPT"

Const APP_NAME = "Delete unused Details"
Const APP_VER =  "V0.2"


Function IsDrawingDocument() As Boolean

	Dim doc As Document
    IsDrawingDocument = False

	Err.Clear : On Error Resume Next
	Set doc = CATIA.ActiveDocument
	On Error Goto 0

	If Err.Number <> 0 Then
		Exit Function
	End If

	If ( TypeName(doc) = "DrawingDocument" ) Then
		IsDrawingDocument = True
	End If

End Function

' // note: obj_list() index always starts at position 1 (!)
' // in other words: obj_list(1) represents the 1st value in the list
' //
Sub ObjAppend (ByRef obj_list() As AnyObject, ByVal obj As AnyObject)
	ReDim Preserve obj_list(UBound(obj_list) + 1)
	Set obj_list( UBound(obj_list) ) = obj
End Sub


Sub DeleteSelectedObjects (ByVal sel As Collection, ByVal msg1 As String)

	Dim i,usr As Integer
	Dim msg As String

	Select Case sel.Count
	Case 0
		Msgbox _
			"Delete all unused details:" _
		+	vBNewline _
		+	"No more unused details could be detected.", _
			vbInformation + vbOKOnly, msg1

		Exit Sub
	Case 1
		msg = "There is 1 unused object available." + vBNewline _
			+ "Object name: " _
			+ vBNewline _
			+ "  " + sel.Item(1).Value.Name
	Case Else
		msg = "There are " + CStr(sel.Count) + " unused objects available." _
			+ vBNewline _
			+ "Object names:"
		
		For i = 1 To sel.Count
			msg = msg _
				+ vBNewline _
				+ "  " + sel.Item(i).Value.Name
		Next
		
	End Select

	If ( sel.Count > 0 ) Then

		usr = Msgbox( msg _
				+	vBNewline + vBNewline _
				+	"Do you want to delete ... ?", _
					vbQuestion + vbYesNo, msg1)

		' YES = 6 / NO = 7
		If (usr = 6) Then
			sel.Delete
		End If

		sel.Clear
	End If

End Sub


' // process all available details in detail sheet(s) and
' // check if each individual detail is inserted in any of the
' // available drawing sheets,
' // if not, the detail is added to the selection
' // return value is the number of unused details
' //
Sub DeleteAllUnusedDetails (ByVal active_doc As Document)

	Dim i, j, k As Integer
	Dim in_use As Boolean
	Dim view_name, detail_name As String

	Dim sh As DrawingSheet
	Dim vw As DrawingView
	Dim obj As AnyObject
	Dim sel As Collection

	Dim all_instances() As AnyObject : ReDim all_instances(0)
	Dim all_details()   As AnyObject : ReDim all_details(0)
	Dim noshow_details()  As AnyObject : ReDim noshow_details(0)


	set sel = active_doc.Selection
	
	' clean all details which might be stored in no-show (!)

	For i = 1 to active_doc.Sheets.Count
		Set sh = active_doc.Sheets.Item(i)

		If (Not sh.IsDetail) Then

			' for regular sheet
			' compile a list of all instantiated details, regardless
			' if they  are inserted in "Main View" or "Background View"

			For j = 1 to sh.Views.Count
				Set vw = sh.Views.Item(j)

				For k = 1 to vw.Components.Count
					Set obj = vw.Components.Item(k)

					' determine if an object is in no-show and if yes,
					' add the object to the instance list (!)
					' we assume here, that no-show objects might be an artifact
					' from the past and should be wiped out as well...
					sel.Clear
					sel.Add obj

					Dim objVisProps As VisPropertySet
					Dim showstate  As CatVisPropertyShow

					Set objVisProps = sel.VisProperties
					objVisProps.GetShow showstate

					If (showstate = catVisPropertyNoShowAttr) Then
						' ---------------------------
						ObjAppend noshow_details, obj
						' ---------------------------
					End If
				Next
			Next
		End If
	Next
	
	sel.Clear
	
	If (UBOUND(noshow_details) > 0) Then
		For i = 1 To UBOUND(noshow_details)
			sel.Add noshow_details(i)
		Next
	
		Call DeleteSelectedObjects (sel, "NO-SHOW - Unused Detail search:")
	End If


	' loop through all available drawing sheets ...

	For i = 1 to active_doc.Sheets.Count
		Set sh = active_doc.Sheets.Item(i)

		If (sh.IsDetail) Then

			' for detail sheets
			' compile a list of all available details,
			' "Main View" or "Background View" does not matter...

			For j = 1 to sh.Views.Count

				Set obj = sh.Views.Item(j)
				view_name = obj.Name

				If ( LCase(Left(view_name, 10)) <> "background" And _
					 LCase(Left(view_name, 9))  <> "main view") Then
					' MsgBox view_name
					' ------------------------
					ObjAppend all_details, obj
					' ------------------------
				End If
			Next
		Else
			' for regular sheet
			' compile a list of all instantiated details, regardless
			' if they  are inserted in "Main View" or "Background View"

			For j = 1 to sh.Views.Count
				Set vw = sh.Views.Item(j)

				For k = 1 to vw.Components.Count
					Set obj = vw.Components.Item(k)

					' MsgBox obj.CompRef.Name
					' --------------------------
					ObjAppend all_instances, obj
					' --------------------------
				Next
			Next
		End If
	Next

	sel.Clear

	' loop through all details
	' and compare against instances ...

	For i = 1 to UBOUND(all_details)
		detail_name = all_details(i).Name

		in_use = False

		For j = 1 to UBOUND(all_instances)
			
			' assumption: detail (detail sheet) and instantiated detail
			' share the same name - which should always be the case ...

			If (detail_name = all_instances(j).CompRef.Name) Then
				in_use = True
				Exit For
			End If
		Next

		If (Not in_use) Then
			sel.Add(all_details(i))
		End If
	Next

	Call DeleteSelectedObjects (sel, "Drawing Sheet - Unused Detail search:")

End Sub


Sub DeleteEmptyDetailSheets (ByVal active_doc As Document)

	Dim i, j As Integer
	Dim compounents_available As Boolean

	Dim sh As DrawingSheet
	Dim vw As DrawingView
	Dim sel As Collection

	Dim empty_sheets() As AnyObject : ReDim empty_sheets(0)

	set sel = active_doc.Selection
	sel.Clear
	
	' attempt to clean all empty details sheets ....

	For i = 1 to active_doc.Sheets.Count
		Set sh = active_doc.Sheets.Item(i)

		' "Main View" and "Background" are always available,
		' which means an empty sheet view count is always 2

		If (sh.IsDetail And sh.Views.Count = 2) Then
			sel.Add sh
		End If

	Next
	
	If (sel.Count > 0) Then
		Call DeleteSelectedObjects (sel, "Drawing Sheets - Empty Sheet Search:")
	End If

	sel.Clear
End Sub


' // -----------------------------------------
' // >>> Application execution starts here <<<
' // -----------------------------------------

Sub CATMain ()

	Dim active_doc As Document

	If ( Not IsDrawingDocument() ) Then

		Msgbox _
			"Your active Document type is wrong" + vBNewline _
		+	"or there is no active Drawing available!" _
		+	vBNewline + vBNewline _
		+ 	"Please open a CATDrawing and try again!" _
		,	vbExclamation + vbOKOnly, APP_NAME + " " + APP_VER

		Exit Sub
	End If

	Set active_doc = CATIA.ActiveDocument
	CATIA.RefreshDisplay = False

	' ---------------------------------------
	Call DeleteAllUnusedDetails (active_doc)
	Call DeleteEmptyDetailSheets (active_doc)
	' ---------------------------------------

	CATIA.RefreshDisplay = True

End Sub


' -- EOF ---

Notes

This program is made with and is distributed in the hope that it will be useful, but without any warranty, without even the implied warranty of merchantability or fitness for a particular purpose.