Understanding the title block macro in CATIA V5

CATIA gives its users the possibility to use a VBscript macro to generate Title Blocks automatically adjusted to any drawing format. A few macros are provided by default. Users can customize frames and title blocks by either modifying one the default title block macros or by creating their own macros.

The default macros are stored in the install_root/intel_a/VBScript/FrameTitleBlock directory and have a .CATScript extension. We can specify another location in the Tools > Options > Mechanical Design > Drafting > Layout tab.

A macro is comprised of Sub procedures and functions. When the Insert Frame and Title Block dialog box is displayed, it will show a set of actions predefined in the macro. Those actions are Sub procedures prefixed using CATDrw_.

For instance, the Creation action looks like this:

Sub CATDrw_Creation( targetSheet as CATIABase )
'-------------------------------------------------------------------------------
'How to create the FTB
'-------------------------------------------------------------------------------
If Not CATInit(targetSheet) Then Exit Sub
If CATCheckRef(1) Then Exit Sub 'To check whether a FTB exists already in the sheet
CATCreateReference 'To place on the drawing a reference point
CATFrame 'To draw the frame
CATCreateTitleBlockFrame 'To draw the geometry
CATTitleBlockText 'To fill in the title block
CATColorGeometry 'To change the geometry color
CATExit targetSheet 'To save the sketch edition
End Sub

Contents

CATInit()

When creating the Title Block, the first thing to do is activate the sheet and the view calling the CATInit() function. This function will initialize the dialog and create main objects. A simplified version of this function can be a Sub procedure with just the following:

Sub CATinit()
'-----------------------------------------------------------------------------
'How to init the dialog and create main objects
'-----------------------------------------------------------------------------
Set DrwDocument = CATIA.ActiveDocument
Set DrwSheets = DrwDocument.Sheets
Set Selection = DrwDocument.Selection
Set Drw.Sheet = DrwSheets.ActiveSheet
Set DrwView = DrwSheet.Views.ActiveView
Set DrwTexts = DrwView.Texts
Set Fact = DrwView.Factory2D
Set GeomElems = DrwView.GeometricElements
 
End Sub

CATCreateReference()

The next step is to create the frame’s overall dimensions and reference point. The default offset value is of 10 mm, while for sheets bigger than a DIN A2, this values grows to 20 mm. The reference point will tell other title block macros that there’s already a title block created. The reference text will also be used to check if the macro can make some actions like delete, update or resize on the existing Title Block.

Function GetMacroID() as String
GetMacroID = "Drawing_Titleblock_theansweris27_EN"
End Function
Function GetOffset() as Double
If Sheet.PaperSize = CatPaperA0 Or Sheet.PaperSize = CatPaperA1 Or ( Sheet.PaperSize = CatPaperUser And (GetWidth() > 594. Or GetHeight() > 594.)) Then
GetOffset = 20.
Else
GetOffset = 10.
End If
End Function
Sub CATCreateReference()
'-------------------------------------------------------------------------------
'How to create a reference text
'-------------------------------------------------------------------------------
Set Text = Texts.Add("", GetWidth() - GetOffset(), GetOffset())
Text.Name = "Reference_" + GetMacroID
End Sub

CATFrame()

The frame —which is composed of a border, some centring marks, letters and a ruler— will enclose the drafts that we create from our products and assemblies.

Sub CATFrame()
'-------------------------------------------------------------------------------
'How to create the Frame
'-------------------------------------------------------------------------------
Dim Cst_1 As Double 'Length (in cm) between 2 horinzontal marks
Dim Cst_2 As Double 'Length (in cm) between 2 vertical marks
Dim Nb_CM_H As Integer 'Number/2 of horizontal centring marks
Dim Nb_CM_V As Integer 'Number/2 of vertical centring marks
Dim Ruler As Integer 'Ruler length (in cm)
 
CATFrameStandard Nb_CM_H, Nb_CM_V, Ruler, Cst_1, Cst_2
CATFrameBorder
CATFrameCentringMark Nb_CM_H, Nb_CM_V, Ruler, Cst_1, Cst_2
CATFrameText Nb_CM_H, Nb_CM_V, Ruler, Cst_1, Cst_2
CATFrameRuler Ruler, Cst_1
End Sub

The CATFrameStandard Sub procedure defines the length between two horizontal/vertical marks Cst_, computes the number of centring marks Nb_CM_, and computes the maximum Ruler lenght. The spacing values are divisors of the ISO A series paper size standard.

Sub CATFrameStandard(Nb_CM_H As Integer, Nb_CM_V As Integer, Ruler As Integer, Cst_1 As Double, Cst_2 As Double)
'-------------------------------------------------------------------------------
'How to compute standard values
'-------------------------------------------------------------------------------
Cst_1 = 74.2 '297, 594, 1189 are multiples of 74.2
Cst_2 = 52.5 '210, 420, 841 are multiples of 52.2
 
If Sheet.Orientation = CatPaperPortrait And _
(Sheet.PaperSize = CatPaperA0 Or _
Sheet.PaperSize = CatPaperA2 Or _
Sheet.PaperSize = CatPaperA4) Or _
Sheet.Orientation = CatPaperLandscape And _
(Sheet.PaperSize = CatPaperA1 Or _
Sheet.PaperSize = CatPaperA3) Then
Cst_1 = 52.5
Cst_2 = 74.2
End If
 
Nb_CM_H = CInt(.5 * GetWidth() / Cst_1)
Nb_CM_V = CInt(.5 * GetHeight() / Cst_2)
Ruler = CInt((Nb_CM_H - 1) * Cst_1 / 50) * 100 'here is computed the maximum ruler length
 
If GetRulerLength() < Ruler Then Ruler = GetRulerLength()
End Sub

Once some basic lengths have been defined, the CATFrameBorder Sub procedure draws the border while the CATCentringMark Sub procedure generates the centring marks and the CATFrameText Sub procedure writes the numbers and letters —starting from Chr(65), corresponding to capital letter A— in the frame.

Sub CATFrameBorder()
'-------------------------------------------------------------------------------
'How to draw the frame border
'-------------------------------------------------------------------------------
On Error Resume Next
CreateLine GetOV(), GetOV() , GetOH(), GetOV() , "Frame_Border_Bottom"
CreateLine GetOH(), GetOV() , GetOH(), GetHeight() - GetOffset(), "Frame_Border_Left"
CreateLine GetOH(), GetHeight() - GetOffset(), GetOV(), GetHeight() - GetOffset(), "Frame_Border_Top"
CreateLine GetOV(), GetHeight() - GetOffset(), GetOV(), GetOV() , "Frame_Border_Right"
If Err.Number <> 0 Then Err.Clear
On Error Goto 0
End Sub
Sub CATFrameCentringMark(Nb_CM_H As Integer, Nb_CM_V As Integer, Ruler As Integer, Cst_1 As Double, Cst_2 As Double)
'-------------------------------------------------------------------------------
'How to draw the centring marks
'-------------------------------------------------------------------------------
On Error Resume Next
CreateLine .5 * GetWidth() , GetHeight() - GetOffset(), .5 * GetWidth(), GetHeight() , "Frame_CentringMark_Top"
CreateLine .5 * GetWidth() , GetOV() , .5 * GetWidth(), .0 , "Frame_CentringMark_Bottom"
CreateLine GetOV() , .5 * GetHeight() , .0 , .5 * GetHeight(), "Frame_CentringMark_Left"
CreateLine GetWidth() - GetOffset(), .5 * GetHeight() , GetWidth() , .5 * GetHeight(), "Frame_CentringMark_Right"
For i = Nb_CM_H To Ruler/2/Cst_1 Step -1
If (i * Cst_1 < .5 * GetWidth() - 1.) Then
x=.5 * GetWidth() + i * Cst_1
CreateLine x, GetOV(), x, .25 * GetOffset(), "Frame_CentringMark_Bottom_"&Int(x)
x=.5 * GetWidth() - i * Cst_1
CreateLine x, GetOV(), x, .25 * GetOffset(), "Frame_CentringMark_Bottom_"&Int(x)
End If
Next
For i = 1 To Nb_CM_H
If (i * Cst_1 < .5 * GetWidth() - 1.) Then
x=.5 * GetWidth() + i * Cst_1
CreateLine x, GetHeight() - GetOffset(), x, GetHeight() - .25 * GetOffset(), "Frame_CentringMark_Top_"&Int(x)
x=.5 * GetWidth() - i * Cst_1
CreateLine x, GetHeight() - GetOffset(), x, GetHeight() - .25 * GetOffset(), "Frame_CentringMark_Top_"&Int(x)
End If
Next
 
