AsprovaのCOMインターフェイスとプラグイン拡張の詳細

2011/10/04

COMインターフェイス

生産スケジューラAsprovaは、COMインターフェイスを公開しており、EXEファイルやプラグイン(DLL)で機能を拡張できます。これにより、メモリー上に展開されているプロジェクトオブジェクトを取得し、Asprovaの下位のテーブルオブジェクトにアクセスすることが可能です。

Asprova本体は、イベントの発生タイミングにプラグインを実行させるためのHookを用意しており、このイベントを表すアクセスポイントであるプラグインキーは、Wordpressのdo_actionフックまたはapply_filtersフックに該当します。

Asprova

インドネシアの生産スケジューラ

生産計画と負荷計画は密接に関連しており、数量ベースでの確認が求められる。PSI表を用いて生産数量、消費数量、在庫数量を対比することが重要。計画は実績と比較して進捗を確認し、在庫数量に基づく予測でリセットされる。

続きを見る

この記事でわかること

  • AsprovaはCOMインターフェイスを通じて機能を拡張できます。
  • DLLファイルはAsprovaのEXEと同じフォルダに配置する必要があります。
  • プラグインキーはWordpressのdo_actionフックに似ています。
  • Asprovaのプラグインは4つの引数で登録されます。
  • VBからJet Database EngineにアクセスするにはADOを使用します。

COMインターフェイスとは

AsprovaはCOM (Component Object Model)を利用して、内部のデータや処理内容を公開する仕組みを持っています。これにより、プラグイン(ActiveX DLLファイル)やオートメーションクライアント(Standard EXEファイル)から機能を追加することが可能です。プラグインはAsprovaから関数を呼び出す形で、オートメーションクライアントは外部プログラムからAsprovaにアクセスする形で機能します。

DLLファイルはAsprovaのEXEと同じフォルダに配置され、起動時に自動的に読み込まれます。DLLはAsprovaの内部コマンドとして登録され、ユーザー定義メニューに組み込むことで、AsprovaからDLLを呼び出すことができます。一方、EXEの場合はプロジェクトファイルの名前を指定して開くことで、アクティブなプロジェクトを取得します。

DLLの配置場所

DLLは、起動するEXEから見て特定の場所に配置する必要があります。これにより、EXEがDLLを正しく認識し、機能を正常に実行できます。以下に、DLLを配置するための具体的な手順を示します。

  1. EXEとDLLを同じディレクトリに配置します。これにより、EXEは直接DLLを見つけることができます。
  2. EXEを起動する際に、DLLのディレクトリをカレントディレクトリとして設定して起動します。これにより、EXEはそのディレクトリ内のDLLを優先的に使用します。
  3. DLLをsystem32ディレクトリに配置します。このディレクトリは、Windowsシステムの一部として認識されるため、DLLが広く利用される場合に便利です。
  4. DLLをWindowsディレクトリに配置します。これもシステム全体でDLLを利用する際に有効です。
  5. Path環境変数にDLLが配置されているディレクトリを設定します。これにより、システム全体でDLLを認識しやすくなります。

事例:特定のアプリケーションでDLLが見つからない場合、Path環境変数の設定が不足していることが原因であることがあります。この場合、適切に設定することで問題を解決できます。

要点:DLLの配置場所を正しく設定することで、EXEがDLLをスムーズに認識し、正常に動作することが可能になります。

開発環境の参照設定(プラグイン内からAsprovaのライブラリを使用)

参照設定は、GUIを持たないActiveXオブジェクトのタイプライブラリをプロジェクトで利用するために、プロジェクトファイル(.vbpファイル)内に保存されます。これにより、プラグイン(プロジェクトファイルをコンパイルしたDLL)からCOMインターフェイスを通してAsprovaのライブラリにアクセスできます。

参照設定を行うことで、Dim変数宣言の際にそのオブジェクトの型を使用したり、new演算子でインスタンスを生成することが可能になります。

  1. Asprovaプロジェクトクラス

    Dim project As aslib.ASBProject

  2. 拡張プラグインDLLで使うプラグインキーに関連のあるオブジェクトのリスト

    Dim ArgList As ASPArgList

  3. 品目クラス

    Dim item As ASBItem

プラグインからAsprovaのライブラリを参照する場合、以下の2つのAsprovaのクラスライブラリを開発環境の参照設定から登録します。

  1. As 1.1 Type Library
  2. AsPlugInManager 1.0 Type Library

プラグインのプロジェクトファイルの構成

プラグインの場合、Asprovaから呼び出す関数をASDefaultクラスのAutoRegistrationメソッドに登録します。Asprovaの「プラグイン情報」にプラグインとして登録しておけば、Asprova起動時にAutoRegistration関数が自動的に呼ばれ、プロジェクトオブジェクト内に実装されます。

COMポート2
Standard EXE(オートメーションクライアント)の場合はASDefaultクラスは必要ありません。

Asprovaのプラグインマネージャー(プラグイン登録関数)のAddASPlugInメソッドに4つの引数を渡すことによりプラグインを登録します。その内容は「自分はFactoryというプロジェクトで、OvertimeというクラスにAddOverTimeというメソッド(エントリ関数)を用意しているから、プラグインキーKeyHookGenericのタイミングで呼んでください」というものです。

プラグインキー(アクセスポイント)に対応するフックと関数のマッピング

Asprovaは、特定のイベントごとにプラグインを実行するためのフックを提供しています。このフックは、各イベントを表すアクセスポイントとして機能し、プラグインキーと呼ばれます。例えば、KeyHookGenericは「コマンドの追加」を示し、追加したコマンドが起動するタイミングでプラグインを実行します。

Option Explicit

Public Function AutoRegistration(plugInManager As ASPPlugInManager, module As ASPModule) As Boolean

    'このモジュールのコメントを設定します
    module.Comment = "APS Extended Functionality PlugIns (VB)"

    'プラグインオブジェクトを保持する変数を定義します
    Dim plugIn As ASPPlugIn

    ' ---------------------------------------------------------------------------------------------

    'プラグインマネージャを呼び出し、新しいプラグインを登録します。呼び出しメソッド名はAddASPlugIn です

    ' 第1Param:プラグイン表示名
    ' 第2Param:プラグインが実装されているモジュール及びクラスを表すProgID
    ' 第3Param:プラグインのエントリ関数名(呼び出し名)
    ' 第4Param:プラグインが使用されるコンテキストを表すキー名

    '(1)オーバータイムや土日残業を自動的に計算しカレンダーテーブルにセットする
    Set plugIn = plugInManager.AddASPlugIn("オーバータイムを残業と土曜出勤に組み込む", "Factory1.OverTime", "AddOverTime", ASPlugInKeyName.KeyHookGeneric)

    'このプラグインにコメント等などを設定します。

    plugIn.Comment = "オーバータイムを平日残業2時間と土曜2シフト出勤に割り振る。"

    'プラグイン呼び出し順(同一プラグインキーのプラグインが複数あったときのため)
    plugIn.Order = 1

    '自動登録が正常に行われたという事でTrue を返します。
    AutoRegistration = True

End Function

Asprovaは起動時にプラグインを自動的に読み込み、内部コマンドのプラグインに「エントリ関数の表示名」を表示します。プラグインの中からAsprovaのプラグインマネージャーを呼び出し、4つの引数を渡すことでプラグインを登録します。

COMポート3

COMポート(communication port)のポートと同じ考え方

COMポートとCOMインターフェイスのCOMは異なるものですが、外部インターフェイスとの標準規格という点では共通しています。ソフトウェアやハードウェアには、外部とデータを入出力するための標準化されたインターフェース(ポート)があります。例えば、POPとSMTPサーバーのポートや、DB接続時のポートはTCP/IPのポートです。

標準的なパソコンには、キーボードなどの周辺機器を接続するためのPS/2ポートやUSBポート、LANポート(Ethernetポート)などが備わっています。

ソフトウェアでは、外部装置や通信ネットワークとのデータ送受信を標準的に扱う方法がOSによって提供され、通信相手を識別するためにポートが使われます。

Windowsでは、モデムやプリンタ、イメージスキャナなどにアプリケーションソフトが統一的にアクセスできるよう、入出力方式を統一した「COMポート」が提供されています。アプリケーションソフトは、対象機器がどのCOMポートに接続されているかを知るだけで、入出力を取り扱えます。

例えば、USBバーコードを接続する場合にはCOM13が割り当てられますが、物理的にPCに13個のインターフェイスは存在しないため、COM13は仮想的なものです。TCP/IPを利用したネットワーク通信では、通信機器やコンピュータのIPアドレスの下に設けられた補助アドレスとして、0から65535までの「ポート番号」が使われます。

これにより、1台のコンピュータで複数のサービスを提供したり、複数のコンピュータと同時に通信できるようになります。単に「ポート」と言う場合、TCP/IPのポート番号を指すことが多いです。

レコードセットのフィールド値をttxファイルを介してCrystal reportのフィールド定義にマッピング

Asprovaの作業テーブルをAccessにエクスポートして現品票を発行します。Crystal report 9にはParameter Fieldがあり、VBからPassing Parameterすることが可能です。しかし、Record Setを渡すと自動的にフィールドから値を取得し、Crystal Report Viewerという無償のActiveXコンポーネントビューアーにレポートを表示できます。

    CrRep.Database.SetDataSource rs, 3, 1

    CRViewer91.ReportSource = CrRep

    CRViewer91.ViewReport

このコードの3番目の引数1はTable Numberを表します。

    '選択されたコンボのORDERCODを取得

    result = Combo1.List(Combo1.ListIndex)


    'Passing parameter from VB6 to CR using CRAXDRT

    Dim CrApp As CRAXDRT.Application

    Dim CrRep As CRAXDRT.Report


    'ORDERTBLからORDERCODのレコードセットを取得

    Dim conn As New ADODB.Connection

    Dim rs As ADODB.Recordset


    Dim mySQL As String


    cn.Open _

        "Provider = Microsoft.Jet.OLEDB.4.0; " & _

            "Data Source = " & CurDir & "\NNA.mdb"


    Set CrApp = New CRAXDRT.Application

    Set CrRep = CrApp.OpenReport(App.Path & "\reports\TravelSheet.rpt", & _

                    crOpenReportByTempCopy)


    CrRep.DiscardSavedData


    If result <> "ALL" Then

        mySQL = "SELECT * FROM OPERATIONTBL WHERE ORDERCOD='" & _

            Combo1.Text & "' ORDER BY ORDERCOD"

    Else

        mySQL = "SELECT * FROM OPERATIONTBL ORDER BY ORDERCOD"


    End If

    With rs

        .ActiveConnection = cn

        .CursorLocation = adUseServer

        .CursorType = adOpenKeyset

        .LockType = adLockOptimistic

        .Properties("IRowsetIdentity") = True


        .Open mySQL

    End With

    CrRep.Database.SetDataSource rs, 3, 1

    CRViewer91.ReportSource = CrRep

    CRViewer91.ViewReport

しかし、Crystal Report ViewerのようなWin7での標準以外のコンポーネントを使った開発アプリはXPで問題を起こす可能性が高く、crviewer9.dllが古いPCで問題を引き起こすことがあります。そのため、CR8.5にダウングレードし、以下のようにコードを変更します。

Dim result As String


    '選択されたコンボボックスのORDERCODを取得

    result = Combo1.List(Combo1.ListIndex)


    'ORDERTBLからORDERCODのレコードセットを取得

    Dim conn As New ADODB.Connection

    Dim rs As ADODB.Recordset


    Dim mySQL As String


    cn.Open _

        "Provider = Microsoft.Jet.OLEDB.4.0; " & _

            "Data Source = " & CurDir & "\DNN.mdb"


    If result <> "ALL" Then

        mySQL = "SELECT * FROM OPERATIONTBL WHERE ORDERCOD='" & _

                    Combo1.Text & "' ORDER BY ORDERCOD"


    Else

        mySQL = "SELECT * FROM OPERATIONTBL ORDER BY ORDERCOD"


    End If


    rs.Open mySQL, cn, adOpenKeyset, adLockOptimistic


    With rptControl

        .WindowTitle = "Travel Sheet"

        .ReportFileName = App.Path & "\Reports\TravelSheet.rpt"


        .SetTablePrivateData 0, 3, rs

        .WindowShowPrintBtn = True

        .WindowShowPrintSetupBtn = True


        .RetrieveDataFiles

        .WindowState = crptMaximized

        .Destination = crptToWindow

        .Action = 1

    End With

CRファイルのReport Expertでttxファイル(rpt.ttx)を指定すると、コード内のレコードセットのフィールド値が自動的にCRファイルのフィールドにマッピングされます。

reportexpert

ttxファイルにタブ区切りでフィールド名、属性、長さを定義する方法は日本では古典的ですが、インドネシアではまだ現役です。

ORDERCOD	string	100

PROCNO	number

RESOURCE	string	100

ITEM	string	100

QTY	number

STARTDATE	string	100

ENDDATE	string	100

WORKTIME	string	100

PARENTITEM	string	100

CLASS	number

VBからJet Database Engineにアクセス

VBからJet Database Engineにアクセスするためには、まず参照設定で「Microsoft ActiveX Data Objects 2.1 Library」を追加します。

Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset

conn.Open _
    "Provider = Microsoft.Jet.OLEDB.4.0; " & _
"Data Source = C:\Users\Toshiba\Desktop\ERP\VB\LinkWithERP.mdb"

'DELETE
Dim query1 As String
query1 = "DELETE * FROM ORDER_SOURCE"
rs.Open query1, cn, adOpenKeyset, adLockOptimistic

'SELECT
Dim query2 As String
query2 = "SELECT * FROM ORDER_SOURCE"
rs.Open query2, cn, adOpenKeyset, adLockOptimistic

Do Until rs.EOF
    X1 = rs!Order_Code
    X2 = rs!Order_Item
    X3 = rs!Order_Qty

    rs.MoveNext
Loop

ADOやODBCは、Jet Database Engine(MDB)を利用するためのミドルウェアです。MS-Access形式のMDBファイルは、Jet Database EngineというMicrosoft社が開発したリレーショナルデータベースエンジンのファイルであり、データ格納用のコンテナです。

これはMicrosoft Accessアプリケーションとは独立した別個のファイルであり、MS-Accessがインストールされていない環境でも使用可能です。

MS-AccessがインストールされていないPCでも、Excel VBAでADOを使ってテーブル操作が可能で、MSのサイトからRuntimeをダウンロードして開くこともできます。ライセンスの制限にも抵触しません。Runtimeとは、アプリケーションの開発機能を省き、実行機能のみを取り出したプログラムのことです。

  • http://www.microsoft.com/ja-jp/download/details.aspx?id=4438

メモ帳がテキストファイルを編集する唯一のアプリケーションではないのと同様に、システムからDB(RDB)への接続はADO接続かODBC接続のどちらかが一般的です。両者の違いは以下の通りです。

  • ADOはOLEDBをActiveXコントロールとして操作するためのインターフェース
  • ODBCはOLEDBのうちRDBを提供するインターフェース

OLEDBの中にODBCプロバイダがあり、RDBへ接続しますが、開発者はADOのインターフェースでOLEDBにアクセスできます。接続オブジェクトとレコードセットオブジェクトの生成方法は、CreateObject関数を使って新規オブジェクト変数を生成し、Setでオブジェクトへの参照をオブジェクト変数に代入します。

Dim conn As Variant
Dim rs As Variant
Set conn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")

Newを使ったオブジェクト参照の代入は、SetでNewを使って新しくオブジェクトを作成し、オブジェクト変数にオブジェクトの参照を代入します。

Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset

VBからMySQLにアクセス

Windows 64bit版のPCでも、開発環境であるVB6は32bitで動作するため、MySQL ODBC Connectorも32bit版を使用する必要があります。

ADODB接続の場合は問題ありませんが、DSN接続を行う際に32bit版のODBCドライバを64bit版Windowsにインストールすると、コントロールパネルからODBC設定画面を起動してもインストールしたMySQL5.1ドライバが表示されないことがあります。

この場合、コマンドプロンプトから以下のコマンドを実行して32bit版のODBCデータソースアドミニストレーター画面を表示し、DSN設定を行います。

  • %windir%\SysWOW64\odbcad32.exe

DSN接続の場合、以下のコードを使用して接続オブジェクトを生成します。

'Mysql5.1ドライバ用DSN用接続オブジェクト生成

Dim conn As New ADODB.Connection

Dim rs As New ADODB.Recordset

Dim dsn As String
dsn = "dsn=xxx;uid=yyy;pwd=zzz"
conn.Open dsn
conn.CursorLocation = 3

ADODB接続の場合、以下のコードを使用して接続オブジェクトを生成します。

'Mysql5.1ドライバ用ADO用接続オブジェクト生成

Dim conn As New ADODB.Connection

Dim rs As ADODB.Recordset

Dim strConn, xServer, xDatabase, xUID, xPass As String

If conn.State = 0 Then

    xServer = "localhost"

    xDatabase = "xxx"

    xUID = "yyy"

    xPass = "zzz"

    strConn = "DRIVER={MySQL ODBC 5.1 Driver};SERVER=" & xServer & _
               ";PORT=3306" & _
               ";DATABASE=" & xDatabase & _
               ";USER=" & xUID & _
               ";PASSWORD=" & xPass & _
               ";OPTION=3;"
    conn.Open strConn

End If

'DELETE

Dim query1 As String

query1 = "DELETE * FROM ORDER_SOURCE"

rs.Open query1, strConn

'SELECT

Dim query2 As String

query2 = "SELECT * FROM ORDER_SOURCE"

rs.Open query2, strConn

Do Until rs.EOF

    X1 = rs!Order_Code

    X2 = rs!Order_Item

    X3 = rs!Order_Qty

    rs.MoveNext

Loop

VBからExcelにアクセス

VBからExcelにアクセスするためには、まず参照設定からMicrosoft Excel 12.0 Object Libraryを追加します。

'Excel関連オブジェクト

Dim xlApp As Excel.Application

Dim xlBook As Excel.Workbook

Dim xlSheet As Excel.Worksheet



'ファイル名(フルパス)

Dim strFilename As String

strFilename = "C:\SO\Delivery Schedule.xls"



'シート名

Dim strSheetName As String

strSheetName = "Delivery Schedule"



'Application生成

Set xlApp = CreateObject("Excel.Application")



'EXCELを開く

'xlApp.Workbooks.Open FileName:=strFilename, UpdateLinks:=0



'Workbookオブジェクト生成

'Set xlBook = xlApp.Workbooks(Dir(strFilename))

Set xlBook = xlApp.Workbooks.Open(strFilename)



'Worksheetオブジェクト生成

Set xlSheet = xlBook.Worksheets(strSheetName)



'Worksheetデータの取得

Dim cnt As Integer

cnt = 1



Do

    'ORDCOD = Worksheets("Delivery Schedule").Cells(cnt, 1).Textでも取得可

    ORDCOD = xlSheet.Cells(cnt, 1).Text

    ORDITM = xlSheet.Cells(cnt, 2).Text

    ORDQTY = xlSheet.Cells(cnt, 3).Text



    cnt = cnt + 1

Loop While ORDCOD <> ""

ブックオブジェクト生成の際、ファイル名を変数から代入する場合は拡張子を削除しないと取得できません。ただし、固定パスを文字列で代入する場合は問題ありません。InStrRevを使用してピリオドの位置を取得し、拡張子を除外します。

strFilename = CurDir & "\data\" & strFilename

'拡張子を削除する(これをやらないとエラーになる)

strFilename = Left(strFilename, InStrRev(strFilename, ".") - 1)



Set xlBook = xlApp.Workbooks.Open(strFilename)

ワークシート名の取得と追加は以下の通りです。

'ワークシート名の取得

j = 0

For Each ws In xlBook.Worksheets

    sheetArry(j) = ws.Name

    j = j + 1

Next



'ワークシート6の追加

Set xlSheet = xlBook.Worksheets.Add  'ワークシートを追加

xlSheet.Name = "New sheet"

VBからテキストファイル(CSV)にアクセス

VBでCSVファイルにアクセスするには、まず参照設定からMicrosoft Scripting Runtimeを追加します。FileSystemObjectは、Windowsでファイルシステムを簡単に扱えるようにするためのコンポーネントです。

'DB接続オブジェクトとレコードセットオブジェクト生成

Dim conn As New ADODB.Connection

Dim rs As New ADODB.Recordset



'CSVファイルを扱うためのコンポーネントオブジェクト生成

Dim objFSO As New Scripting.FileSystemObject



'DBに接続

conn.Open _

    "Provider = Microsoft.Jet.OLEDB.4.0; " & _

    "Data Source = " & CurDir & "\SO.mdb"



'SELECTでレコードセット生成(空)

query1 = "SELECT * FROM ORDER_SOURCE"

rs.Open query1, conn, adOpenStatic, adLockOptimistic



'CSVファイルのデータをオブジェクトに読み込む

