DA# Macro(6): DA# Modeler API
This article looks at the DA# Modeler API Object Model used in DA# Macro, VBA code configuration, and source code examples.
5. DA# Modeler API
5.1. DA# Modeler API Object Model
Previous article(DA# Macro(1): DA#, DA# API, DA# Macro Overview) briefly introduced the DA# API Object Model.
The list of classes provided by DA# Modeler is as follows. (I checked it with the 'Search Object' function in Excel VBE (Visual Basic Editor).)
The object model of DA# Modeler API is as follows. (The content is not in the official manual, and I have compiled it myself.)
The hierarchical structure of the object from Application to Attribute, which is the most important among them, is as follows.
1)Application -> 2)Models -> 3)Model -> 4)Entitys -> 5)Entity -> 6)Attributes -> 7)Attribute
If this layer is expressed as an example model of DA# Modeler, it is as follows.
A brief summary of the Object Model hierarchy, concept, and use of DA# Modeler API is as follows.
5.2. Using DA# Modeler API in Excel VBA
DA# Modeler API in Excel VBA early binding To use it in this way, you must first add a reference to the “Modeler5” library.
▼ Switch to Excel VBE (Visual Basic Editor) (shortcut key) Alt + F11) to execute the Tools > Reference menu.
▼ Check and select “Modeler5” in the “Available References” list and click the “OK” button.
Now we can write VBA code like this:
'Modeler5 Application 개체 생성 Dim odApp As Modeler5.Application Set odApp = New Modeler5.Application '새 모델 개체 생성 Dim odModel As Modeler5.Model Set odModel = odApp.GetModelMustBe("새모델") 'Entity 생성과 값 할당 Dim odEntity As Modeler5.Entity Set odEntity = odModel.GetEntityMustBe("엔터티1") odEntity.TableName = "Table1" 'Attribute 생성과 값 할당 Dim odAttribute As Modeler5.Attribute Set odAttribute = odEntity.GetAttributeMustBe("속성1") odAttribute.ColName = "Column1"
5.3. DA# Macro VBA code configuration
The list and brief description of Worksheet, UserForm, Module, and Class are as follows.
▼ Worksheet Object
- shtAttributeGet: Implementation of “Attribute(Get)” sheet UI function
- shtAttributeSet: Implementation of “Attribute(Set)” sheet UI function
- shtEntityGet: Implementation of “Entity(Get)” sheet UI function
- shtEntitySet: Implementation of “Entity(Set)” sheet UI function
- shtReverse: Implement “Reverse” sheet UI function
▼ Form Object
- frmModelFromFile: The user form displayed when clicking the “Select Model (File)” button
- frmProgress: A user form to show the progress bar (ProgressBar) when processing a function
▼ Module Object
- modDAConstType: constant declaration required for function implementation, implementation of DA# Enum and Name conversion function
- modDAModeler: Implement DA# related functions (GetModel, Reverse, SetEntity, SetAttribute, etc.)
- modTest: Test code
- modUtil: Common functions (DoLog, ClearList, GetElapsedTime, etc.)
- modWinAPI: currently deprecated
▼ Class Module Object
- CDAAttribute: Class of 1 attribute unit
- CDAAttributeList: A class that manages the attribute list as a Dictionary structure (Key-Value)
- Key: ModelName:KeyName (KeyName is in the form of entity name. attribute name or table name. column name)
- Value: CDAAttribute instance
- CDAEntity: A class of 1 unit of entity
- CDAEntityList: A class that manages the entity list as a Dictionary structure (Key-Value)
- Key: ModelName:KeyName (KeyName is entity name or table name)
- Value: CDAEntity instance
- CDAFK: A class of one FK unit
- CDAFKList: Class that manages the FK list as a Dictionary structure (Key-Value)
- Key: ModelName: parent entity name -> child entity name
- Value: CDAFK instance
- CDAModel: Class of one Model unit
- CDAModelList: A class that manages the model list as a dictionary structure (Key-Value)
- Key: ModelName
- Value: CDAModel instance
- CDASubject: Class of one unit of subject area
- CDASubjectList: A class that manages the list of subject areas as a Dictionary structure (Key-Value)
- Key: ModelName:SubjectName
- Value: CDASubject instance
- CUDPNameType: Class that manages UDP name and target (used for UDP Get/Set)
5.4. Example of source code using DA# API main classes
5.4.1. Create a model instance from a file
Implemented as function “GetModel” in module “modDAModeler”.
'모델명과 파일명(경로포함)으로 Model Instance 반환 Public Function GetModel(ByRef adApp As Modeler5.Application, aModelName As String, aModelFileName As String) As Modeler5.Model Dim odModel As Modeler5.Model If adApp Is Nothing Then Set adApp = New Modeler5.Application Set odModel = adApp.GetModel(aModelName) '열려 있는 모델에서 ModelName으로 비교 If (odModel Is Nothing) And (Trim(aModelFileName) <> "") Then Set odModel = GetModelAlreadyOpened(adApp, aModelName, aModelFileName) '열려 있는 모델에서 FilePath로 비교 If odModel Is Nothing Then '모델이 열려 있지 않은 경우 adApp.OpenFile (aModelFileName) Set odModel = adApp.GetActiveModel End If End If adApp.SetActiveModel odModel Set GetModel = odModel If odModel Is Nothing Then '열려 있는 모델에도 없고 파일명도 비어있는 경우 MsgBox "GetModel Error" & vbLf & _ "ModelName: " & aModelName & vbLf & _ "ModelFileName: " & aModelFileName, vbOKOnly & vbExclamation, "GetModel Error" End If End Function
Before calling the GetModel function, first create a Modeler5.Application instance as follows and pass it as a parameter.
Set m_odApp = New Modeler5.Application Set odModel = GetModel(m_odApp, aFileNameOnly, aFileName)
If the Modeler5.Application instance is not passed, an instance is created inside the function (line 4).
5.4.2. Get list of entities from model file
Implemented as function “GetEntityListFromFile” of “Entity(Get)” sheet.
Public Sub GetEntityListFromFile(aFileNameOnly As String, aFileName As String, baGetYN() As Boolean, _ aUDPNameCol As Collection, aIsSaveNClose As Boolean) Dim odModel As Modeler5.Model Dim odSubjects As Modeler5.Subjects, odSubject As Modeler5.Subject Dim odLogicalPane As Modeler5.Pane, odEntitys As Modeler5.Entitys, odEntity As Modeler5.Entity Dim sModelName As String, oBaseRange As Range, oOutRange As Range, oUDPOutRange As Range Dim vOutRngArr As Variant, vUDPRngArr As Variant Set odModel = GetModel(m_odApp, aFileNameOnly, aFileName) sModelName = odModel.Name If odModel Is Nothing Then MsgBox "DA# 모델이 없습니다." & vbLf & "<모델명: " & sModelName & ">", vbCritical GoTo Finalize_Section End If odModel.ActiveAction (False) 'Undo/Redo 해제 Set oBaseRange = Range("EntityListBase").Offset(1, 0): Set oOutRange = oBaseRange.Offset(m_lRowOffset, 0) Set oUDPOutRange = Range("EntityUDPNameBase").Offset(1, 0): Set oUDPOutRange = oUDPOutRange.Offset(m_lRowOffset, 0) Set odEntitys = odModel.Entitys Dim lEntIdx As Long ReDim vOutRngArr(1 To odEntitys.Count, DA_GETENT_ItemCount) ReDim vUDPRngArr(1 To odEntitys.Count, DA_GETENT_ItemCount) For lEntIdx = 1 To odEntitys.Count Set odEntity = odEntitys.Item(lEntIdx - 1) Dim arrayEnt() As Variant arrayEnt = odEntity.Values '엔터티 Property를 Variant Array로 한번에 받아오기 vOutRngArr(lEntIdx, DA_GETENT_Sequence_IDX) = lEntIdx vOutRngArr(lEntIdx, DA_GETENT_ModelName_IDX) = sModelName vOutRngArr(lEntIdx, DA_GETENT_EntityName_IDX) = odEntity.Name '- 엔터티 Property 직접 접근 방식 ----------------------------------------------------------------------------------------------------------------------------------------- If baGetYN(DA_GETENT_EntityTableName_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityTableName_IDX) = odEntity.TableName If baGetYN(DA_GETENT_EntitySynonym_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntitySynonym_IDX) = odEntity.Synonym If baGetYN(DA_GETENT_EntityAltName_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityAltName_IDX) = odEntity.AltName If baGetYN(DA_GETENT_EntityDBOwner_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityDBOwner_IDX) = odEntity.DBOwner If baGetYN(DA_GETENT_EntityCategory_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityCategory_IDX) = GetEntityCategoryName(odEntity.Category) If baGetYN(DA_GETENT_EntityLevel_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityLevel_IDX) = odEntity.Level If baGetYN(DA_GETENT_EntityRank_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityRank_IDX) = GetEntityRankName(odEntity.Rank) If baGetYN(DA_GETENT_EntityVirtual_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityVirtual_IDX) = GetEntityTypeName(odEntity.Virtual) If baGetYN(DA_GETENT_EntityStandardType_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityStandardType_IDX) = GetStandardTypeName(odEntity.StandardType) If baGetYN(DA_GETENT_EntityStatus_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityStatus_IDX) = odEntity.Status If baGetYN(DA_GETENT_EntityPeriod_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityPeriod_IDX) = odEntity.Period If baGetYN(DA_GETENT_EntityMonthly_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityMonthly_IDX) = odEntity.Monthly If baGetYN(DA_GETENT_EntityManage_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityManage_IDX) = odEntity.Manage If baGetYN(DA_GETENT_EntityTotal_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityTotal_IDX) = odEntity.Total If baGetYN(DA_GETENT_EntityDesc_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityDesc_IDX) = Replace(odEntity.Desc, vbCrLf, vbLf) '정의 If baGetYN(DA_GETENT_EntityFlow_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityFlow_IDX) = Replace(odEntity.Flow, vbCrLf, vbLf) '데이터 처리 형태 If baGetYN(DA_GETENT_EntityRemark_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityRemark_IDX) = Replace(odEntity.Remark, vbCrLf, vbLf) '특이사항 If baGetYN(DA_GETENT_EntityNote_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityNote_IDX) = Replace(odEntity.Note, vbCrLf, vbLf) '노트 If baGetYN(DA_GETENT_EntityTag_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityTag_IDX) = odEntity.TagName '- 엔터티 Property Array 접근 방식 ----------------------------------------------------------------------------------------------------------------------------------------- ' If baGetYN(DA_GETENT_EntityTableName_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityTableName_IDX) = arrayEnt(Modeler5.ENT_TABLENAME) ' If baGetYN(DA_GETENT_EntitySynonym_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntitySynonym_IDX) = arrayEnt(Modeler5.ENT_SYNONYM) ' If baGetYN(DA_GETENT_EntityAltName_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityAltName_IDX) = arrayEnt(Modeler5.ENT_ALTNAME) ' If baGetYN(DA_GETENT_EntityDBOwner_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityDBOwner_IDX) = arrayEnt(Modeler5.ENT_DBOWNER) ' If baGetYN(DA_GETENT_EntityCategory_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityCategory_IDX) = GetEntityCategoryName(arrayEnt(Modeler5.ENT_CATEGORY)) ' If baGetYN(DA_GETENT_EntityLevel_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityLevel_IDX) = arrayEnt(Modeler5.ENT_LEVEL) ' If baGetYN(DA_GETENT_EntityRank_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityRank_IDX) = GetEntityRankName(arrayEnt(Modeler5.ENT_RANK)) ' If baGetYN(DA_GETENT_EntityVirtual_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityVirtual_IDX) = GetEntityTypeName(arrayEnt(Modeler5.ENT_VIRTUAL)) ' If baGetYN(DA_GETENT_EntityStandardType_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityStandardType_IDX) = GetStandardTypeName(arrayEnt(Modeler5.ENT_STANDARDTYPE)) ' If baGetYN(DA_GETENT_EntityStatus_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityStatus_IDX) = arrayEnt(Modeler5.ENT_STATUS) ' If baGetYN(DA_GETENT_EntityPeriod_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityPeriod_IDX) = arrayEnt(Modeler5.ENT_PERIOD) ' If baGetYN(DA_GETENT_EntityMonthly_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityMonthly_IDX) = arrayEnt(Modeler5.ENT_MONTHLY) ' If baGetYN(DA_GETENT_EntityManage_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityManage_IDX) = arrayEnt(Modeler5.ENT_MANAGE) ' If baGetYN(DA_GETENT_EntityTotal_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityTotal_IDX) = arrayEnt(Modeler5.ENT_TOTAL) ' If baGetYN(DA_GETENT_EntityDesc_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityDesc_IDX) = Replace(arrayEnt(Modeler5.ENT_DESC), vbCrLf, vbLf) '정의 ' If baGetYN(DA_GETENT_EntityFlow_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityFlow_IDX) = Replace(arrayEnt(Modeler5.ENT_FLOW), vbCrLf, vbLf) '데이터 처리 형태 ' If baGetYN(DA_GETENT_EntityRemark_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityRemark_IDX) = Replace(arrayEnt(Modeler5.ENT_REMARK), vbCrLf, vbLf) '특이사항 ' If baGetYN(DA_GETENT_EntityNote_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityNote_IDX) = Replace(arrayEnt(Modeler5.ENT_NOTE), vbCrLf, vbLf) '노트 ' If baGetYN(DA_GETENT_EntityTag_IDX) = True Then vOutRngArr(lEntIdx, DA_GETENT_EntityTag_IDX) = arrayEnt(Modeler5.ENT_TAGNAME) If Not aUDPNameCol Is Nothing Then 'Get UDP Value Dim oUDPNamePType As CUDPNameType, lUDPNameIdx As Long For lUDPNameIdx = 1 To aUDPNameCol.Count Set oUDPNamePType = aUDPNameCol(lUDPNameIdx) If oUDPNamePType.m_bUDPTargetYN = False Then GoTo SkipUDP vUDPRngArr(lEntIdx, lUDPNameIdx - 1) = odEntity.GetUDPValue(oUDPNamePType.m_sUDPName) SkipUDP: Next lUDPNameIdx End If '---------------------------------------------------------------------------------------------------- m_lRowOffset = m_lRowOffset + 1 Next lEntIdx '---------------------------------------------------------------------------------------------------- Set oOutRange = oOutRange.Resize(UBound(vOutRngArr, 1), UBound(vOutRngArr, 2)) Set oUDPOutRange = oUDPOutRange.Resize(UBound(vOutRngArr, 1), UBound(vOutRngArr, 2)) oOutRange.Value2 = vOutRngArr oUDPOutRange.Value2 = vUDPRngArr '---------------------------------------------------------------------------------------------------- Finalize_Section: odModel.ActiveAction (True) 'Undo/Redo 활성화 If aIsSaveNClose Then 'odApp.SaveActiveModelFile 'Get은 Save 하지 않도록 주석처리 m_odApp.CloseActiveModelFile End If Set odModel = Nothing Set odSubjects = Nothing Set odSubject = Nothing Set odEntity = Nothing End Sub
The property array approach has better performance than the entity property direct approach, but at the time of writing this article, when accessing the array, the value could not be retrieved properly, so I returned it to the direct approach.
Rows 88 to 91 use Variant Array to write a two-dimensional array in memory to an Excel sheet at a time. For an explanation of this, refer to the following article.
VBA Coding Pattern: Range Loop - Write
5.4.3. Setting values on Entity
Implemented as procedure “SetValue” of class “CDAEntityList”.
Public Sub SetValue(aTargetModelList As CDAModelList, aIsAppendMode As Boolean, _ baSetYN() As Boolean, aIsSaveNClose As Boolean) On Error GoTo ErrHandling Dim odApp As Modeler5.Application, odModel As Modeler5.Model Dim odEntitys As Modeler5.Entitys, odEntity As Modeler5.Entity Set odApp = New Modeler5.Application Dim startTime As Date, endTime As Date, sElapedTime As String DoLog ("Entity(Set) Started...") startTime = Now frmProgress.Hide: frmProgress.InitProgress: frmProgress.Show Application.ScreenUpdating = False Dim lTargetDAModelIndex As Long, oTargetDAModel As CDAModel Dim lEntIndex As Long, sKey As String, oDAEntity As CDAEntity, lSetCount As Long, sProgressMsg As String lSetCount = 0 For lTargetDAModelIndex = 0 To aTargetModelList.Count - 1 'Model Level Loop Set oTargetDAModel = aTargetModelList.GetItemByIndex(lTargetDAModelIndex) Set odModel = GetModel(odApp, oTargetDAModel.m_s모델명, oTargetDAModel.m_s모델파일명) odModel.ActiveAction (False) 'Undo/Redo 해제 frmProgress.UpdateProgressBar aTargetModelList.Count, lTargetDAModelIndex + 1, oTargetDAModel.m_s모델명, True sProgressMsg = "[" + CStr(lTargetDAModelIndex + 1) + "/" + CStr(aTargetModelList.Count) + "] " + oTargetDAModel.m_s모델명 DoDisplayStatusMsg sProgressMsg DoLog sProgressMsg + " (" + oTargetDAModel.m_s모델파일명 + ")" If frmProgress.IsCanceled Then GoTo Finalize_Section Set odEntitys = odModel.Entitys For lEntIndex = 0 To odEntitys.Count - 1 'Entity Level Loop Set odEntity = odEntitys.Item(lEntIndex) If m_eDACompareType = DACompareLogicalName Then sKey = odModel.Name + ":" + odEntity.Name ElseIf m_eDACompareType = DAComparePysicalName Then sKey = odModel.Name + ":" + odEntity.TableName End If Set oDAEntity = GetItem(sKey) If oDAEntity Is Nothing Then GoTo Skip_Set '변경할 대상이 아니면 skip lSetCount = lSetCount + 1 'Set 개수 증가 '- 엔터티 Property 직접 접근 방식 ----------------------------------------------------------------------------------------------------------------------------------------- ' If baSetYN(DA_SETENT_EntityName_IDX) = True Then odEntity.Name = oDAEntity.m_s엔터티명 ' If baSetYN(DA_SETENT_EntityTableName_IDX) = True Then odEntity.TableName = oDAEntity.m_s테이블명 ' If baSetYN(DA_SETENT_EntitySynonym_IDX) = True Then odEntity.Synonym = oDAEntity.m_s동의어 ' If baSetYN(DA_SETENT_EntityAltName_IDX) = True Then odEntity.AltName = oDAEntity.m_s보조명 ' If baSetYN(DA_SETENT_EntityDBOwner_IDX) = True Then odEntity.DBOwner = oDAEntity.m_sDBOwner ' If baSetYN(DA_SETENT_EntityCategory_IDX) = True Then odEntity.Category = GetEntityCategoryEnum(oDAEntity.m_s분류) ' If baSetYN(DA_SETENT_EntityLevel_IDX) = True Then odEntity.Level = oDAEntity.m_sLevel ' If baSetYN(DA_SETENT_EntityRank_IDX) = True Then odEntity.Rank = GetEntityRankEnum(oDAEntity.m_s단계) ' If baSetYN(DA_SETENT_EntityVirtual_IDX) = True Then odEntity.Virtual = GetEntityTypeEnum(oDAEntity.m_s유형) ' If baSetYN(DA_SETENT_EntityStandardType_IDX) = True Then odEntity.StandardType = GetStandardTypeEnum(oDAEntity.m_s표준화) ' If baSetYN(DA_SETENT_EntityStatus_IDX) = True Then odEntity.Status = oDAEntity.m_s상태 ' If baSetYN(DA_SETENT_EntityPeriod_IDX) = True Then odEntity.Period = oDAEntity.m_s발생주기 ' If baSetYN(DA_SETENT_EntityMonthly_IDX) = True Then odEntity.Monthly = oDAEntity.m_s월간발생량 ' If baSetYN(DA_SETENT_EntityManage_IDX) = True Then odEntity.Manage = oDAEntity.m_s보존기한 ' If baSetYN(DA_SETENT_EntityTotal_IDX) = True Then odEntity.Total = oDAEntity.m_s총건수 ' If baSetYN(DA_SETENT_EntityDesc_IDX) = True Then odEntity.Desc = IIf(aIsAppendMode, odEntity.Desc + vbCrLf + oDAEntity.m_s정의, oDAEntity.m_s정의) ' If baSetYN(DA_SETENT_EntityFlow_IDX) = True Then odEntity.Flow = IIf(aIsAppendMode, odEntity.Flow + vbCrLf + oDAEntity.m_s데이터처리형태, oDAEntity.m_s데이터처리형태) ' If baSetYN(DA_SETENT_EntityRemark_IDX) = True Then odEntity.Remark = IIf(aIsAppendMode, odEntity.Remark + vbCrLf + oDAEntity.m_s특이사항, oDAEntity.m_s특이사항) ' If baSetYN(DA_SETENT_EntityNote_IDX) = True Then odEntity.Note = IIf(aIsAppendMode, odEntity.Note + vbCrLf + oDAEntity.m_sNote, oDAEntity.m_sNote) ' If baSetYN(DA_SETENT_EntityTag_IDX) = True Then odEntity.TagName = oDAEntity.m_sTag Dim arrEnt(Modeler5.ENT_ARRAYCOUNT) As Variant '- 엔터티 Property Array 접근 방식 ----------------------------------------------------------------------------------------------------------------------------------------- If baSetYN(DA_SETENT_EntityName_IDX) = True Then odEntity.Name = oDAEntity.m_s엔터티명 If baSetYN(DA_SETENT_EntityTableName_IDX) = True Then arrEnt(Modeler5.ENT_TABLENAME) = oDAEntity.m_s테이블명 If baSetYN(DA_SETENT_EntitySynonym_IDX) = True Then arrEnt(Modeler5.ENT_SYNONYM) = oDAEntity.m_s동의어 If baSetYN(DA_SETENT_EntityAltName_IDX) = True Then arrEnt(Modeler5.ENT_ALTNAME) = oDAEntity.m_s보조명 If baSetYN(DA_SETENT_EntityDBOwner_IDX) = True Then arrEnt(Modeler5.ENT_DBOWNER) = oDAEntity.m_sDBOwner If baSetYN(DA_SETENT_EntityCategory_IDX) = True Then arrEnt(Modeler5.ENT_CATEGORY) = GetEntityCategoryEnum(oDAEntity.m_s분류) If baSetYN(DA_SETENT_EntityLevel_IDX) = True Then arrEnt(Modeler5.ENT_LEVEL) = oDAEntity.m_sLevel If baSetYN(DA_SETENT_EntityRank_IDX) = True Then arrEnt(Modeler5.ENT_RANK) = GetEntityRankEnum(oDAEntity.m_s단계) If baSetYN(DA_SETENT_EntityVirtual_IDX) = True Then arrEnt(Modeler5.ENT_VIRTUAL) = GetEntityTypeEnum(oDAEntity.m_s유형) If baSetYN(DA_SETENT_EntityStandardType_IDX) = True Then arrEnt(Modeler5.ENT_STANDARDTYPE) = GetStandardTypeEnum(oDAEntity.m_s표준화) If baSetYN(DA_SETENT_EntityStatus_IDX) = True Then arrEnt(Modeler5.ENT_STATUS) = oDAEntity.m_s상태 If baSetYN(DA_SETENT_EntityPeriod_IDX) = True Then arrEnt(Modeler5.ENT_PERIOD) = oDAEntity.m_s발생주기 If baSetYN(DA_SETENT_EntityMonthly_IDX) = True Then arrEnt(Modeler5.ENT_MONTHLY) = oDAEntity.m_s월간발생량 If baSetYN(DA_SETENT_EntityManage_IDX) = True Then arrEnt(Modeler5.ENT_MANAGE) = oDAEntity.m_s보존기한 If baSetYN(DA_SETENT_EntityTotal_IDX) = True Then arrEnt(Modeler5.ENT_TOTAL) = oDAEntity.m_s총건수 If baSetYN(DA_SETENT_EntityDesc_IDX) = True Then arrEnt(Modeler5.ENT_DESC) = IIf(aIsAppendMode, odEntity.Desc + vbCrLf + oDAEntity.m_s정의, oDAEntity.m_s정의) If baSetYN(DA_SETENT_EntityFlow_IDX) = True Then arrEnt(Modeler5.ENT_FLOW) = IIf(aIsAppendMode, odEntity.Flow + vbCrLf + oDAEntity.m_s데이터처리형태, oDAEntity.m_s데이터처리형태) If baSetYN(DA_SETENT_EntityRemark_IDX) = True Then arrEnt(Modeler5.ENT_REMARK) = IIf(aIsAppendMode, odEntity.Remark + vbCrLf + oDAEntity.m_s특이사항, oDAEntity.m_s특이사항) If baSetYN(DA_SETENT_EntityNote_IDX) = True Then arrEnt(Modeler5.ENT_NOTE) = IIf(aIsAppendMode, odEntity.Note + vbCrLf + oDAEntity.m_sNote, oDAEntity.m_sNote) If baSetYN(DA_SETENT_EntityTag_IDX) = True Then arrEnt(Modeler5.ENT_TAGNAME) = oDAEntity.m_sTag odEntity.Values = arrEnt '-------------------- Set UDP Value -------------------- If oDAEntity.m_oUDPDic.Count = 0 Then GoTo Skip_Set 'UDP Collection이 비어 있으면 Skip Dim vUDPName As Variant, sUDPValue As String For Each vUDPName In oDAEntity.m_oUDPDic.Keys 'Dictionary에는 Set대상 UDP만 가지고 있음 sUDPValue = oDAEntity.m_oUDPDic(vUDPName) odEntity.SetUDPValue vUDPName, sUDPValue Next vUDPName Skip_Set: odEntity.UpdateDrawEntity Next lEntIndex odModel.ActiveAction (True) 'Undo/Redo 활성화 If aIsSaveNClose Then odApp.SaveActiveModelFile odApp.CloseActiveModelFile End If Next lTargetDAModelIndex frmProgress.UpdateProgressBar aTargetModelList.Count, lTargetDAModelIndex + 1, oTargetDAModel.m_s모델명, True ErrHandling: Resume Next Finalize_Section: Application.ScreenUpdating = True endTime = Now sElapedTime = GetElapsedTime(startTime, endTime) DoLog ("Entity(Set) Finished. [ElapsedTime: " + sElapedTime + "]") frmProgress.SetDoneMsg sProgressMsg, sElapedTime MsgBox "처리완료" + vbCrLf + _ "처리건수: " + CStr(lSetCount) + vbCrLf + _ "Elapsed Time: " + sElapedTime, vbInformation End Sub
- Line 21: Undo/Redo. (To save memory and improve performance)
- Lines 10, 25, 112: Record the processing status with the DoLog function. (This function is a user function that uses the Windows API 'OutputDebugMessage', and will be posted separately in this regard)
- Line 83: Assign an Array (Variant type) containing entity properties to Entity.Values and set the values at once.
Up to this point, we looked at the DA# Modeler API Object Model used in the DA# Macro, VBA code configuration, and source code examples.
As for the source code, I sometimes repeat coding and refactoring when I have time over three years, so the overall code consistency is not very good. The overall refactoring should be tinkered with at some point, but I don't know when.
Data modelers, DAs (Data Architects) who use DA#, hope this tool will be helpful.
<< List of related articles >>
- DA# Macro(1): DA#, DA# API, DA# Macro Overview
- DA# Macro(2): DA# Macro Function(1)-Common Function, Entity Get/Set
- DA# Macro(3): DA# Macro Function(2)-Attribute Get/Set
- DA# Macro(4): DA# Macro Function(3)-Reverse
- DA# Macro(5): Usage notes/notes, downloads, features to be added in the future, notes
- DA# Macro(6): DA# Modeler API
- DA# Macro function demonstration video (YouTube)
- DA# Macro Description Contents , Download