For i = 1 To Nb_CM_V
If (i * Cst_2 < .5 * GetHeight() - 1.) Then
y= .5 * GetHeight() + i * Cst_2
CreateLine GetOV(), y, .25 * GetOffset(), y, "Frame_CentringMark_Left_"&Int(y)
CreateLine GetOH(), y, GetWidth() - .25 * GetOffset(), y, "Frame_CentringMark_Right_"&Int(y)
y= .5 * GetHeight() - i * Cst_2
CreateLine GetOV(), y, .25 * GetOffset(), y, "Frame_CentringMark_Left_"&Int(y)
CreateLine GetOH(), y, GetWidth() - .25 * GetOffset(), y, "Frame_CentringMark_Right_"&Int(y)
End If
Next
If Err.Number <> 0 Then Err.Clear
On Error Goto 0
End Sub
Sub CATFrameText(Nb_CM_H As Integer, Nb_CM_V As Integer, Ruler As Integer, Cst_1 As Double, Cst_2 As Double)
'-------------------------------------------------------------------------------
'How to create coordinates
'-------------------------------------------------------------------------------
On Error Resume Next
 
For i = Nb_CM_H To (Ruler/2/Cst_1 + 1) Step -1
CreateText Chr(65 + Nb_CM_H - i) ,.5 * GetWidth() + (i - .5) * Cst_1,.5 * GetOffset(),"Frame_Text_Bottom_1_"&Chr(65 + Nb_CM_H - i)
CreateText Chr(64 + Nb_CM_H + i) ,.5 * GetWidth() - (i - .5) * Cst_1,.5 * GetOffset(),"Frame_Text_Bottom_2_"&Chr(65 + Nb_CM_H + i)
Next
 
For i = 1 To Nb_CM_H
t=Chr(65 + Nb_CM_H - i)
CreateText(t,.5 * GetWidth() + (i - .5) * Cst_1,GetHeight() - .5 * GetOffset(),"Frame_Text_Top_1_"&t).Angle=-90
t=Chr(64 + Nb_CM_H + i)
CreateText(t,.5 * GetWidth() - (i - .5) * Cst_1,GetHeight() - .5 * GetOffset(),"Frame_Text_Top_2_"&t).Angle=-90
Next
 
For i = 1 To Nb_CM_V
t=CStr(Nb_CM_V + i)
CreateText t ,GetWidth() - .5 * GetOffset(),.5 * GetHeight() + (i - .5) * Cst_2,"Frame_Text_Right_1_"&t
CreateText(t ,.5 * GetOffset() ,.5 * GetHeight() + (i - .5) * Cst_2,"Frame_Text_Left_1_"&t).Angle=-90
 
t=CStr(Nb_CM_V - i + 1)
CreateText t ,GetWidth() - .5 * GetOffset(),.5 * GetHeight() - (i - .5) * Cst_2,"Frame_Text_Right_1_"&t
CreateText(t ,.5 * GetOffset() ,.5 * GetHeight() - (i - .5) * Cst_2,"Frame_Text_Left_2"&t).Angle=-90
Next
 
If Err.Number <> 0 Then Err.Clear
On Error Goto 0
End Sub

The CATFrameRuler Sub procedure creates a small ruler at the bottom of the document to use as a reference for sizes. The bigger marks in the ruler are spaced at intervals of 5 cm while the smaller marks are spaced at intervals of 1 cm.

Sub CATFrameRuler(Ruler As Integer, Cst_1 As Single)
'-------------------------------------------------------------------------------
'How to create a ruler
'-------------------------------------------------------------------------------
'Frame_Ruler_Guide -----------------------------------------------
'Frame_Ruler_1cm | | | | | | | | | | | | | | | | | | | | | | | |
'Frame_Ruler_5cm | | | | |
 
On Error Resume Next
CreateLine .5 * GetWidth() - Ruler/2 , .75 * GetOffset(), .5 * GetWidth() + Ruler/2, .75 * GetOffset(), "Frame_Ruler_Guide"
 
For i = 1 To Ruler/100
CreateLine .5 * GetWidth() - 50 * i, GetOV(), .5 * GetWidth() - 50 * i, .5 * GetOffset() , "Frame_Ruler_1_"&i
CreateLine .5 * GetWidth() + 50 * i, GetOV(), .5 * GetWidth() + 50 * i, .5 * GetOffset() , "Frame_Ruler_2_"&i
For j = 1 To 4
CreateLine .5 * GetWidth() - 50 * i + 10 * j, GetOV(), .5 * GetWidth() - 50 * i + 10 * j, .75 * GetOffset(), "Frame_Ruler_3"&i&"_"&j
CreateLine .5 * GetWidth() + 50 * i - 10 * j, GetOV(), .5 * GetWidth() + 50 * i - 10 * j, .75 * GetOffset(), "Frame_Ruler_4"&i&"_"&j
Next
Next
 
If Err.Number <> 0 Then Err.Clear
On Error Goto 0
End Sub
Sub CATDeleteTitleBlockFrame()
DeleteAll "CATDrwSearch.2DGeometry.Name=TitleBlock_Line_*"
End Sub

CATCreateTitleBlockFrame()

This is one of the most interesting Sub procedures in the Title Block’s creation process in terms of customization. In this procedure we create all the blocks that will contain our own information and information about the product such as title, scale, drawer, supervisor, weight, part number, etc.

Sub CATCreateTitleBlockFrame()
'-------------------------------------------------------------------------------
'How to draw the title block geometry
'-------------------------------------------------------------------------------
CreateLine GetOH() + Col(1), GetOV() , GetOH() , GetOV() , "TitleBlock_Line_Bottom"
CreateLine GetOH() + Col(1), GetOV() , GetOH() + Col(1), GetOV() + Row(6), "TitleBlock_Line_Left"
CreateLine GetOH() + Col(1), GetOV() + Row(6), GetOH() , GetOV() + Row(6), "TitleBlock_Line_Top"
CreateLine GetOH() , GetOV() + Row(6), GetOH() , GetOV() , "TitleBlock_Line_Right"
CreateLine GetOH() + Col(3), GetOV() + Row(1), GetOH() , GetOV() + Row(1), "TitleBlock_Line_Row_1"
CreateLine GetOH() + Col(1), GetOV() + Row(2), GetOH() + Col(3), GetOV() + Row(2), "TitleBlock_Line_Row_2"
CreateLine GetOH() + Col(1), GetOV() + Row(3), GetOH() , GetOV() + Row(3), "TitleBlock_Line_Row_3"
CreateLine GetOH() + Col(1), GetOV() + Row(4), GetOH() + Col(3), GetOV() + Row(4), "TitleBlock_Line_Row_4"
CreateLine GetOH() + Col(3), GetOV() + Row(5), GetOH() , GetOV() + Row(5), "TitleBlock_Line_Row_5"
CreateLine GetOH() + Col(2), GetOV() , GetOH() + Col(2), GetOV() + Row(4), "TitleBlock_Line_Column_1"
CreateLine GetOH() + Col(3), GetOV() , GetOH() + Col(3), GetOV() + Row(6), "TitleBlock_Line_Column_2"
CreateLine GetOH() + Col(4), GetOV() + Row(1), GetOH() + Col(4), GetOV() + Row(3), "TitleBlock_Line_Column_3"
CreateLine GetOH() + Col(5), GetOV() , GetOH() + Col(5), GetOV() + Row(1), "TitleBlock_Line_Column_4"
CreateLine GetOH() + Col(6), GetOV() , GetOH() + Col(6), GetOV() + Row(1), "TitleBlock_Line_Column_5"
CreateLine GetOH() + Col(7), GetOV() , GetOH() + Col(7), GetOV() + Row(1), "TitleBlock_Line_Column_6"
CreateLine GetOH() + Col(8), GetOV() + Row(1), GetOH() + Col(8), GetOV() + Row(3), "TitleBlock_Line_Column_7"
End Sub

The different blocks are 2D lines created using the CreateLine function, which accepts a set of coordinates —line start and line end— and the name of the line.

Function CreateLine( iX1 As Double, iY1 As Double, iX2 As Double, iY2 As Double, iName As String) As Curve2D