Set objFile = objFSO.OpenTextFile("C:\APS_ERP\VB\" & CSVNAME)



'1行ずつ読み込みレコードセットに格納

cnt = 0

Do Until objFile.AtEndOfStream

    strMastflow = objFile.ReadLine

    arrMastflow = Split(strMastflow, ",")



    rs.AddNew

    rs("Order_Code") = arrMastflow(0)

    rs("Order_Item") = arrMastflow(1)

    rs("Order_Qty") = arrMastflow(2)

    rs.Update



    cnt = cnt + 1

Loop

事例:この方法を用いることで、VBから直接CSVファイルを読み込み、データベースに格納することが可能です。特に、ADODB.ConnectionとADODB.Recordsetを使用することで、データベースとの連携がスムーズに行えます。

要点:VBでCSVファイルを扱う際は、FileSystemObjectを活用し、データベースとの連携を効率的に行うことが重要です。

OLE DB関連用語

ADOを通してデータベースにアクセスするまでのミドルウェアやコンポーネントの関係は、荷送り人(Shipper)から荷受人(Consignee)に荷物を海上輸送する過程に似ています。

oledb

開発アプリケーションプログラム(Shipper)からRDBやExcel、Texfile(Consignee)にアクセスするには、OLE DBデータプロバイダーという仲介人(Forwarder)に手続きを依頼しますが、直接OLE DBとやりとりするのは煩雑なため、ADO(カーゴ業者)に任せます。

  • OLE DB(Object Linking and Embedding DataBase)は、Microsoft社によって開発された、データベースの種類に依存せず統一的な手法でデータベースにアクセスするためのプログラミングインターフェースです。DB(Consignee)に対して、OLE DBはCOMコンポーネントの集合体として実現され、どんなプログラミング言語からでも利用可能です。OLE DBは「コンシューマ (consumer)」と「プロバイダ(provider)」に分けられ、コンシューマはデータにアクセスするアプリケーション、プロバイダはインタフェースを実装したソフトウェアコンポーネントで、コンシューマにデータを提供します。
  • COMインターフェイスは、COM (Component Object Model)で内部のデータや処理内容を公開する仕組みです。プラグイン(ActiveX DLLファイル)やオートメーションクライアント(Standard EXEファイル)からアプリケーションが公開している機能にアクセスし、プラグインを開発・公開できます。
  • ADO(ActiveX Data Object)は、OLE DBプロバイダを介してデータベースにアクセスするためのコンポーネントで、OLE DBをActiveXコントロールの形で使えるようにしたプログラミングインターフェースです。ADOを利用してVBからテーブルレコードを直接操作できます。
  • ActiveXコントロールは、従来OLEコントロールと呼ばれていた技術にインターネット対応の拡張を施したものです。ActiveXコントロールはネットワークを通じてWebサーバからダウンロードされ、Internet Explorerに機能を追加する形で使用されます。

プラグインDLLは機能(関数)の追加、拡張インターフェイスDLLは既存ロジックに対する変更のために開発します。AsDefaultクラスのAutoRegistrationメソッドの中にプラグインキー(KeyHookGeneric)を定義するか、インターフェイス(IEIIFilterCalc ReplenishOrderLotSizing)を定義するかの違いです。

プラグインキーとインターフェイスの違い

Asprovaでプラグインを使用する際、AsDefaultクラスのAutoRegistrationメソッド内でプラグインキー(KeyHookGeneric)を定義すると、該当するイベントが発生したときにエントリ関数が呼び出され実行されます。

同様に、EII(Extension Interface Implementation)のAsDefaultクラスのAutoRegistrationメソッド内でインターフェイス(IEIIFilterCalc ReplenishOrderLotSizing)を定義すると、該当するイベントが発生した際にエントリ関数が呼び出されます。

インターフェイスはプラグインキーよりも呼び出しにかかるオーバーヘッドが小さくなるようにカスタマイズされており、オーダ展開や自動補充、ロットまとめなど頻繁に呼び出しがかかるロジックの変更に適しています。プラグインDLLは機能(関数)の追加を目的とし、拡張インターフェイスDLLは既存ロジックの変更を目的として開発されます。

プラグインDLL

拡張インターフェイスを使用すると、プラグインキーを使用するよりも呼び出しにかかるオーバーヘッドが小さいため、リスケジュールの中で頻繁に発生するイベントから呼び出したいエントリ関数を追加する場合に適しています。

補充オーダのロットサイズを変更する拡張インターフェイス(DLL)

補充オーダのロットサイズは「製造ロットサイズMAX」「製造ロットサイズMIN」「製造ロットサイズUNIT」によって決まりますが、FilterCalcReplenishOrderLotSizingは「オーダ展開」コマンドの中での紐付け時に呼び出され、以下の3つのオブジェクトを取得して補充オーダのロットサイズを変更(上書き)し、結果をArgListに渡します。

  1. 補充品目の配列 ArgAsObject(kArgItem)
  2. 親オーダの初工程の作業入力指図のリスト ArgAsObject(kArgObjectList)
  3. ロットサイズのリスト ArgAsSafeArray(kSafeArrayArgDouble)

ロットサイズ

  1. ロットサイズは自動補充「はい」
  2. ロットサイズは補充オーダ生成時に決定される
  3. 作業入力指図のリスト(2次元配列)と作業出力指図のリスト(品目)

オーダ展開のプロセス

  1. 親オーダの作業(作業入力指図と作業出力指図)を生成します。初期状態での親オーダとは受注オーダ、または登録オーダの製造オーダであり、製造BOMより作業入力指図、作業出力指図を生成します。
  2. 自動補充では、親オーダの作業の作業入力指図が紐付け対象かどうか確認します。親オーダが在庫(絶対量)よりも過去の日時の場合、作業入力指図は紐付け対象外となり、不足分の作業入力指図の製造オーダを自動生成します。親オーダの作業入力指図(入力品目)の不足分の製造オーダを子オーダとして生成し、子オーダの作業入力指図の不足分の製造オーダを孫オーダとして生成します。
  3. オーダ間の紐付け1回目では、自動補充設定のある受注オーダ、製造オーダ、購買オーダ、在庫オーダの紐付けを行います。自動補充設定のない製造オーダ同士(製造BOMで繋がりのある品目同士)も紐付けされます。

製造オーダ完成7回分で前工程をまとめる例

  1. 1回目の自動補充でitemにB1が、instにBのリストが入ります。作業M4の入力指図B1の不足数量(在庫がないのでRemainingQtyはBそのもの)を7回足しこみます。
  2. 2回目の自動補充でitemにCが、instにAのリストが入ります。作業M2の入力指図Cの不足数量を7回足しこみます。
  3. inst.Operation.OperationMainRes.Code='M4'が条件なので(2)は実行されません。

プラグインDLL

Asprovaの各テーブルにアクセスするためには、メモリ上に展開されているAsprovaのプロジェクトオブジェクトを通す必要があります。このプロジェクトオブジェクトの取得方法はDLLとEXEでは異なります。

DLLの場合は引数argsにASPArgListというプラグインキーに関連のあるオブジェクトのリストをロードし、ここからプロジェクトオブジェクトを取得しますが、EXEの場合は所定のプロジェクトファイルをロードしたドキュメントオブジェクトからアクティブなプロジェクトを取得します。

拡張プラグイン(DLL)の場合

'(ASPArgList内にあるオブジェクトの定義と取得)

'------------------------------------------------------------------

Public Function AddPersonPlan(args As ASPArgList) As TReturnType



    'APSの各テーブルのオブジェクトにはプロジェクトオブジェクトからアクセスします。

    'プロジェクトオブジェクトはargsインターフェイスから取得します。

    'ASPAgrListオブジェクトからプロジェクトオブジェクトをASBProject型変数に代入することにより引数を受け取ります。



    Dim project As aslib.ASBProject

    Set project = args.ArgAsObject(kArgProject)



    'プロジェクトオブジェクトからRootObjectをASORootObject型変数に代入します。

    Dim root As aslib.ASORootObject

    Set root = project.RootObject



    'プロジェクトオブジェクトからRootCalendarオブジェクトをASBCalendar型変数に代入します。

    Dim calendarRoot As aslib.ASBCalendar

    Set calendarRoot = project.RootCalendar



    'プロジェクトオブジェクトからRootResourceオブジェクトをASBResource型変数に代入します。

    Dim resourceRoot As aslib.ASBResource

    Set resourceRoot = project.RootResource



    'プロジェクトオブジェクトからorderRootオブジェクトをASBOrder型変数に代入します。

    Dim orderRoot As aslib.ASBOrder

    Set orderRoot = project.orderRoot



    'プロジェクトオブジェクトからitemRootオブジェクトをASBItem型変数に代入します。

    Dim itemRoot As aslib.ASBItem

    Set itemRoot = project.itemRoot



    'プロパティIDの格納用変数の定義

    Dim propID1 As Long



'(取得したオブジェクトへのアクセス)

'------------------------------------------------------------------

    'カレンダーオブジェクトの子供の数(レコード数)

    calendarCount1 = calendarRoot.ChildCount



    'ルートオブジェクトを使って資源コードのプロパティIDを取得します。

    propID1 = root.LookupPropID("Cal_Resource")



    'レコードが終了するまでループします。

    'ChildAsCalendarの引数は1から(0は最後のデータを表します)。

    For i = 1 To calendarCount1

        'レコードにアクセスします。

        Set calendar = calendarRoot.ChildAsCalendar(i)



        'GetAsStrメソッドでプロパティの値にアクセスします。プロパティが配列値でなければ2番目の引数は1を設定します。

        res1 = calendar.GetAsStr(propID1, 1)

    Next



End Function

Standard EXEの場合

Asprovaの外部にあるEXEプログラムからAsprovaのオブジェクトを取得する際には、ドキュメントオブジェクトにプロジェクトファイルをロードし、そこからアクティブなプロジェクトを取得する必要があります。以下にその手順を示します。

Private Sub Command1_Click()

    '■■■Asprova関連オブジェクト■■■

    'Asprovaプロジェクトオブジェクト定義

    Dim m_pProject As ASBProject

    Dim m_pDoc As ASFDocument

    'アスプローバアプリケーションを取得

    Dim app As ASFApplication

    Set app = New ASFApplication

    'アスプローバドキュメントの名前を指定して開く

    Set m_pDoc = app.Deserialize(CurDir & "\data.aru")

    'アクティブなプロジェクトをドキュメントから取得

    Set m_pProject = m_pDoc.ActiveProject

    '■■■作業テーブルから末端オーダ品目でマッチング■■■

    '作業オブジェクト取得

    Dim operation As ASBOperation

    Dim operationList As ASOObjectList

    Set operationList = m_pProject.GetOperationList(False)

    'ルートオブジェクトの取得

    Dim root As ASORootObject

    Set root = m_pProject.RootObject

    'propIDの取得(rootオブジェクトから取得)

    propID1 = root.LookupPropID("Work_OperationOutMainItemQty")

    'プロジェクト全体の作業を取得して1発マッチング

    operationList.FilterByExprStr ("WorkUser_MostRightOrderItem=='" & Left(Combo1.Text, 7) & "')

    '製造開始日時の昇順でソートする。

    operationList.SortByExprStr ("Work_OperationProductionStartTime,a")

    Do

        'リストのデータを取得

        Set operation = operationList.Object(i)

        '値の取得

        PrdQty = operation.GetAsStr(propID1, 1)

        '値の保存

        operation.SetAsStr propID1, 1, Text1.Text

        i = i + 1

    Loop While i <= operationList.ObjectCount

    '■■■資源テーブルのデータを1件ずつチェック■■■

    '資源オブジェクト定義

    Dim RootResource As AsLib.ASBResource

    Dim resource As AsLib.ASBResource

    '資源ルートオブジェクトの取得

    Set RootResource = m_pProject.RootResource

    'propIDの取得(rootオブジェクトから取得)

    propID2 = root.LookupPropID("Res_Code")

    '資源テーブルのレコード数

    ResourceCount = RootResource.ChildCount

    For i = 1 To ResourceCount

        Set resource = RootResource.ChildAsResource(i)

        ResCode = resource.GetAsStr(propID2, 1)

    Next i

    '■■■品目テーブルから品目コードでマッチング■■■

    '品目オブジェクトの定義

    Dim RootItem As ASBItem

    Dim Item As ASBItem

    '品目ルートオブジェクトの取得

    Set RootItem = m_pProject.RootItem

    '品目オブジェクトの取得

    Set Item = RootItem.FindChild(Left(Combo1.Text, 7))

    '品目テーブルでマッチしたレコード数

    ItemCount=Item.ChildCount
End Sub

よくある質問|AsprovaのCOMインターフェイス

本稿の内容に沿って、繰り返し出る問いを短く整理します。

AsprovaのCOMインターフェイスとは何ですか?

AsprovaのCOMインターフェイスは、内部のデータや処理内容を公開する仕組みです。これにより、プラグインやオートメーションクライアントから機能を追加することが可能です。

Asprovaのプラグインはどのように登録されますか?

Asprovaのプラグインは、プラグインマネージャーのAddASPlugInメソッドを使用して登録されます。このメソッドに4つの引数を渡すことで、プラグインが特定のイベントで実行されるように設定します。

DLLファイルはどこに配置すればよいですか?

DLLファイルは、AsprovaのEXEと同じフォルダに配置する必要があります。これにより、EXEがDLLを正しく認識し、機能を正常に実行できます。