Macros – The Voice of Data Architect

by Sep 13, 2023

Introduction

ER/Studio Data Architect supports programmatic event handling.

To better understand when these events are triggered, I’ll share an updated script of the sample macro: ERSBasicHandlers.bas

The option for the Create Handlers has been checked:

Automation options

Automation options

This macro speaks different texts depending on the event.

Moreover, I’ll also share a second macro which reads the definitions of the selected entities|tables.

You can see these 2 macros in action in this video:

Scripts

ERSBasicHandlers.bas

Const VOICE_INDEX%   =  1 ' Change this number to change the voice. Max value depends on your OS.
Const SPEAK_TIMEOUT% = 10 ' Stop speaking after 10s

Const SVSFlagsAsync% =  1
Dim Sapi As Object

Private Sub Read(txt$)

	If Sapi Is Nothing Then
		
		Set Sapi = CreateObject("SAPI.Spvoice")
		Set Sapi.Voice = Sapi.GetVoices.Item(VOICE_INDEX)
		Sapi.Speak "TTS object created!", SVSFlagsAsync

	End If

	' The speaking of the text string
	Sapi.Speak txt, SVSFlagsAsync

	' Blocks the caller until either the voice has finished speaking or the specified time interval has elapsed.
'	Sapi.WaitUntilDone (SPEAK_TIMEOUT * 1000)

End Sub
 
Sub CreateEntityHandler(CurEntity As Object, CurDiagram As Object)

	Dim e As Entity
	Dim d As Diagram
	Set e = CurEntity
	Set d = CurDiagram
	Read IIf(d.ActiveModel.Logical, "Entity""Table") & " created: " & IIf(d.ActiveModel.Logical, e.EntityName, e.TableName)

End Sub

Sub CreateAttributeHandler(CurAttribute As Object, CurDiagram As Object)

	Dim a As AttributeObj
	Dim d As Diagram
	Set a = CurAttribute
	Set d = CurDiagram
	Read IIf(d.ActiveModel.Logical, "Attribute""Column") & " created: " & IIf(d.ActiveModel.Logical, a.AttributeName, a.ColumnName)

End Sub


Sub CreateRelationshipHandler(CurRelationship As Object, CurDiagram As Object)

	Dim rs As Relationship
	Set rs = CurRelationship
	Read "Relationship created: " & rs.Name

End Sub


Sub CreateIndexHandler(CurIndex As Object, CurDiagram As Object)

	Dim i As Index
	Set i = CurIndex
	Read "Index created: " & i.Name

End Sub


Sub CreateModelHandler(CurModel As Object, CurDiagram As Object)

	Dim m As Model
	Set m = CurModel
	Read "Model created: " & m.Name

End Sub


Sub CreateSubModelHandler(CurSubModel As Object, CurDiagram As Object)

	Dim sm As SubModel
	Set sm = CurSubModel
	Read "SubModel created: " & sm.Name

End Sub


Sub CreateDomainHandler(CurDomain As Object, CurDiagram As Object)

	Dim d As Domain
	Set d = CurDomain
	Read "Domain created: " & d.Name

End Sub


Sub CreateDefaultHandler(CurDefault As Object, CurDiagram As Object)

	Dim d As Default
	Set d = CurDefault
	Read "Default created: " & d.Name

End Sub


Sub CreateUserDatatypeHandler(CurUserDatatype As Object, CurDiagram As Object)

	Dim udt As UserDatatype
	Set udt = CurUserDatatype
	Read "UserDatatype created: " & udt.Name

End Sub


Sub CreateRuleHandler(CurRule As Object, CurDiagram As Object)

	Dim r As Rule
	Set r = CurRule
	Read "Rule created: " & r.Name

End Sub


Sub CreateViewHandler(CurView As Object, CurDiagram As Object)

	Dim v As View
	Set v = CurView
	Read "View created: " & v.Name

End Sub


Sub CreateTriggerHandler(CurTrigger As Object, CurDiagram As Object)

	Dim t As Trigger
	Set t = CurTrigger
	Read "Trigger created: " & t.Name

End Sub


Sub CreateProcedureHandler(CurProcedure As Object, CurDiagram As Object)

	Dim p As Procedure
	Set p = CurProcedure
	Read "Procedure created: " & p.Name

End Sub


Sub CreateViewRelationshipHandler(CurViewRelationship As Object, CurDiagram As Object)

	Dim vrs As ViewRelationship
	Set vrs = CurViewRelationship
	Dim d As Diagram
	Set d = CurDiagram
	Read "ViewRelationship created for " & IIf(d.ActiveModel.Logical, "Entity""Table") & ": " & IIf(d.ActiveModel.Logical, vrs.ParentEntity.EntityName, vrs.ParentEntity.TableName)

End Sub

Sub CreateDiagramHandler(CurDiagram As Object)

	Dim d As Diagram
	Set d = CurDiagram
	Read "Diagram created: " & d.ProjectName

End Sub

Sub CreateEntityDisplayHandler(CurEntityDisplay As Object, CurDiagram As Object)

	Dim ed As EntityDisplay
	Set ed = CurEntityDisplay
	Read "Entity Display created: " & ed.Name

End Sub

Sub CreateRelationshipDisplayHandler(CurRelationshipDisplay As Object, CurDiagram As Object)

	Dim rsd As RelationshipDisplay
	Set rsd = CurRelationshipDisplay
	Read "Relationship Display created: " & rsd.ParentRelationship.Name

End Sub

Sub CreateViewDisplayHandler(CurViewDisplay As Object, CurDiagram As Object)

	Dim vd As ViewDisplay
	Set vd = CurViewDisplay
	Read "View Display created: " & vd.Name