The columns and rows have been defined assisted by constants Col and Row taking the lower-right corner of the frame as the reference point:

Function Col(idx As Integer) As Variant
Col=Array(-190, -145, -125, -110, -95, -50, -30, -15)(idx-1)
End Function

Function Row(idx As Integer) As Variant
Row=Array( 10, 12, 24, 36, 40, 60)(idx-1)
End Function

CATTitleBlockText()

Now that we have the blocks, it’s time to fill them with content. The CATTitleBlockText Sub procedure will do most of the job for us. This procedure we can use to define our own names to display, like the name of the company who owns the drawing. It’s also where we can change the displayed texts in case we want the title block in Spanish or German.

Sub CATTitleBlockText()
'-------------------------------------------------------------------------------
'How to fill in the title block
'-------------------------------------------------------------------------------
Text_01 = "DESIGNED BY"
Text_02 = "P. Fernández"
Text_03 = "DATE"
Text_04 = "XXX"
Text_05 = "CHECKED BY"
Text_06 = "DRAWN BY"
Text_07 = "This drawing is our property." + Chr(10) + _
"It can't be reproduced" + Chr(10) + _
"or communicated without" + Chr(10) + _
"our written agreement."
Text_08 = "SCALE"
Text_09 = "WEIGHT(kg)"
Text_10 = "SHEET"
Text_11 = "SIZE"
Text_12 = "XXX" ' Paper Format
Text_13 = "DRAWING NUMBER"
Text_14 = "REV"
Text_15 = "X"
Text_16 = "DRAWING TITLE"
Text_17 = "THE ANSWER IS 27"
 
