DA# 宏(6): DA# Modeler API

本文研究 DA# 宏中使用的 DA# Modeler API 对象模型、VBA 代码组合和源代码示例。

5.DA# 建模器 API

5.1. DA# Modeler API 对象模型

上一篇文章 (DA# 宏(1):DA#、DA# API、DA# 宏概述)简单介绍了DA# API对象模型。

DA# Modeler 提供的类列表如下。 (我使用 Excel VBE(Visual Basic 编辑器)中的“搜索对象”功能进行了检查。)

DA# Modeler에서 제공하는 클래스 목록
DA# Modeler 提供的类列表

DA# Modeler API 的对象模型如下。 (官方手册上没有这个,我自己整理的。)

DA# API Object Model
DA# API 对象模型

其中,最核心的从Application到Attribute的对象层次结构如下。

1)应用程序 -> 2)模型 -> 3)模型 -> 4)实体 -> 5)实体 -> 6)属性 -> 7)属性

如果将该层表示为DA# Modeler示例模型,则如下。

DA# 모델러 API 핵심 Object
DA# Modeler API 核心对象

DA# Modeler API 的对象模型层次结构、概念和用法的简要总结如下。

DA# Modeler API Object Model 계층 구조
DA# Modeler API 对象模型层次结构

5.2.在 Excel VBA 中使用 DA# Modeler API

Excel VBA 中的 DA# 建模器 API 提前绑定 要以这种方式使用它,您必须首先添加对“Modeler5”库的引用。

▼ 切换到Excel VBE(Visual Basic编辑器)(快捷键 Alt + F11) 执行工具 > 参考菜单。

도구 > 참조 메뉴 실행
工具 > 参考菜单运行

▼ 在“Available References”列表中勾选并选择“Modeler5”,然后单击“OK”按钮。

Modeler5 참조 추가
添加 Modeler5 参考

现在您可以编写如下 VBA 代码:

'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#宏VBA代码配置

工作表、用户表单、模块、类列表和简要说明如下。

DA# Macro VBA 코드 구성
DA#宏VBA代码配置

▼ 工作表对象

  • shtAttributeGet:“Attribute(Get)”表单UI功能的实现
  • shtAttributeSet:“属性(集)”表单UI功能的实现
  • shtEntityGet:“Entity(Get)”表单UI功能的实现
  • shtEntitySet:“Entity(Set)”表单UI功能的实现
  • shtReverse:实现“反转”表单 UI 功能

▼ 表单对象

  • frmModelFromFile:点击“选择模型(文件)”按钮时显示的用户表单
  • frmProgress:处理函数时显示进度(ProgressBar)的用户表单

▼ 模块对象

  • modDAConstType:函数实现所需的常量声明,实现DA# Enum和Name转换函数
  • modDAModeler:DA#相关函数的实现(GetModel、Reverse、SetEntity、SetAttribute等)
  • modTest:测试代码
  • modUtil:常用函数(DoLog、ClearList、GetElapsedTime 等)
  • modWinAPI:目前已弃用

▼ 类模块对象

  • CDAAttribute:1 类属性单元
  • CDAAttributeList:将属性列表作为字典结构(Key-Value)进行管理的类
    • Key:ModelName:KeyName(KeyName为实体名.属性名或表名.列名格式)
    • 值:CDAAttribute 实例
  • CDAEntity:一类 1 单元实体
  • CDAEntityList:将实体列表作为字典结构(Key-Value)进行管理的类
    • Key: ModelName:KeyName (KeyName为实体名或表名)
    • 值:CDAEntity 实例
  • CDAFK:一类 FK 单位
  • CDAFKList:将 FK 列表作为字典结构(Key-Value)进行管理的类
    • Key: ModelName: 父实体名称 -> 子实体名称
    • 值:CDAFK 实例
  • CDAModel:一类模型单元
  • CDAModelList:将模型列表作为字典结构(Key-Value)进行管理的类
    • 关键:型号名称
    • 值:CDAModel 实例
  • CDASubject:学科领域一单元的类别
  • CDASubjectList:以字典结构(键值)形式管理主题区域列表的类
    • 键:模型名称:主题名称
    • 值:CDASubject 实例
  • CUDPNameType:管理UDP名称和目标的类(用于UDP获取/设置)

5.4.使用DA# API主类的源代码示例

5.4.1.从文件创建模型实例

作为模块“modDAModeler”中的函数“GetModel”实现。

'모델명과 파일명(경로포함)으로 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

在调用 GetModel 函数之前,首先创建 Modeler5.Application 实例并将其作为参数传递,如下所示。

Set m_odApp = New Modeler5.Application
Set odModel = GetModel(m_odApp, aFileNameOnly, aFileName)

如果未传递 Modeler5.Application 实例,则会在函数内部创建一个实例(第 4 行)。

5.4.2.从模型文件中获取实体列表

作为“Entity(Get)”表的“GetEntityListFromFile”函数实现。

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

属性数组方式比实体属性直接方式有更好的性能,但是在写这篇文章的时候,存在访问数组时无法正确获取值的现象,所以又回到了直接方式。

第 88 至 91 行使用 Variant Array 将内存中的二维数组一次性写入 Excel 工作表。有关对此的解释,请参阅以下文章。

VBA 编码模式:范围循环写入


5.4.3.为实体设置值

作为“CDAEntityList”类的过程“SetValue”实现。

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
  • 第 21 行:撤消/重做。 (节省内存并提高性能)
  • 第10、25、112行:用DoLog函数记录处理状态。 (该函数是使用Windows API 'OutputDebugMessage'的用户函数,这方面将单独发布)
  • 第83行:通过将包含实体属性的Array(Variant类型)分配给Entity.Values来一次性设置值。

到目前为止,我们已经了解了 DA# 宏中使用的 DA# Modeler API 对象模型、VBA 代码配置和源代码示例。

对于源代码来说,我在3年多的时间里时不时地重复编码和重构,所以整体代码一致性不是很好。整体重构应该在某个时候触及,但我不知道什么时候。

我们希望该工具对使用 DA# 的数据建模者和 DA(数据架构师)有所帮助。


<< 相关文章列表 >>

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

zh_CN简体中文