End Sub

Sub CreateViewRelationshipDisplayHandler(CurViewRelationshipDisplay As Object, CurDiagram As Object)

	Dim vrsd As ViewRelationshipDisplay
	Set vrsd = CurViewRelationshipDisplay
	Dim d As Diagram
	Set d = CurDiagram
	Read "View Relationship Display created for " & IIf(d.ActiveModel.Logical, "Entity""Table") & ": " & IIf(d.ActiveModel.Logical, vrsd.ParentViewRelationship.ParentEntity.EntityName, vrsd.ParentViewRelationship.ParentEntity.TableName)

End Sub

Sub CreateViewFieldHandler(CurViewField As Object, CurDiagram As Object)

	Dim vf As ViewField
	Set vf = CurViewField
	Read "View Field created: " & vf.Alias

End Sub

Sub CreateFKColumnPairHandler(CurFKColumnPair As Object, CurDiagram As Object)

	Dim fkcp As FKColumnPair
	Set fkcp = CurFKColumnPair
	Dim d As Diagram
	Set d = CurDiagram
	Read "FK Column Pair created. Parent " & IIf(d.ActiveModel.Logical, "attribute""column") & ": " & IIf(d.ActiveModel.Logical, fkcp.ParentAttribute.AttributeName, fkcp.ParentAttribute.ColumnName) & "." & vbCrLf & "Child " & IIf(d.ActiveModel.Logical, "attribute""column") & ": " & IIf(d.ActiveModel.Logical, fkcp.ChildAttribute.AttributeName, fkcp.ChildAttribute.ColumnName)

End Sub

Sub CreateIndexColumnHandler(CurIndexColumn As Object, CurDiagram As Object)

	Dim ic As IndexColumn
	Set ic = CurIndexColumn
	Read "Index Column created for column: " & ic.ColumnName

End Sub

Sub CreateSubTypeHandler(CurSubType As Object, CurDiagram As Object)

	Dim st As SubType
	Set st = CurSubType
	Read "SubType created for entity: " & st.Entity.EntityName

End Sub

Sub CreateSubTypeClusterHandler(CurSubTypeCluster As Object, CurDiagram As Object)

	Dim stc As SubTypeCluster
	Set stc = CurSubTypeCluster
	Read "SubType Cluster created with Discriminator: " & stc.Discriminator

End Sub

wReadDefinition.BAS

'#Language "WWB-COM"
'
''MACRO TITLE: Read Definition
'
'This macro is reading the Definition of the currently selected
'	Entities or Tables
'
'-------------------------------------------------------------------

Option Explicit

Const VOICE_INDEX%   =  0 ' Change this number to change the voice. Max value depends on your OS.
Const SPEAK_TIMEOUT% = 10 ' Stop speaking after 10s

Const SVSFlagsAsync% = 1
Dim Sapi As Object

Sub Main
	
	Dim MyDiagram As Diagram
	Dim MyModel As Model
	Dim MyEntity As Entity
	Dim MySubModel As SubModel
	Dim MySelObject As SelectedObject

	Dim ID As Integer
	Dim Logical As Boolean
	Dim ObjectName As String
	Dim ObjType As Integer

	Debug.Clear

	' Display the available voices
	DisplayVoices

	'Get the current diagram.
	Set MyDiagram = DiagramManager.ActiveDiagram
	
	'Get the current model.
	Set MyModel = MyDiagram.ActiveModel
	
	'Get the current submodel.
	Set MySubModel = MyModel.ActiveSubModel
	
	'Determine if the model is logical or physical.
	Logical = MyModel.Logical
	
	'Iterate through all the selected entities in the submodel
	For Each MySelObject In MySubModel.SelectedObjects
		
		'Get type of the selected object.
		ObjType = MySelObject.Type
		
		'We only want to get the entities, so check the object type.
		If ObjType = 1 Then
		
			'Get the ID of the selected object.
			ID = MySelObject.ID
	
			'Now, get the actual entity object with this ID.
			Set MyEntity = MyModel.Entities.Item(ID)

			'If the model is logical, get the entity name. 
			'If it is physical, get the table name.
			ObjectName = IIf(Logical, "Entity " & MyEntity.EntityName, "Table " & MyEntity.TableName)

			If MyEntity.Definition = "" Then
				
				Read ObjectName & " has no definition!"

			Else

				Read "The definition of " & ObjectName & " is:"
				Read MyEntity.Definition

			End If

		End If
		
	Next MySelObject

	Debug.Print ""
	Debug.Print "End!"

End Sub

Private Sub Read(txt$)

	If Sapi Is Nothing Then
		
		Set Sapi = CreateObject("SAPI.Spvoice")
		Set Sapi.Voice = Sapi.GetVoices.Item(VOICE_INDEX)
'		Sapi.Speak "TTS object created!", SVSFlagsAsync

	End If

	Debug.Print "Reading: " & txt

	' The speaking of the text string
	Sapi.Speak txt, SVSFlagsAsync

	' Blocks the caller until either the voice has finished speaking or the specified time interval has elapsed.
	Sapi.WaitUntilDone (SPEAK_TIMEOUT * 1000)

End Sub

Private Sub DisplayVoices

	Dim v As Object
	Dim i%

	If Sapi Is Nothing Then
		
		Set Sapi = CreateObject("SAPI.Spvoice")
		Set Sapi.Voice = Sapi.GetVoices.Item(VOICE_INDEX)

	End If

	i = 0
	For Each v In Sapi.GetVoices

		Debug.Print i & ": " & v.GetDescription     'The token's name
		i += 1

	Next

	Debug.Print

End Sub

Bonus

A short video which shows how to create a macro from a script in ER/Studio Data Architect: