DA# Macro(6): DA# Modeler API

今回の記事では、DA# Macro(マクロ)で使用しているDA# Modeler API Object ModelとVBAコード構成、ソースコードの例を見ていきます。

5. DA# Modeler API

5.1。 DA# Modeler API Object Model

前の記事(DA# Macro(1): DA#, DA# API, DA# Macro(マクロ)の概要)でDA# API Object Modelについて少し紹介しました。

DA# Modelerが提供するクラスのリストは次のとおりです。 (Excel VBE(Visual Basic Editor)で「オブジェクトを参照」機能で確認した。)

DA# Modeler에서 제공하는 클래스 목록
DA# Modelerが提供するクラスのリスト

DA# Modeler APIのObject Modelは次のとおりです。 (公式マニュアルにはない内容であり、直接整理した。)

DA# API Object Model
DA# API Object Model

この中で最も重要なApplicationからAttributeまでのObject階層は次の通りである。

1)Application -> 2)Models -> 3)Model -> 4)Entitys -> 5)Entity -> 6)Attributes -> 7)Attribute

この層をDA# Modelerの例モデルと表記すると、次のようになります。

DA# 모델러 API 핵심 Object
DA#モデラーAPIコアオブジェクト

DA# Modeler APIのObject Model階層と概念、用途を簡単にまとめると、次のようになります。

DA# Modeler API Object Model 계층 구조
DA# Modeler API Object Model階層

5.2。 Excel VBAでDA# Modeler APIを使用する

DA# Modeler APIをExcel VBAで Early binding 方法で使用するには、まず「Modeler5」ライブラリを参照して追加する必要があります。

▼ Excel VBE(Visual Basic Editor)に切り替え(ショートカットキー Alt + F11)してツール>参照メニューを実行します。

도구 > 참조 메뉴 실행
ツール > 参照メニューの実行

▼「利用可能な参照」リストで「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# Macro VBAコードの設定

Worksheet、UserForm、Module、Classのリストと簡単な説明は次のとおりです。

DA# Macro VBA 코드 구성
DA# Macro VBAコードの設定

▼ Worksheet オブジェクト

  • shtAttributeGet: “Attribute(Get)” シート UI 機能の実装
  • shtAttributeSet: “Attribute(Set)” シート UI 機能の実装
  • shtEntityGet:「Entity(Get)」シートUI機能の実装
  • shtEntitySet:「Entity(Set)」シートUI機能の実装
  • shtReverse:「Reverse」シートUI機能の実装

▼フォームオブジェクト

  • frmModelFromFile:「Select Model(File)」ボタンをクリックしたときに表示されるユーザーフォーム
  • frmProgress:機能処理中の進行状況を表示するためのユーザーフォーム

▼ モジュールオブジェクト

  • modDAConstType: 機能の実装に必要な定数宣言、DA# Enum および Name 変換関数の実装
  • modDAModeler:DA#関連機能の実装(GetModel、Reverse、SetEntity、SetAttributeなど)
  • modTest: Test コード
  • modUtil:共通機能(DoLog、ClearList、GetElapsedTimeなど)
  • modWinAPI:現在使用されていません

▼クラスモジュールオブジェクト

  • CDAAttribute: 属性 1 個単位のクラス
  • CDAAttributeList: 属性リストを Dictionary 構造 (Key-Value) で管理するクラス
    • Key: ModelName:KeyName (KeyName はエンティティ名、属性名またはテーブル名、列名形式)
    • Value: CDAAttribute instance
  • CDAEntity: エンティティ 1 個単位のクラス
  • CDAEntityList: エンティティのリストを Dictionary 構造 (Key-Value) で管理するクラス
    • Key: ModelName:KeyName (KeyName はエンティティ名またはテーブル名)
    • Value: CDAEntity instance
  • CDAFK:FK 1個単位のクラス
  • CDAFKList: FK リストを Dictionary 構造 (Key-Value) で管理するクラス
    • Key: ModelName:親エンティティ名->子エンティティ名
    • Value: CDAFK instance
  • CDAModel: Model 1個単位のクラス
  • CDAModelList: Model リストを Dictionary 構造 (Key-Value) で管理するクラス
    • Key: ModelName
    • Value: CDAModel instance
  • CDASubject: トピック領域 1 単位のクラス
  • CDASubjectList:サブジェクト領域のリストを辞書構造(Key-Value)で管理するクラス
    • Key: ModelName:SubjectName
    • Value: CDASubject instance
  • CUDPNameType:UDP名、対象かどうかを管理するクラス(UDP Get / Setに使用)

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 instanceを最初に作成してパラメータに渡します。

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

Modeler5.Application instanceを渡さない場合は、関数内部でinstanceを生成します。

5.4.2。モデルファイルからEntityリストを取得する

「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

エンティティPropertyダイレクトアプローチよりもProperty Arrayアプローチはパフォーマンスが良いが、この記事を作成する時点でArrayにアクセスしたときに値を正しくインポートできないという現象があり、直接アプローチに戻しておいた。

行88〜91は、Variant Arrayを使用してメモリ上の2次元配列をExcelシートとして一度に書く。これについては次の記事を参照してください。

VBAコーディングパターン:Range Loop - Write


5.4.3。 Entityに値を設定する

クラス「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行目: Undo/Redoを解除する。 (メモリー節約と性能向上目的)
  • 行10、25、112:DoLog関数で処理状態を記録します。 (この関数はWindows API 'OutputDebugMessage'を利用するユーザー関数であり、これに関して別々に投稿する予定です)
  • 行83:エンティティPropertyが格納されたArray(Variant type)をEntity.Valuesに割り当てて、一度に値を設定します。

ここまでDA# Macroで使用しているDA# Modeler API Object ModelとVBAコード構成、ソースコードの例を見てきました。

ソースコードは3年余りにわたって時間がかかるときに時々コーディングとリファクタリングを繰り返すので、全体的なコードの一貫性は悪くない。全体的なリファクタリングはいつか触れなければならないが、いつかは分からない。

DA#を使用するデータモデラー、DA(Data Architect、データアーキテクト)にこのツールが役立つことを願っています。


<< 関連記事のリスト >>

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ja日本語