CreateTextAF Text_01,GetOH() + Col(1) + 1. ,GetOV() + Row(2) ,"TitleBlock_Text_Design" ,catTopLeft ,3
CreateTextAF Text_04,GetOH() + Col(1) + 1. ,GetOV() ,"TitleBlock_Text_Design_1" ,catBottomLeft ,4
CreateTextAF Text_03,GetOH() + Col(2) + 1. ,GetOV() + Row(2) ,"TitleBlock_Text_DeDate" ,catTopLeft ,3
CreateTextAF Text_04,GetOH() + .5*(Col(2)+Col(3)),GetOV() ,"TitleBlock_Text_DeDate_1" ,catBottomCenter,2
CreateTextAF Text_05,GetOH() + Col(1) + 1. ,GetOV() + Row(3) ,"TitleBlock_Text_Check" ,catTopLeft ,3
CreateTextAF Text_04,GetOH() + Col(1) + 1. ,GetOV() + Row(2) ,"TitleBlock_Text_Check_1" ,catBottomLeft ,4
CreateTextAF Text_03,GetOH() + Col(2) + 1. ,GetOV() + Row(3) ,"TitleBlock_Text_CDate" ,catTopLeft ,3
CreateTextAF Text_04,GetOH() + .5*(Col(2)+Col(3)),GetOV() + Row(2) ,"TitleBlock_Text_CDate_1" ,catBottomCenter,2
CreateTextAF Text_06,GetOH() + Col(1) + 1. ,GetOV() + Row(4) ,"TitleBlock_Text_Drawn" ,catTopLeft ,3
CreateTextAF Text_02,GetOH() + Col(1) + 1. ,GetOV() + Row(3) ,"TitleBlock_Text_Drawn_1" ,catBottomLeft ,4
CreateTextAF Text_03,GetOH() + Col(2) + 1. ,GetOV() + Row(4) ,"TitleBlock_Text_DrDate" ,catTopLeft ,3
CreateTextAF ""&Date,GetOH() + .5*(Col(2)+Col(3)),GetOV() + Row(3) ,"TitleBlock_Text_DrDate_1" ,catBottomCenter,2
CreateTextAF Text_07,GetOH() + .5*(Col(1)+Col(3)),GetOV() + .5*(Row(6)+Row(4)),"TitleBlock_Text_Rights" ,catMiddleCenter,2.5
CreateTextAF Text_08,GetOH() + Col(3) + 1 ,GetOV() + .5*Row(1) ,"TitleBlock_Text_Scale" ,catMiddleLeft ,3
' Insert Text Attribute link on sheet's scale
Set Text=CreateTextAF("" ,GetOH() + Col(5) - 1 ,GetOV() + .5*Row(1) ,"TitleBlock_Text_Scale_1" ,catMiddleRight,3)
Select Case GetContext():
Case "LAY": Text.InsertVariable 0, 0, ActiveDoc.Part.GetItem("CATLayoutRoot").Parameters.Item(ActiveDoc.Part.GetItem("CATLayoutRoot").Name+"\"+Sheet.Name+"\ViewMakeUp2DL.1\Scale")
Case "DRW": Text.InsertVariable 0, 0, ActiveDoc.DrawingRoot.Parameters.Item("Drawing\"+Sheet.Name+"\ViewMakeUp.1\Scale")
Case Else:Text.Text = "XX"
End Select
 
CreateTextAF Text_09,GetOH() + Col(5) + 1 ,GetOV() + .5*Row(1) ,"TitleBlock_Text_Weight" ,catMiddleLeft ,3
CreateTextAF Text_04,GetOH() + Col(6) - 1 ,GetOV() + .5*Row(1) ,"TitleBlock_Text_Weight_1" ,catMiddleRight ,3
CreateTextAF Text_10,GetOH() + Col(7) + 1 ,GetOV() + .5*Row(1) ,"TitleBlock_Text_Sheet" ,catMiddleLeft ,3
CreateTextAF Text_04,GetOH() - 1 ,GetOV() + .5*Row(1) ,"TitleBlock_Text_Sheet_1" ,catMiddleRight ,3
CreateTextAF Text_11,GetOH() + Col(3) + 1 ,GetOV() + Row(3) ,"TitleBlock_Text_Size" ,catTopLeft ,3
CreateTextAF Text_12,GetOH()+.5*(Col(3)+Col(4)) ,GetOV() + Row(1) ,"TitleBlock_Text_Size_1" ,catBottomCenter,4
CreateTextAF Text_13,GetOH() + Col(4) + 1 ,GetOV() + Row(3) ,"TitleBlock_Text_Number" ,catTopLeft ,3
CreateTextAF Text_04,GetOH()+.5*(Col(4)+Col(8)) ,GetOV() + Row(1) ,"TitleBlock_Text_EnoviaV5_Effectivity" ,catBottomCenter,4
CreateTextAF Text_14,GetOH() + Col(8) + 1 ,GetOV() + Row(3) ,"TitleBlock_Text_Rev" ,catTopLeft ,3
CreateTextAF Text_15,GetOH()+.5*Col(8) ,GetOV() + Row(1) ,"TitleBlock_Text_Rev_1" ,catBottomCenter,4
CreateTextAF Text_16,GetOH() + Col(3) + 1 ,GetOV() + Row(5) ,"TitleBlock_Text_Title" ,catTopLeft ,3
CreateTextAF Text_04,GetOH()+.5*Col(3) ,GetOV() + Row(3) ,"TitleBlock_Text_Title_1" ,catBottomCenter,5
CreateTextAF Text_17,GetOH()+.5*Col(3) ,GetOV()+.5*(Row(5)+Row(6)) ,"TitleBlock_Text_Company" ,catMiddleCenter,6
 
CATLinks
End Sub

The texts are placed inside the blocks with the CreateTextAF function which gets as arguments a string with the caption we want to write, the coordinates of the anchor position, and the font size.

Function CreateTextAF(iCaption as String, iX as Double, iY As Double, iName As String, iAnchorPosition As CatTextAnchorPosition, iFontSize As Double) As DrawingText
'-------------------------------------------------------------------------------
'How to create a text
'-------------------------------------------------------------------------------
Set CreateTextAF = Texts.Add(iCaption, iX, iY)
CreateTextAF.Name = iName
CreateTextAF.AnchorPosition = iAnchorPosition
CreateTextAF.SetFontSize 0, 0, iFontSize
End Function

Examples

I took the Drawing_TitleBlock_Sample2.CATScript file and edited some lines in the CATTitleBlockText Sub procedure to display the name of this blog and my own name as the drawer of the draft.

Landscape A4, English with CATIA V5 title block macro.
Landscape A4, English.
Landscape A3, Spanish with CATIA V5 title block macro.
Landscape A3, Spanish.