〔実施形態1〕
以下、本発明の一側面に係る実施の形態(以下、「本実施形態」とも表記する)を、図1から図13に基づいて説明する。なお、図中同一または相当部分には同一符号を付してその説明は繰返さない。本実施の形態においては、例えば開発支援装置10を、PLC(Programmable Logic Controller)20(制御装置)で実行されるプログラム(例えば、ユーザプログラム)をユーザが作成するのを支援する開発支援装置の典型例として説明を行う。本発明の一態様に係る開発支援装置10についての理解を容易にするため、先ず、開発支援装置10を含む制御システム1の概要を、図2を用いて説明する。
§1.適用例
(制御システムの全体概要)
図2は、開発支援装置10を含む制御システム1の全体概要を示す図である。制御システム1は、マスタ装置としてのPLC20と、マスタ装置にネットワーク(フィールドネットワーク60)を介して接続される1つ以上のスレーブ装置40と、を含むマスタスレーブ制御システムである。PLC20は、フィールドネットワーク60を介したデータ伝送を管理しているという意味で「マスタ装置」と呼ばれる。
フィールドネットワーク60に複数のPLC20が接続される場合には、いずれか1つのPLC20がマスタ装置となり、残りのPLC20がスレーブ装置になる場合もある。また、PLC20およびスレーブ装置40のいずれとも異なる制御主体がマスタ装置になってもよい。すなわち、「マスタ装置」および「スレーブ装置」は、フィールドネットワーク60上のデータ伝送の制御機能に着目して定義されるものであり、各装置間でどのような情報が送受信されるかについては、特に限定されない。
PLC20は、制御システム1の全体の制御を行う。具体的には、PLC20は、スレーブ装置40を介して、センサなどの入力機器であるデバイス50からの情報を入力データとして取得する。PLC20は、予め組み込まれたユーザプログラムに従って、取得した入力データを用いた演算処理を実行する。PLC20は、前記演算処理を実行して、アクチュエータなどの出力機器であるデバイス50への制御内容を決定し、その制御内容に対応する制御データを、スレーブ装置40を介して、デバイス50へと出力する。
フィールドネットワーク60は、PLC20が受信し、またはPLC20が送信する各種データを伝送し、例えば、EtherCAT(登録商標)、PROFINET(登録商標)、MECHATROLINK(登録商標)-III、Powerlink、SERCOS(登録商標)-III、CIP Motionである。また、フィールドネットワーク60は、例えば、EtherNet/IP(登録商標)、DeviceNet、CompoNet(登録商標)などであってもよい。なお、以下では、フィールドネットワーク60上をデータフレームが順次転送されることで、PLC20とスレーブ装置40との間、または、複数のスレーブ装置40の間でデータが送受信される制御システム1について説明を行う。
スレーブ装置40は、PLC20をマスタ装置とするネットワーク(フィールドネットワーク60)におけるスレーブ装置であり、例えば、デバイス50との通信を管理する通信カプラ等のデバイス通信管理ユニットである。スレーブ装置40は、フィールドネットワーク60に直接接続される、サーボドライバであってもよい。
デバイス50は、例えばセンサなどの入力機器であり、また、例えばアクチュエータなどの出力機器である。1つ以上のデバイス50が、通信ケーブルを介して、スレーブ装置40に接続される。
開発支援装置10は、例えばUSB(Universal Serial Bus)ケーブルである通信ケーブルを介して、PLC20に接続する。開発支援装置10は、PLC20で実行されるユーザプログラム、および、制御システム1に対する各種の設定情報などを生成するための情報処理装置である。
開発支援装置10は、例えば、PLC20の開発環境を提供し、ユーザが、制御目的(たとえば、対象のラインおよびプロセス)に応じてユーザプログラム等のプログラムを作成する(作成・編集する)ための環境を提供する。ユーザは、開発支援装置10の提供する開発環境(プログラミングツール)を用いて、PLC20で実行させる制御プログラム(ユーザプログラム)のプログラムコードを作成する。開発支援装置10は、PLC20で実行させる制御プログラムをユーザが作成・編集するのを支援するため、デバック機能およびシミュレーション機能を有していてもよい。
また、開発支援装置10は、例えば、PLC20による状態値の取得(入力リフレッシュ)のタイミング、および、PLC20による出力値の更新(出力リフレッシュ)のタイミングの算出および設定を実行してもよい。開発支援装置10は、PLC20の運転状態、および各種データの値などを監視してもよい。
開発支援装置10は、PLC20のプログラミング、コンフィグレーション(構成設定)、デバッグ、メンテナンス、モニタリング機能の他、3Dモーションシミュレーションにも対応した統合開発環境を提供する装置であってもよい。また、開発支援装置10は、スレーブ装置40のための各種のパラメータの設定および調整を行ってもよい。
開発支援装置10は、典型的には、汎用のコンピュータで構成される。例えば、開発支援装置10で実行される情報処理プログラムは、不図示のCD-ROM(Compact Disk-Read Only Memory)に格納されて流通してもよい。このCD-ROMに格納されたプログラムは、図示しないCD-ROM駆動装置によって読取られ、開発支援装置10のハードディスクなどへ格納される。あるいは、開発支援装置10は、上位のホストコンピュータなどから、ネットワークを通じて、前記DVD-ROMに格納されたプログラムと同様のプログラムをダウンロードするように構成してもよい。
図2に示すように、HMI(Human Machine Interface)30が、通信ケーブルを介して、PLC20に接続されてもよい。HMI30は、人間と機械とが情報をやり取りするための手段であり、具体的には、人間が機械を操作したり(機械に指示を与えたり)、機械が現在の状態・結果を人間に知らせたりする手段である。HMI30について、人間が機械に指示を与える手段としてはスイッチ、ボタン、ハンドル、ダイヤル、ペダル、リモコン、マイク、キーボード、マウスなどが含まれる。また、HMI30について、機械が現在の状態・結果等に係る情報を人間に伝える手段としては液晶画面、メーター、ランプ、スピーカーなどが含まれる。
HMI30は、表示部と、操作部と、PLC20と通信する通信部と、各部を制御する制御部と、を備える。HMI30は、操作部へのユーザ操作に応じて、制御システム1(例えば、PLC20)の各種の設定を変更することができる。また、HMI30の表示部は、制御システム1についての所定の情報を表示する。
開発支援装置10の提供する開発環境を利用してユーザが作成・編集するプログラムは、ユーザプログラム、モーション演算プログラム、およびシーケンス命令演算プログラム等を含む。「ユーザプログラム」は、ユーザの制御対象(例えば、対象のラインおよびプロセス)に応じて作成される。開発支援装置10は、ラダーロジック(ラダー言語)によって記述されたラダープログラムなど(ソースプログラム)をコンパイルすることにより、ユーザプログラムを生成する。ラダーロジックは、論理回路を記述するための手法で、多くのPLCで採用されているプログラム言語である。ユーザプログラムは、例えば、PLC20に含まれるマイクロプロセッサで実行可能なオブジェクトプログラム形式で生成される。「モーション演算プログラム」は、ユーザプログラムによる指示に従って実行され、サーボモータドライバおよびパルスモータドライバなどのモータドライバに対して出力する指令値を実行されるごとに算出するプログラムである。「シーケンス命令演算プログラム」は、ユーザプログラムで使用される所定のシーケンス命令が実行されるときに呼び出され、該命令の内容を実現するために実行されるプログラムである。
(用語の説明)
ユーザプログラムなどのプログラムは、複数の機能上の構成要素であるプログラム要素PEによって構成される。すなわち、ユーザは、開発支援装置10の提供する開発環境(プログラミングツール)において、複数のプログラム要素PEを組み合わせることによって、プログラムを構成する。
プログラム要素PEは、「プログラムを構成する機能上の構成要素(機能単位、構成単位)」であり、「プログラム実行モデル単位」と言い換えることもできるし、「再利用可能なソフトウェア単位」と言い換えることもできる。プログラム要素PEは、「プログラム構成単位」と捉えることができ、また、「プログラム管理上の最小単位」と捉えることができる。
プログラム要素PEは、例えば、IEC61131-3(JIS B 3503)において定義されているPOU(Program Organization Unit)である。IEC61131-3では、機能単位でプログラムを作成し、この機能単位のことを、「POU」と呼ぶ。POUは、「複数の命令語から構成されるプログラム管理上の最小単位」と捉えることができ、ユーザプログラムを構成する構成要素の総称である。
ユーザプログラムを構成する構成要素としては、プログラム、ファンクション、ファンクションブロックが挙げられる。つまり、POUの種類は、プログラム、ファンクション、ファンクションブロックの3種類であり、POUは、これらの総称である。
プログラム(Program)は、「PRG」と略記されることがあり、ファンクション、ファンクションブロックなどを使用したアルゴリズムをいう。
ファンクションブロック(Function Block)は、「FB」と略記されることがあり、内部の変数などを保持する必要がある処理のかたまりをいう。ライブラリの多くは、ファンクションブロックである。
ファンクション(Function)は、「FUN」と略記されることがあり、四則演算、型変換などに使用する、内部状態を持たない命令をいう。
ファンクションブロックとファンクションとの違いについて、ファンクションブロックは同じ型の別インスタンスを生成できるが、ファンクションはロジックのみでインスタンス生成できない。また、ファンクションは、入力が同じであれば、演算結果は常に同じになり、この点が、ファンクションブロックとの違いである。
(ファンクションブロックについての留意事項)
ファンクションブロックは、予め作成しておいた「FB定義」と、それを実際にプログラム上で使用するための「インスタンス」とから成る。すなわち、ファンクションブロックを使用するためには、先ずFB定義を作成し、次に、FB定義を、インスタンスとしてプログラムに配置する必要がある。
ファンクションブロックは、FB定義を作成し、作成したFB定義をインスタンスとして別のPOU(例えば、プログラムなど)に配置することによって、実際に動作できるようになる。具体的には、ファンクションブロックは、FB定義が作成され、作成されたFB定義に対応するインスタンス変数が変数テーブルに作成(登録)された後、登録されたインスタンス変数がプログラム内で呼び出されることによって、実際に動作できるようになる。
開発支援装置10は、プログラム内のインスタンス変数を呼び出すべき箇所にユーザがインスタンス名を記述すると、その記述に同期して、変数テーブルにインスタンス変数(インスタンス名)を自動で作成(登録)してもよい。このような開発支援装置10の処理によって、ユーザは、FB定義を作成し、作成したFB定義に対応するインスタンス名を別のPOU(例えば、プログラムなど)に記述する(呼び出す)だけで、ファンクションブロックを実際に動作させることができる。言い換えれば、FB定義が、「プログラム、および、そのファンクションブロックとは別のファンクションブロックの少なくとも一方」から呼び出されることによって、ファンクションブロックは、インスタンスとして実際に配置されてもよい。1つのFB定義を、複数のプログラムで呼び出したり、別のファンクションブロックで呼び出したりすることによって、インスタンスとして配置することができる。
FB定義は、「プログラム、および、そのファンクションブロックとは別のファンクションブロックの少なくとも一方」に配置した時点で、インスタンスとして、個別に扱われるようになる。つまり、FB定義は、インスタンスとして配置されることにより、そのFB定義が配置されたプログラム、および、そのFB定義が配置されたファンクションブロックで、実際に動作できるようになる。
FB定義を作成した際にFB定義に付与した名称を、「FB定義名」または「命令名」と呼ぶ。
これに対して、ファンクションブロックを管理するために、プログラムごとに配置したファンクションブロック(FB定義)に対して個別に付与する名称を、「インスタンス名」または「インスタンス変数」と呼ぶ。つまり、或るファンクションブロックを、別のPOU(例えば、プログラム、および、その或るファンクションブロックとは別のファンクションブロックなど)から呼び出す際に、その或るファンクションブロックに設定するのが、「インスタンス名」である。
別のPOUに配置したファンクションブロック(FB定義)に「インスタンス名」を付与し、個別に内部変数を保持できる状態になったファンクションブロックを「ファンクションブロックのインスタンス」と呼ぶ。前述の通り、インスタンス化されたファンクションブロックは、自動的にローカル変数に登録されてもよい。また、ユーザが、FB定義に対応するインスタンス変数(インスタンス名)を、手動で、変数テーブルに作成(登録)してもよい。別のPOUからファンクションブロックを呼び出す際には、インスタンス名を指定する。
(プログラム例について)
図4は、開発支援装置10の提供する開発環境を用いてユーザが作成したプログラム(ユーザプログラム)の一例を示す図であり、ユーザがラダー(Ladder)プログラムを作成した例を示す図である。図4に例示する画像は、例えば、開発支援装置10が表示する。
図4に例示する「Program1」というプログラム(POU)は、以下の3つのPOUを呼び出している。すなわち、図4に例示する「Program1」というPOUは、「Function1」というファンクション(POU)を呼び出している。また、「Program1」というPOUは、「Function2」というファンクション(POU)を呼び出している。さらに、「Program1」というPOUは、『インスタンス名(インスタンス変数名)が「fb1」で、FB定義の名称(または命令名)が「FunctionBlock0」であるファンクションブロック(POU)』を呼び出している。
『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』を、『「FunctionBlock0」というPOU』と略記する場合、図4の「Program1」というPOUは、以下の4つのPOUによって構成されている。すなわち、「Program1」というPOUは、自信である「Program1」というPOUに加えて、「Function1」、「Function2」、および、「FunctionBlock0」という、計4つのPOUによって構成されている。
図5は、開発支援装置10の提供する開発環境を用いてユーザが作成したプログラム(ユーザプログラム)の一例を示す図であり、ユーザがストラクチャードテキスト(Structured Text)プログラムを作成した例を示す図である。図5に例示する画像は、例えば、開発支援装置10が表示する。
図5に例示する「Program1」というプログラム(POU)は、以下の3つのPOUを呼び出している。すなわち、図5に例示する「Program1」というPOUは、「Function1」というファンクション(POU)を呼び出している。また、「Program1」というPOUは、「Function2」というファンクション(POU)を呼び出している。さらに、「Program1」というPOUは、『インスタンス名(インスタンス変数名)が「fb1」で、FB定義の名称(または命令名)が「FunctionBlock0」であるファンクションブロック(POU)』を呼び出している。
『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』を、『「FunctionBlock0」というPOU』と略記する場合、図5の「Program1」というPOUは、以下の4つのPOUによって構成されている。すなわち、「Program1」というPOUは、自信である「Program1」というPOUに加えて、「Function1」、「Function2」、および、「FunctionBlock0」という、計4つのPOUによって構成されている。
図4に例示する「Program1」というPOUと、図5に例示する「Program1」というPOUとは、表現形式が異なるが、同じ内容(同じ処理内容)のプログラムである。開発支援装置10は、ユーザに、ラダーロジック(ラダー言語)によってプログラミングする開発環境を提供してもよいし、ストラクチャードテキストでプログラミングする開発環境を提供してもよい。また、開発支援装置10は、ユーザに、SFC言語でプログラミングする開発環境を提供してもよい。開発支援装置10がユーザに提供する開発環境において、プログラムは、ラダー言語、SFC言語、ストラクチャードテキスト等の複数の言語が混在していてもよい。
(その他、一般的留意事項)
本実施形態では、原則として、プログラム要素PEがPOUである例について、開発支援装置10が実行する処理等について説明する。ただし、プログラム要素PEがPOUであることは、開発支援装置10にとって必須ではない。
また、以下の説明においては、複数のPOUの各々を区別する必要がある場合には、「n」を「1以上の整数」として、符号に「(1)」、「(2)」、「(3)」、・・・、「(n)」等の添え字を付して区別する。例えば、「POU(1)」、「POU(2)」、「POU(3)」、・・・、「POU(n)」と記載して区別する。複数のPOUの各々を特に区別する必要がない場合は単に「POU」と称する。
(開発支援装置がユーザに提供する利便性についての説明)
或るプロジェクト(例えば、PJ1)で作成した或るプログラム(例えば、PRG1)について、PRG1を構成するPOUの一つであるPOU(x)を、以下のように利用(再利用)したいという状況が発生し得る。すなわち、POU(x)を、別のプロジェクト(例えば、PJ2)のためのプログラム(例えば、PRG2)でも利用したいという状況が発生し得る。つまり、PRG1を構成するPOU(x)を、PRG2において再利用したいという状況が発生し得る。
この場合、PRG1において、POU(x)が別のPOU(y)を呼び出している時には、PRG2でPOU(x)を利用(再利用)するには、以下の点に注意する必要がある。すなわち、POU(y)も、POU(x)と一緒に、PRG2にペーストしなければならない点に注意する必要がある。つまり、PRG1を構成するPOU(x)をPRG2で再利用するには、PRG1においてPOU(x)によって呼び出されているPOU(y)も、POU(x)と一緒にコピー&ペーストする必要がある。
そこで従来、ユーザは、POU(x)とPOU(y)との両方を、手作業でコピーの対象として選択し、コピーしたPOU(x)とPOU(y)とを、プログラムPRG2にペーストしていた。
しかしながら、「コピーしたいPOUによって呼び出されている、別のPOU」の調査は、ユーザにとって手間である。特に、コピーしたいPOUの個数が多い場合、それらのPOUの各々について、「コピーしたいPOUによって呼び出されている、別のPOU」を調査するのは、非常に手間である。また、コピーしたいPOUが1つでも、そのPOUによって呼び出されている別のPOUの個数が多い場合、「コピーしたいPOUによって呼び出されている、別のPOU」を全て調べ上げるのは、非常に手間である。
その上、ユーザによる『「POUによって呼び出されている、別のPOU」の調査』には誤りが発生する可能性がある。つまり、「POUによって呼び出されている、別のPOU」を調査する段階で、ユーザによる誤りが発生し得る。
また、ユーザが調査を正確に行えたとしても、コピーの対象を選択する際に、調査した「POUによって呼び出されている、別のPOU」とは異なるPOUを、ユーザが選択してしまう可能性もある。つまり、「POUによって呼び出されている、別のPOU」をコピーの対象として選択する段階で、ユーザによる誤りが発生し得る。
そこで、開発支援装置10は、或るプログラムを構成する或るPOUをコピーの対象として選択するユーザ操作があると、その或るプログラムにおいてその或るPOUが呼び出している別のPOUを、コピーの対象に追加する。
例えば、PRG1において或るPOU(x)が別のPOU(y)を呼び出している場合に、PRG1におけるPOU(x)をコピーの対象として選択するユーザ操作があると、開発支援装置10は、以下の処理を実行する。すなわち、開発支援装置10は、POU(x)に加えて、POU(y)も、コピーの対象に含める。
そのため、ユーザは、コピーしたいPOU(例、POU(x))が呼出している、別のPOU(例、POU(y))を調査する必要がない。つまり、開発支援装置10は、「コピーしたいPOUが呼び出している、別のPOU」の調査という手間を、ユーザから省いてくれる。
その上、開発支援装置10は、プログラムに基づいて、「コピーしたいPOUが呼び出している、別のPOU」を調査し、コピーの対象を選択する。したがって、開発支援装置10は、上述の調査段階および選択段階でのユーザによる誤りも防ぐことができる。
ここで、或るプログラム(或るプログラムのプログラムコード)を解析して、その或るプログラムを構成する複数のPOUの間の呼出-被呼出関係を特定するには、或る程度の時間を要する。以下では、「呼出-被呼出関係」を「呼出関係」と略記することがある。
そこで、開発支援装置10は、その或るプログラム(その或るプログラムの内容。つまり、プログラムコード・アルゴリズム)を予め解析しておき、その或るプログラムを構成する複数のPOUの間の呼出関係を特定しておくことが望ましい。
開発支援装置10は、呼出関係を予め特定しておくことで、予め特定しておかない場合と比べて、ユーザによってコピーの対象とするPOUが選択されてから、コピーの対象とすべきPOUを調査、選択するまでに要する時間を短縮することができる。例えば、開発支援装置10は、ユーザによってコピーの対象とするPOUが選択されると、予め特定しておいた呼出関係を参照して、コピーの対象とされたPOUによって呼び出されている別のPOUを即座に把握することができる。そのため、開発支援装置10は、コピーの対象とすべきPOUを調査、選択する処理の完了を、ユーザに待たせることがない。
開発支援装置10(特に、後述する解析部160)は、例えば、以下のタイミングで、プログラム(プログラムのプログラムコード・アルゴリズム)を解析して、そのプログラムを構成する複数のPOUの間の呼出関係を特定する。すなわち、開発支援装置10は、プログラムがユーザによって作成されたタイミング、作成されたプログラムがユーザによって変更、編集されたタイミングで、プログラム(プログラムのプログラムコード等)を解析し、POUの間の呼出関係を特定する。一例を挙げれば、開発支援装置10は、ユーザによる編集作業が完了したタイミングで、編集後のプログラム(編集後のプログラムのプログラムコード等)を解析し、編集後のプログラムを構成する複数のPOUの間の呼出関係を特定する。
以下、図3を参照して、ユーザがPOUをコピー&ペーストしようとする際に、開発支援装置10が実行する処理の概要を説明する。
図3は、ユーザがPOUをコピー&ペーストしようとする際に、開発支援装置10が表示する画像の一例を示す図である。図3に例示する画像は、例えば、開発支援装置10が表示する。
図3の左上の画像は、開発支援装置10が管理している、或るプロジェクト(例えば、「new_Controller_0」)におけるPOUについて、ユーザが「複数選択コピー」というユーザ操作を行ったことを示している。
「複数選択コピー」というユーザ操作を受け付けた開発支援装置10は、図3の右上に示すように、ユーザに、コピーの対象とするPOUを選択させ、また、コピーの方式を選択させる。図3の右上の画像において、点線で囲んでいるように、ユーザは、コピーの対象として、「Program0」というプログラム(POU)を選択している。また、図3の右上の画像において、一点鎖線で囲んでいるように、ユーザは、コピーの方式として、「(参照先の)POU、グローバル変数、データ型を含める」を選択している。ここでいう「参照先」とは、「呼出先」を意味している。つまり、ユーザは、『「選択したPOU」に加えて、「選択したPOUによって呼び出されている、別のPOU、グローバル変数、および、データ型」をもコピーの対象とする』というコピーの方式を選択している。
開発支援装置10は、図3の右上に示すように、開発支援装置10が管理している複数のPOUの間の呼出-被呼出関係を示す情報を、具体的には、呼出関係データ132(詳細は後述する)を、表示してもよい。開発支援装置10は、ユーザに、コピーの対象とするPOUを選択させる前のタイミングで、または、コピーの対象とするPOUを選択させた後のタイミングで、呼出関係データ132を表示してもよい。図3の右上において二点鎖線で示すように、コピーの対象とするPOUがユーザによって選択されると、開発支援装置10は、呼出関係データ132において、選択されたPOUに係る呼出関係を強調して表示してもよい。
図3の右上に例示する呼出関係データ132において、「Program0」というプログラム(POU)を構成する、「Program0」、「Function0」、「Function1」、および、「Function3」という4つのPOUについて、以下の呼出関係が示されている。すなわち、「Program0」というPOUを呼出元(参照元)とし、「Function0」というPOUと、「Function1」というPOUとを呼出先(参照先)とする、呼出関係が示されている。また、「Function0」というPOUを呼出元とし、「Function3」というPOUを呼出先とする、呼出関係が示されている。
以下では、或るPOUが別のPOUを呼び出している場合に、その「或るPOU」を「呼出元POU」と称し、『その「或るPOU」によって呼び出されている別のPOU』を「呼出先POU」と称することがある。
また、図3の右上に例示する呼出関係データ132において、「Program1」というプログラムを構成する、「Program1」、「Function1」、「Function2」、および、「FunctionBlock0」という4つのPOUについて、以下の呼出関係が示されている。すなわち、「Program1」というPOUを呼出元とし、「Function1」というPOUと、「Function2」というPOUと、「FunctionBlock0」というPOUとを呼出先とする、呼出関係が示されている。
図3の右上に例示するように、呼出関係データ132において、プログラムを構成する複数のPOUの間の呼出関係は、例えば、プログラムごとに整理されている。言い換えれば、複数のPOUの間の呼出関係は、それらのPOUによって構成されるプログラムに対応付けられている。
図3の右上に示す画像において、ユーザによって、「コピーの対象とするPOU」および「コピーの方式」が選択された後に、「コピーの実行」を指示するユーザ操作(例えば、「コピー」ボタンの押下)があると、開発支援装置10は、以下の処理を実行する。すなわち、開発支援装置10は、コピー対象一覧133を生成する。
図3の右下に示すクリップボードは、「Program0」というPOUがコピーの対象としてユーザに選択された場合に開発支援装置10が生成するコピー対象一覧133の一例である。開発支援装置10(特に、後述する第一追加部120および第二追加部140)は、「コピーの対象とするPOU」と、呼出関係データ132とから、コピー対象一覧133を生成する。例えば、開発支援装置10は、「Program0」というPOUがコピーの対象としてユーザに選択されると、以下のようにしてコピー対象一覧133を生成する。
すなわち、先ず、開発支援装置10は、コピーの対象として選択された「Program0」というPOUを、コピー対象一覧133に格納する(第一追加処理)。次に、開発支援装置10は、呼出関係データ132を参照して、「Program0」というPOUによって、「Function0」というPOUと、「Function1」というPOUとが呼び出されていることを確認する。この確認結果から、開発支援装置10は、「Function0」というPOUと、「Function1」というPOUとを、コピー対象一覧133に格納する(第二追加処理)。さらに、開発支援装置10は、呼出関係データ132を参照して、「Function0」というPOUによって、「Function3」というPOUが呼び出されていることを確認する。この確認結果から、開発支援装置10は、「Function3」というPOUを、コピー対象一覧133に格納する(第二追加処理)。
したがって、図3の右下に例示するように、「Program0」というPOUがコピーの対象としてユーザに選択されると、開発支援装置10は、以下の4つのPOUが格納されたコピー対象一覧133(クリップボード)を生成する。すなわち、開発支援装置10は、「Program0」、「Function0」、「Function1」、および、「Function3」という4つのPOUが格納されたコピー対象一覧133を生成する。
コピー対象一覧133の生成が完了している状態で、コピーの対象として選択したPOUを所望の位置へとペーストするユーザ操作があると、開発支援装置10は、コピー対象一覧133に格納されているPOUを全て、その所望の位置へとペーストする。例えば、ペースト方法として「複数選択コピーされた項目を貼り付け」を選択するユーザ操作があると、開発支援装置10は、図3の右下に例示するクリップボードに含まれるPOUを全て、ユーザの指定する場所へとペーストする。
図3に示す例において、別のプロジェクト(例えば、「new_Controller_2」)を貼り付け先とし、ペースト方法として「複数選択コピーされた項目を貼り付け」を選択するユーザ操作があると、開発支援装置10は、以下の処理を実行する。すなわち、開発支援装置10は、図3の左下に示すように、「Program0」、「Function0」、「Function1」、および、「Function3」という4つのPOUを、別のプロジェクトへとペーストする。
§2.構成例
これまで、図2を用いて、制御システム1の概要を説明してきた。次に、開発支援装置10について、その詳細を説明する。図1等を用いて以下に詳細を説明する開発支援装置10について、最初に概要を整理しておけば、以下の通りである。
すなわち、開発支援装置10は、PLC20(制御装置)で実行されるプログラムをユーザが作成するのを支援する開発支援装置である。開発支援装置10は、第一追加部120と、第二追加部140と、ペースト部150とを備える。
第一追加部120は、ユーザによって、プログラムを構成する複数の機能上の構成要素であるプログラム要素PE(例えば、POU)の中から、コピーの対象とするPOUが選択されると、選択されたPOUをコピー対象一覧133に含める。
第二追加部140は、第二追加処理(追加処理)を、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、繰り返し実行する。
第二追加処理は、「プログラムにおいて、コピー対象一覧133に含まれているPOUによって呼び出されている、コピー対象一覧133に含まれていないPOU」を、コピー対象一覧133に含める処理である。例えば、「Program0」というプログラムにおいて、コピー対象一覧133に格納されている「Function0」というPOUによって、「Function3」というPOUが呼び出されていると、第二追加部140は、第二追加処理として、以下の処理を実行する。すなわち、第二追加部140は、『「Function3」というPOUが、未だ、コピー対象一覧133に含まれていない(格納されていない)』ことを確認すると、「Function3」というPOUを、コピー対象一覧133に含める(格納する)。
ペースト部150は、「コピーの対象として選択したPOUを、所望の位置へとペーストする」ユーザ操作があると、コピー対象一覧133に含まれているPOUの全てを、その所望の位置へとペーストする。
前記の構成によれば、開発支援装置10は、ユーザによってコピーの対象とするPOUが選択されると、先ず、選択されたPOUをコピー対象一覧133に含める。次に、開発支援装置10は、「『コピー対象一覧133に含まれているPOU』によって呼び出されている、『コピー対象一覧133に含まれていないPOU』を、コピー対象一覧133に含める」第二追加処理を、以下の条件が満たされるまで、繰り返し実行する。すなわち、開発支援装置10は、第二追加処理を、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、繰り返し実行する。そして、コピーの対象として選択したPOUを所望の位置へとペーストするユーザ操作があると、開発支援装置10は、コピー対象一覧133に含まれているPOUの全てを、その所望の位置へとペーストする。
ここで、或るプロジェクト(例えば、PJ1)で作成した或るプログラム(例えば、PRG1)について、PRG1を構成するPOUの一つであるPOU(x)を、以下のように利用(再利用)したいという状況が発生し得る。すなわち、POU(x)を、別のプロジェクト(例えば、PJ2)のためのプログラム(例えば、PRG2)でも利用したいという状況が発生し得る。つまり、PRG1を構成するPOU(x)を、PRG2において再利用したいという状況が発生し得る。
この場合、PRG1において、POU(x)が別のPOU(y)を呼び出している時には、PRG2でPOU(x)を利用(再利用)するには、以下の点に注意する必要がある。すなわち、POU(y)も、POU(x)と一緒に、PRG2にペーストしなければならない点に注意する必要がある。つまり、PRG1を構成するPOU(x)をPRG2で再利用するには、PRG1においてPOU(x)によって呼び出されているPOU(y)も、POU(x)と一緒にコピー&ペーストする必要がある。
そこで従来、ユーザは、POU(x)とPOU(y)との両方を、手作業でコピーの対象として選択し、コピーしたPOU(x)とPOU(y)とを、プログラムPRG2にペーストしていた。
しかしながら、「コピーしたいPOUによって呼び出されている、別のPOU」の調査は、ユーザにとって手間である。特に、コピーしたいPOUの個数が多い場合、それらのPOUの各々について、「コピーしたいPOUによって呼び出されている、別のPOU」を調査するのは、非常に手間である。また、コピーしたいPOUが1つでも、そのPOUによって呼び出されている別のPOUの個数が多い場合、「コピーしたいPOUによって呼び出されている、別のPOU」を全て調べ上げるのは、非常に手間である。
その上、ユーザによる『「POUによって呼び出されている、別のPOU」の調査』には誤りが発生する可能性がある。つまり、「POUによって呼び出されている、別のPOU」を調査する段階で、ユーザによる誤りが発生し得る。
また、ユーザが調査を正確に行えたとしても、コピーの対象を選択する際に、調査した「POUによって呼び出されている、別のPOU」とは異なるPOUを、ユーザが選択してしまう可能性もある。つまり、「POUによって呼び出されている、別のPOU」をコピーの対象として選択する段階で、ユーザによる誤りが発生し得る。
これに対して、開発支援装置10は、POU(x)がユーザによって「コピーの対象とするPOU」として選択されると、先ず、POU(x)を、コピー対象一覧133に含める。
さらに、開発支援装置10は、「『コピー対象一覧133に含まれているPOU』によって呼び出されている、『コピー対象一覧133に含まれていないPOU』を、コピー対象一覧133に含める」処理である第二追加処理を実行する。例えば、開発支援装置10は、「コピー対象一覧133に含まれているPOU(x)」がプログラムPRG1において呼び出しているPOU(y)を、コピー対象一覧133に含める。
開発支援装置10は、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、第二追加処理を繰り返し実行する。そして、開発支援装置10は、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなったことを確認すると、第二追加処理を終了する。例えば、プログラムPRG1において、POU(x)によって呼び出されているのがPOU(y)のみであり、POU(y)は別のPOUを呼び出していない場合、開発支援装置10は、以下の時点で第二追加処理を終了する。すなわち、開発支援装置10は、コピー対象一覧133に、POU(x)とPOU(y)とが含まれている(格納されている)ことを確認すると、第二追加処理を終了する。
つまり、開発支援装置10は、POU(x)がコピー対象として選択されると、POU(x)と共に、プログラムPRG1においてPOU(x)によって呼び出されているPOU(y)を、コピーの対象とする。
そのため、開発支援装置10は、「プログラムにおいて、或るPOUによって呼び出されている、別のPOU」の調査および選択の負担をユーザに課すことなく、当該別のPOUを、当該或るPOUと共に、コピーの対象とすることができる。
また、開発支援装置10は、プログラムに基づいて、「或るPOUによって呼び出されている、別のPOU」を調査、選択するから、「或るPOUによって呼び出されている、別のPOU」の調査および選択について、誤りを発生させるおそれがない。
さらに、開発支援装置10は、第二追加処理を、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、繰り返し実行する。そのため、開発支援装置10は、或るPOUを再利用するのに必要な、全てのPOUを、コピーの対象とすることができる。
したがって、開発支援装置10は、プログラムを構成する複数のPOUを、ユーザがより効率的に利用することを可能とするとの効果を奏する。
開発支援装置10は、ユーザによってコピーの対象とするPOUが選択される前に、予めプログラム(プログラムの内容・アルゴリズム)を解析して、プログラムにおける複数のPOUの間の呼出関係を特定しておく解析部160を備える。
前記の構成によれば、開発支援装置10は、ユーザによってコピーの対象とするPOUが選択される前に、予めプログラムを解析して、プログラムを構成する複数のPOUの間の呼出関係を特定しておき、つまり、呼出関係データ132を予め生成しておく。
そして、開発支援装置10は、ユーザによってコピーの対象とするPOUが選択されると、選択されたPOUをコピー対象一覧133に含めた上で、予め特定しておいた呼出関係を利用して、第二追加処理を実行する。特に、開発支援装置10は、呼出関係を利用して、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、繰り返し第二追加処理を実行する。
ここで、第二追加処理を実行するためには、プログラム(プログラムの内容・アルゴリズム)を解析して、プログラムを構成する複数のPOUの間の呼出関係を特定する必要がある。そして、プログラムを解析して、プログラムを構成する複数のPOUの間の呼出関係を特定するには、或る程度の時間を要する。
そのため、開発支援装置10は、呼出関係を予め特定しておかない場合と比べて、ユーザによってコピーの対象とするPOUが選択されてから、第二追加処理を終了するまでに要する時間を短縮することができる。
したがって、開発支援装置10は、POUをコピー&ペーストするユーザ操作に対応する処理を高速化することができ、POUを再利用しようとする際にユーザが感じる操作性を向上させることができるとの効果を奏する。
開発支援装置10は、プログラムを構成する複数のPOUの間の呼出関係を示す情報(具体的には、呼出関係データ132)を、表示装置(具体的には、自装置の表示画面、または、外部の表示装置)に表示させる表示制御部170を備える。
前記の構成によれば、開発支援装置10は、プログラムを構成する複数のPOUの間の呼出関係を示す情報を、表示装置に表示させ、例えば、自装置の表示画面に表示し、また、外部の表示装置に表示させる。
開発支援装置10(具体的には、表示制御部170)は、複数のPOUの間の呼出関係を示す情報を表示する際に、ファンクションブロックについては、その命令名によって、そのファンクションブロックを特定することができるように表示してもよい。
したがって、開発支援装置10は、プログラムを構成する複数のPOUの間の呼出関係を示す情報を、ユーザに確認させることができるとの効果を奏する。
前述の通り、開発支援装置10において、プログラムを構成する複数のプログラム要素PEは、例えば、IEC 61131-3において定義されているPOUである。したがって、開発支援装置10は、POUをユーザがより効率的に利用することを可能とするとの効果を奏する。
これまでに概要を説明した開発支援装置10について、次に、その構成の詳細について図1を参照しながら説明していく。
(開発支援装置の詳細構成)
図1は、開発支援装置10の要部構成を示すブロック図である。図1に示すように、開発支援装置10は、機能ブロックとして、受付部110、第一追加部120、記憶部130、第二追加部140、ペースト部150、解析部160、および、表示制御部170を備えている。
開発支援装置10は、上述の各機能ブロックに加え、ユーザが制御目的に応じてPLC20に実行させる制御プログラムとしてのユーザプログラムをプログラミングするための環境を提供する、不図示のプログラミング支援部などを備えていてもよい。しかしながら、記載の簡潔性を担保するため、本実施の形態に直接関係のない構成は、説明およびブロック図から省略している。ただし、実施の実情に則して、開発支援装置10は、当該省略された構成を備えてもよい。
受付部110、第一追加部120、第二追加部140、ペースト部150、解析部160、および、表示制御部170は、例えば、CPU(central processing unit)等が、ROM(read only memory)、NVRAM(non-Volatile random access memory)等で実現された記憶装置(記憶部130)に記憶されているプログラムを不図示のRAM(random access memory)等に読み出して実行することで実現できる。以下に先ず、受付部110、第一追加部120、第二追加部140、ペースト部150、解析部160、および、表示制御部170の各々について、その詳細を説明する。
(記憶部以外の機能ブロックの詳細)
受付部110は、ユーザ操作を受け付けて、受け付けたユーザ操作の内容に応じて、第一追加部120、ペースト部150、または、表示制御部170に、受け付けたユーザ操作の内容に対応する情報を出力する。
受付部110は、コピーの対象とするPOUを選択するユーザ操作を受け付けると、その旨を第一追加部120に通知し、例えば、コピーの対象として選択されたPOUを第一追加部120に通知する。
受付部110は、「或るプログラムを構成するPOU」をコピーの対象として選択するユーザ操作があると、第一追加部120に、選択されたPOUと共に、選択されたPOUによって構成されたプログラム(前述の「或るプログラム」)を、通知してもよい。言い換えれば、受付部110は、コピーの対象として選択されたPOUに加えて、「コピーの対象として選択されたPOUは、どのプログラムを構成するPOUであるのか」を、第一追加部120に通知してもよい。
例えば、「Program0」というプログラムを構成する、「Function1」というPOUをコピーの対象として選択するユーザ操作があると、受付部110は、以下の2つの情報を、第一追加部120に通知してもよい。すなわち、受付部110は、『コピーの対象として選択されたのは「Program0」というプログラムを構成するPOUである』ことと、『コピーの対象として選択されたのは、「Function1」というPOUである』こととを、第一追加部120に通知してもよい。言い換えれば、受付部110は、第一追加部120に、「コピーの対象として選択されたPOU」に加えて、「どのプログラムにおけるPOUが、コピーの対象として選択されたか」を、通知してもよい。
受付部110は、第一追加部120に通知した情報と同様の情報を、第二追加部140に通知してもよい。
受付部110は、プログラムを構成する複数のPOUの間の呼出関係を示す情報である呼出関係データ132の表示を指示するユーザ操作を受け付けると、その旨を表示制御部170に通知する。
特に、受付部110は、呼出関係データ132の表示を指示するユーザ操作と共に、「インスタンス名を表示するモード」を選択するユーザ操作を受け付けると、「インスタンス名を表示するモード」が選択されたことを、表示制御部170に通知する。
また、受付部110は、呼出関係データ132の表示を指示するユーザ操作と共に、「命令名を表示するモード」を選択するユーザ操作を受け付けると、「命令名を表示するモード」が選択されたことを、表示制御部170に通知する。
受付部110は、コピーの対象として選択したPOUをペーストするユーザ操作を受け付けると、その旨をペースト部150に通知する。
第一追加部120は、受付部110から、コピーの対象として選択されたPOUを通知されると、コピーの対象として選択されたPOUを、コピー対象一覧133に追加し、つまり、コピーの対象として選択されたPOUを、コピー対象一覧133に格納する。「コピーの対象として選択されたPOUを、コピー対象一覧133に格納する」処理を、以下では「第一追加処理」とも称する。
第一追加部120は、コピーの対象として選択されたPOUをコピー対象一覧133に格納すると、つまり、第一追加処理を完了すると、「第一追加処理を完了した」こと(以下、「格納完了」ともいう)を、第二追加部140に通知する。
第一追加部120は、格納完了と共に、以下の情報を第二追加部140に通知してもよい。すなわち、第一追加部120は、格納完了に加えて、「どのプログラムにおけるPOUが、コピーの対象として選択されたか」を、第二追加部140に通知してもよい。言い換えれば、第一追加部120は、格納完了に加えて、「コピーの対象として選択されたPOUは、どのプログラムを構成するPOUであるのか」を、第二追加部140に通知してもよい。
例えば、受付部110が、「Program0」というプログラムを構成する、「Function1」というPOUをコピーの対象として選択するユーザ操作を受け付けると、第一追加部120は、以下の処理を実行する。すなわち、第一追加部120は、「Function1」というPOUをコピー対象一覧133に格納し、格納が完了すると、「Function1」というPOUをコピー対象一覧133に格納したこと(「格納完了」)を、第二追加部140に通知する。さらに、第一追加部120は、『コピーの対象として選択されたのは、「Program0」というプログラムを構成するPOUである』ことを、第二追加部140に通知してもよい。
第二追加部140は、第一追加部120から、コピーの対象として選択されたPOUをコピー対象一覧133に格納したこと(つまり、格納完了)を通知されると、記憶部130のコピー対象一覧133を参照して、以下の処理を実行する。
すなわち、第二追加部140は、コピー対象一覧133に格納されている1つ以上のPOUから、1つのPOUを選択し、選択したPOUについて、記憶部130の呼出関係データ132を参照して、呼出先POUの有無を確認する(呼出先確認処理)。言い換えれば、第二追加部140は、呼出関係データ132を参照して、「選択したPOUを呼出元POUとして、その呼出元POUによって呼び出されている、別のPOU(呼出先POU)」がないかを確認する。
呼出先確認処理によって、「選択したPOUによって呼び出されている、別のPOU」があることを確認すると、つまり、選択したPOUを呼出元POUとする呼出先POUが1つ以上あることを確認すると、第二追加部140は、以下の第二追加処理を実行する。
すなわち、第二追加部140は、1つ以上の呼出先POUから呼出先POUを1つ選択し、選択した呼出先POUについて、「既にコピー対象一覧133に格納されているか」を確認する。そして、第二追加部140は、「選択した呼出先POUが、未だコピー対象一覧133に格納されていない」と判定すると、選択した呼出先POUを、コピー対象一覧133に格納する。
第二追加部140は、選択したPOUを呼出元POUとする、全ての呼出先POUについて、上述の第二追加処理を実行し、全ての呼出先POUに対する第二追加処理の実行を完了すると、コピー対象一覧133を再び参照する。そして、第二追加部140は、第二追加処理の実行完了後のコピー対象一覧133に格納されているPOUについて、「未選択のPOUがないか」、つまり、「呼出先確認処理を未だ実行していないPOUがないか」を確認する。
コピー対象一覧133に未だ選択していないPOUがあると、第二追加部140は、選択していない1つ以上のPOUから、1つのPOUを選択し、選択したPOUについて、呼出先確認処理を実行する。第二追加部140は、コピー対象一覧133に格納されている全てのPOUを選択すると、つまり、コピー対象一覧133に格納されている全てのPOUに対して呼出先確認処理を実行すると、処理を終了する。
第一追加部120から、格納完了に加えて、「どのプログラムにおけるPOUが、コピーの対象として選択されたか」を通知された第二追加部140は、呼出先確認処理の実行に際し、以下の処理を実行してもよい。すなわち、第二追加部140は、呼出関係データ132を参照して、コピーの対象として選択されたPOUによって構成されるプログラムについて、そのプログラムにおける呼出関係から、ユーザの選択したPOUによって呼び出されているPOUを確認してもよい。つまり、或るプログラムを構成するPOUをコピーの対象とするユーザ操作があると、第二追加部140は、呼出関係データ132を参照して、その或るプログラムの呼出関係を全て取得し、取得した呼出関係に従って、コピー対象一覧133を生成してもよい。
詳細は後述するが、呼出関係データ132は、例えば、プログラムごとに、そのプログラムを構成する複数のPOUの間の呼出関係を格納している。そこで、第二追加部140は、呼出関係データ132を参照して、「コピーの対象として選択されたPOUによって構成されるプログラム」に対応付けられた呼出関係から、ユーザの選択したPOUによって呼び出されている別のPOUを確認してもよい。
例えば、「Program0」というプログラムを構成する、「Function1」というPOUをコピーの対象として選択するユーザ操作があると、呼出先確認処理の実行に際し、第二追加部140は、以下の処理を実行してもよい。すなわち、第二追加部140は、呼出関係データ132を参照して、「Program0」というプログラムに対応付けられている全ての呼出関係から、コピー対象一覧133を生成してもよい。
具体的には、第二追加部140は、呼出関係データ132を参照して、「Program0」というプログラムに対応付けられている呼出関係から、「Function1」というPOUによって呼び出されている別のPOUを確認してもよい。つまり、或るプログラムを構成するPOUがユーザによってコピーの対象として選択されると、第二追加部140は、「その或るプログラムにおいて、選択されたPOUが呼び出している別のPOU」を、コピー対象一覧133に格納する。
ペースト部150は、受付部110から、コピーの対象として選択したPOUをペーストするユーザ操作があったことを通知されると、記憶部130を参照して、コピー対象一覧133に格納されているPOUを全て取得する。ペースト部150は、取得した全てのPOUを、「コピーの対象として選択したPOUをペーストする」ユーザ操作において指定されているペースト先へと、ペーストする。
解析部160は、記憶部130のプログラムテーブル131を参照して、プログラムテーブル131に格納されている1つ以上のプログラムの各々について、そのプログラム(内容・アルゴリズム)を解析して、呼出関係データ132を生成する。解析部160は、生成した呼出関係データ132を記憶部130に格納する。
例えば、解析部160は、プログラムごとに、プログラムの内容(アルゴリズム)を解析して、プログラムを構成する複数のPOUの間の呼出関係を把握してもよい。そして、解析部160は、把握した複数のPOUの間の呼出関係を、それらのPOUによって構成されるプログラムに対応付けて、呼出関係データ132として記憶部130に格納してもよい。
解析部160は、例えば、受付部110がコピーの対象とするPOUを選択するユーザ操作を受け付けるタイミングよりも前のタイミングで、プログラムの内容(アルゴリズム)を解析し、呼出関係データ132を生成しておく。解析部160による解析処理、言い換えれば、解析部160による呼出関係データ132の生成処理について、その詳細は図9および図10を用いて後述する。
表示制御部170は、受付部110から、呼出関係データ132の表示を指示するユーザ操作があったことを通知されると、記憶部130を参照して、呼出関係データ132を取得する。そして、表示制御部170は、取得した呼出関係データ132を、自装置の表示画面に表示し、または外部の表示装置に表示させる。
特に、表示制御部170は、受付部110から、「インスタンス名を表示するモード」が選択されたことを通知されると、ファンクションブロックを、そのファンクションブロックのインスタンス名によって表示する。
また、表示制御部170は、受付部110から、「命令名を表示するモード」が選択されたことを通知されると、ファンクションブロックを、そのファンクションブロックの命令名によって表示する。
(記憶部の詳細)
記憶部130は、開発支援装置10が使用する各種データを格納する記憶装置である。なお、記憶部130は、開発支援装置10が実行する(1)制御プログラム、(2)OSプログラム、(3)開発支援装置10が有する各種機能を実行するためのアプリケーションプログラム、および、(4)該アプリケーションプログラムを実行するときに読み出す各種データを非一時的に記憶してもよい。上記の(1)~(4)のデータは、例えば、ROM(read only memory)、フラッシュメモリ、EPROM(Erasable Programmable ROM)、EEPROM(登録商標)(Electrically EPROM)、HDD(Hard Disc Drive)等の不揮発性記憶装置に記憶される。開発支援装置10は、図示しない一時記憶部を備えていてもよい。一時記憶部は、開発支援装置10が実行する各種処理の過程で、演算に使用するデータおよび演算結果等を一時的に記憶するいわゆるワーキングメモリであり、RAM(Random Access Memory)等の揮発性記憶装置で構成される。どのデータをどの記憶装置に記憶するのかについては、PLC20の使用目的、利便性、コスト、または、物理的な制約等から適宜決定される。記憶部130はさらに、プログラムテーブル131、呼出関係データ132、および、コピー対象一覧133を格納している。
プログラムテーブル131には、開発支援装置10の提供する開発環境を用いてユーザが作成したプログラムが1つ以上格納されている。プログラムテーブル131に格納されているプログラムは、自身を含む複数のPOUによって構成されている。
呼出関係データ132は、プログラムテーブル131に格納されている1つ以上のプログラムについて、その各々を構成する複数のPOUの間の呼出関係を示す情報(データ)であり、解析部160によって生成される。呼出関係データ132において、プログラムを構成する複数のPOUの間の呼出関係は、例えば、プログラムごとに、格納されている。具体的には、呼出関係データ132において、プログラムを構成する複数のPOUの間の呼出関係は、それらのPOUによって構成されるプログラムに対応付けられて、格納されている。
コピー対象一覧133には、コピーの対象として選択されたPOUに加えて、コピーの対象として選択されたPOUと共にコピーの対象とすべきPOUが全て格納されている。例えば、コピー対象一覧133は、コピーの対象とするPOUを選択するユーザ操作があると、その都度、第一追加部120によって生成される。
(複数のPOUの間の呼出-被呼出関係について)
図6は、或るプログラムにおける、複数のPOUの間の呼出-被呼出関係を説明する図である。図6の上段および下段に例示する画像は、各々、例えば、開発支援装置10が表示する。
図6の上段に示す画像には、「Program0」というプログラム(POU)が、2つのPOUを呼び出していることが示されている。すなわち、図6の上段において、「Program0」というPOUによって、「Function0」というファンクション(POU)と、「Function1」というファンクション(POU)とが呼び出されている。
すなわち、図6の上段に示す画像には、「Program0」というPOUを呼出元(参照元)とし、「Function0」というPOUと、「Function1」というPOUとを呼出先(参照先)とする、呼出-被呼出関係が示されている。
図6の上段に示す画像に対して、「Function0」というPOUの詳細を確認するユーザ操作があると、開発支援装置10は、図6の下段に示す画像を表示する。
図6の下段に示す画像には、「Function0」というPOUが、「Function3」というファンクション(POU)を呼び出していることが示されている。
すなわち、図6の下段に示す画像には、「Function0」というPOUを呼出元(参照元)とし、「Function3」というPOUを呼出先(参照先)とする、呼出-被呼出関係が示されている。
図6に示すように、プログラムを構成する複数のPOUには、呼出-被呼出関係が設定されていることがある。そして、呼出元のPOUをコピーしてペースト先で再利用しようとする際には、呼出元のPOUと一緒に呼出先のPOUもコピーして、呼出元のPOUと呼出先のPOUとを一緒にペーストする必要がある。
図6に示す例において、例えば、「Program0」というPOUをコピーしてペースト先で再利用しようとする際には、「Program0」というPOUに加えて、少なくとも以下のPOUを全て、コピーの対象とする必要がある。
すなわち、「Program0」というPOUによって呼び出されている、「Function0」というPOUと、「Function1」というPOUとを、コピーの対象とする必要がある。
また、「Function0」というPOUをコピーしてペースト先で再利用しようとする際には、「Function0」というPOUによって呼び出されている、「Function3」というPOUを、コピーの対象とする必要がある。
したがって、「Program0」というPOUをコピーしてペースト先で再利用しようとする際には、「Program0」というPOUに加えて、少なくとも以下の3つのPOUを一緒にコピーして、「Program0」というPOUと一緒にペーストする必要がある。すなわち、少なくとも、「Function0」というPOU、「Function1」というPOU、および、「Function3」というPOUの3つのPOUを、「Program0」というPOUと一緒にコピー&ペーストする必要がある。
図7は、図6に示したのとは別のプログラム(具体的には、「Program1」というプログラム)における、複数のPOUの間の呼出-被呼出関係を説明する図である。図7の上段および下段に例示する画像は、各々、例えば、開発支援装置10が表示する。
図7の上段に示す画像には、「Program1」というプログラム(POU)が、3つのPOUを呼び出していることが示されている。すなわち、図7の上段において、「Program1」というPOUによって、「Function1」というファンクション(POU)と、「Function2」というファンクション(POU)とが呼び出されている。また、「Program1」というPOUによって、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるファンクションブロック(POU)』が呼び出されている。
言い換えれば、図7の上段に示す画像には、「Program1」というPOUを呼出元とし、以下の3つのPOUを呼出先とする、呼出関係が示されている。すなわち、「Function1」というPOUと、「Function2」というPOUと、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』とを呼出先とする、呼出関係が示されている。
図7の上段に示す画像に対して、「Function1」というPOUの詳細を確認するユーザ操作があると、開発支援装置10は、図7の下段に示す画像を表示する。
図7の下段に示す画像には、「Function1」というPOUが、別のPOUを呼び出していないことが示されている。
したがって、図7に示す例において、「Program1」というPOUをコピーしてペースト先で再利用しようとする際には、「Program1」というPOUに加えて以下の3つのPOUを一緒にコピー&ペーストする必要がある。すなわち、「Function1」というPOUと、「Function2」というPOUと、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』とを、「Program1」というPOUと一緒にコピー&ペーストする必要がある。
(呼出-被呼出関係の表示について)
図6および図7を用いて説明したように、ユーザは、プログラムを構成する複数のPOUについて、その間の呼出関係を段階的に調査していくことができる。例えば、図6に例示したように、ユーザは、先ず、「Program0」というPOUの内容を調査して(解析して)、「Program0」というPOUが、「Function0」というPOUと、「Function1」というPOUとを呼び出していることを確認する。次に、ユーザは、「Function0」というPOUの内容を調査して、「Function0」というPOUが、「Function3」というPOUを呼び出していることを確認する。
しかしながら、ユーザにとって、プログラムを構成する複数のPOUについて、その間の呼出関係を一つ一つ確認していくのは、手間である。
そこで、開発支援装置10は、プログラムを構成する複数のPOUについて、その間の呼出関係を示す情報を表示し、例えば、図8に例示する呼出関係データ132を表示する。ユーザは、開発支援装置10が表示する呼出関係データ132を確認することによって、自分で一つ一つ確認していかなくても、プログラムを構成する複数のPOUの間の呼出関係を把握することができる。
図8は、開発支援装置10が表示する、プログラムを構成する複数のPOUの間の呼出関係を示す情報である呼出関係データ132の一例を示す図である。呼出関係データ132は、例えば、受付部110がコピーの対象とするPOUを選択するユーザ操作を受け付けるタイミングよりも前のタイミングで、解析部160によって生成される。図8に例示する呼出関係データ132において、呼出-被呼出関係にある複数のPOUは、互いに直線で結ばれている。特に、図8に示す例では、複数のPOUの間の呼出-被呼出関係は、呼出元のPOUから呼出先のPOUへと延びる矢印線として、示されている。
図8に例示する呼出関係データ132は、図6に例示した「Program0」、および、図7に例示した「Program1」について、各々のプログラムを構成する複数のPOUの間の呼出関係を示している。
具体的には、図6を用いて説明したように、「Program0」というプログラムにおいて、「Program0」というプログラムを構成する、「Program0」、「Function0」、「Function1」、「Function3」という4つのPOUの間には、以下の呼出関係がある。
すなわち、「Program0」というPOUを呼出元とし、「Function0」というPOUと、「Function1」というPOUとを呼出先とする、呼出関係がある。
そこで、図8に示す例では、「Program0」というPOUから「Function0」というPOUへと矢印線が延び、また、「Program0」というPOUから「Function1」というPOUへと矢印線が延びている。
また、図6を用いて説明したように、「Program0」というプログラムにおいて、「Program0」というプログラムを構成する、「Function0」および「Function3」という2つのPOUの間には、以下の呼出関係がある。すなわち、「Function0」というPOUを呼出元とし、「Function3」というPOUを呼出先とする呼出関係がある。
そこで、図8に示す例では、「Function0」というPOUから「Function3」というPOUへと矢印線が延びている。
図7を用いて説明したように、「Program1」というプログラムにおいて、「Program1」というプログラムを構成するのは、以下の4つのPOUである。すなわち、「Program1」というプログラムを構成するのは、「Program1」、「Function1」、「Function2」という3つのPOUと、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』とである。そして、これら4つのPOUの間には、以下の呼出関係がある。すなわち、「Program1」というPOUを呼出元とし、「Function1」というPOUを呼出先とする、呼出関係がある。また、「Program1」というPOUを呼出元とし、「Function2」というPOUを呼出先とする、呼出関係がある。さらに、「Program1」というPOUを呼出元とし、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』を呼出先とする、呼出関係がある。
そこで、図8に示す例では、「Program1」というPOUから、「Function1」というPOUへと矢印線が延びている。また、「Program1」というPOUから、「Function2」というPOUへと矢印線が延びている。さらに、「Program1」というPOUから、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』へと矢印線が延びている。
(ファンクションブロックの表示方式について)
図8に示すように、プログラムを構成する複数のPOUの間の呼出関係を示す情報である呼出関係データ132において、ファンクションブロックは、基本的には、そのインスタンス名ではなく、その命令名(FB定義名)によって、識別される。例えば、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるファンクションブロック』は、呼出関係データ132において、基本的には、「fb1」としてではなく、「FunctionBlock0」として、識別される。
ただし、呼出関係データ132を表示する際、開発支援装置10は、ユーザの選択に応じて、ファンクションブロックについて、「インスタンス名を表示するモード」と「命令名を表示するモード」とを切り替えることができる。
「命令名を表示するモード」において、開発支援装置10は、例えば、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるファンクションブロック』を、図8に示すように「FunctionBlock0」と表示する。
「インスタンス名を表示するモード」において、開発支援装置10は、例えば、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるファンクションブロック』を、「fb1」と表示する。
(プログラムごとの呼出関係について)
図8に例示する呼出関係データ132において、プログラムを構成する複数のPOUの間の呼出関係は、プログラムごとに整理されており、つまり、プログラムに対応付けられている。
例えば、図8に例示する呼出関係データ132において、「Program0」、「Function0」、「Function1」、「Function3」という4つPOUの間の呼出関係は、「Program0」というプログラムに対応付けられている。
また、図8に例示する呼出関係データ132において、「Program1」、「Function1」、「Function2」、「FunctionBlock0」という4つPOUの間の呼出関係は、「Program1」というプログラムに対応付けられている。
(ツリー構造を用いた表示例について)
開発支援装置10は、図8に示すように、複数のPOUの間の呼出関係を示す情報を、つまり、呼出関係データ132を、「呼出元を親ノードとし、呼出先を子ノードとするツリー構造」を用いて、表現してもよい。ただし、呼出関係データ132の表示形式はこれに限られるものではなく、開発支援装置10は、任意の方式で(例えば、表形式で)、呼出関係データ132を表示する。
また、図3に例示したように、開発支援装置10(表示制御部170)は、ユーザによってコピーの対象として選択されたPOUを先祖ノードとするツリー構造として、選択されたPOUに係る呼出関係を強調表示してもよい。
§3.動作例
以下に、開発支援装置10が実行する各種の処理について説明していく。具体的には、解析部160が実行する「呼出関係データ132の生成処理および更新処理」、第一追加部120および第二追加部140が実行するコピー対象一覧生成処理などについて、図9から図12を用いて説明する。
(呼出-被呼出関係を示す情報の生成について)
図9は、開発支援装置10が実行する「呼出関係データ132の生成処理」について、その概要を示すフロー図であり、言い換えれば、解析部160による解析処理の概要を示すフロー図である。解析部160は、「呼出関係データ132の生成処理」を、つまり、解析処理を、例えば、受付部110が「コピーの対象とするPOUを選択する」ユーザ操作を受け付けるよりも前のタイミングで、予め実行しておく。
図9に示すように、解析部160は、先ず、1つ以上のプログラムを含むプロジェクトについて、そのプロジェクト内のPOUを全て列挙する(S110)。解析部160は、例えば、プロジェクトに含まれる全てのプログラムについて、プログラムごとに、プログラムを構成する複数のPOUを全て列挙する。
解析部160は、S110で列挙した全てのPOUに対して繰り返し、以下のS120の処理を実行する。言い換えれば、解析部160は、選択していないPOUが無くなるまで、S110で列挙した全てのPOUを一つずつ選択し、選択したPOUについてS120の処理を実行する。
すなわち、解析部160は、S110で列挙した全てのPOUの中から1つずつPOUを取り出し、取り出したPOUに記述されているプログラム(アルゴリズム)を解析して、呼出関係を記録する(S120)。つまり、解析部160は、取り出したPOUが呼び出している別のPOUを全て列挙し記録する。
例えば、解析部160は、プログラムごとに、そのプログラムを構成する全てのPOUを列挙し、列挙した全てのPOUの中から、1つずつPOUを取り出して、以下の処理を実行する。すなわち、解析部160は、そのプログラムにおいて、取り出したPOUに記述されているアルゴリズムを解析することにより、取り出したPOUが、そのプログラムにおいて呼び出している別のPOUを全て列挙し、これを記憶する。解析部160は、そのプログラムを構成する全てのPOUについて、上述の処理を実行する。
例えば、図6に例示した「Program0」というプログラムについて、解析部160は、「Program0」というプログラムの内容(アルゴリズム)を解析して、「Program0」というプログラムが、以下の4つのPOUによって構成されることを把握する。すなわち、解析部160は、「Program0」というプログラムが、自身である「Program0」というPOUと、「Function0」、「Function1」、および、「Function3」という3つのPOUとによって、構成されることを把握する。つまり、解析部160は、「Program0」というプログラムを構成するのは、「Program0」、「Function0」、「Function1」、および、「Function3」という4つのPOUであることを把握する。
解析部160は、「Program0」、「Function0」、「Function1」、および、「Function3」という4つのPOUの各々について、そのPOUのプログラム(アルゴリズム)を解析して、そのPOUによって呼び出されている別のPOUがないかを確認する。
具体的には、解析部160は、「Program0」というPOUのプログラム(アルゴリズム)を解析して、「Program0」というPOUが、「Function0」というPOUと、「Function1」というPOUとを呼び出していることを把握する。つまり、解析部160は、「Program0」というPOUを呼出元とし、「Function0」というPOUを呼出先とする呼出関係(関係1)と、「Program0」というPOUを呼出元とし、「Function1」というPOUを呼出先とする呼出関係(関係2)とを把握する。
また、解析部160は、「Function0」というPOUのプログラム(アルゴリズム)を解析して、「Function0」というPOUが、「Function3」というPOUを呼び出していることを把握する。つまり、解析部160は、「Function0」というPOUを呼出元とし、「Function3」というPOUを呼出先とする呼出関係(関係3)を把握する。
さらに、解析部160は、「Function1」というPOUのプログラム(アルゴリズム)を解析して、「Function1」というPOUによって呼び出されている別のPOUがないことを確認する。解析部160は、「Function3」というPOUのプログラム(アルゴリズム)を解析して、「Function3」というPOUによって呼び出されている別のPOUがないことを確認する。
解析部160は、把握した関係1、関係2、および、関係3を、呼出関係データ132に格納し、例えば、関係1、関係2、および、関係3を、「Program0」というプログラムに対応付けて、呼出関係データ132に格納する。
例えば、図7に例示した「Program1」というプログラムについて、解析部160は、「Program1」というプログラムの内容(アルゴリズム)を解析して、「Program1」というプログラムを構成する4つのPOUを把握する。具体的には、解析部160は、「Program1」というプログラムが、自身である「Program1」というPOUに加えて、以下の3つのPOUによって構成されることを把握する。すなわち、解析部160は、「Program1」というPOUに加えて、「Function1」というPOUと、「Function2」というPOUと、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』とから構成されることを把握する。
解析部160は、「Program1」、「Function1」、「Function2」、および、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』という4つのPOUの各々について、以下の判定を実行する。すなわち、解析部160は、上述の4つのPOUの各々について、そのPOUのプログラム(アルゴリズム)を解析して、そのPOUによって呼び出されている別のPOUがないかを確認する。
具体的には、解析部160は、「Program1」というPOUのプログラム(アルゴリズム)を解析して、以下の呼出関係を把握する。すなわち、解析部160は、「Program1」というPOUが、「Function1」というPOUと、「Function2」というPOUと、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』とを呼び出していることを把握する。つまり、解析部160は、「Program1」というPOUを呼出元とし、「Function1」というPOUを呼出先とする呼出関係(関係4)を把握する。また、解析部160は、「Program1」というPOUを呼出元とし、「Function2」というPOUを呼出先とする呼出関係(関係5)を把握する。さらに、解析部160は、「Program1」というPOUを呼出元とし、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』を呼出先とする呼出関係(関係6)を把握する。
また、解析部160は、「Function1」というPOUというPOUのプログラム(アルゴリズム)を解析して、「Function1」というPOUによって呼び出されている別のPOUがないことを確認する。解析部160は、「Function2」というPOUというPOUのプログラム(アルゴリズム)を解析して、「Function2」というPOUによって呼び出されている別のPOUがないことを確認する。解析部160は、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』のプログラム(アルゴリズム)を解析して、そのPOUによって呼び出されている別のPOUがないことを確認する。
解析部160は、把握した関係4、関係5、および、関係6を、呼出関係データ132に格納し、例えば、関係4、関係5、および、関係6を、「Program1」というプログラムに対応付けて、呼出関係データ132に格納する。
解析部160は、ファンクションブロックについて、ファンクションブロックを特定する情報として、その命令名を、呼出関係データ132に格納してもよい。例えば、解析部160は、『インスタンス名が「fb1」で、命令名が「FunctionBlock0」であるPOU』について、その命令名である「FunctionBlock0」を、呼出関係データ132に格納してもよい。
解析部160は、S120の処理を、プロジェクト内の全てのPOUについて実行すると、「呼出関係データ132の生成処理」を終了する。
(呼出関係データについての注記)
図9に例示するように、呼出関係データ132において、『呼出元POUの名前(つまり、「POU名(呼出元)」)』と、『呼出元POUによって呼び出されている、全ての呼出先POUの名前(つまり、「呼出先POU名」)』とは対応付けられていてもよい。例えば、或るプログラムにおいて、或るPOU(例えば、POU(p))が、3つの別のPOU(例えば、POU(q)、POU(r)、および、POU(s))を呼び出している場合、呼出関係データ132において、呼出関係は以下のように示されてもよい。すなわち、「POU名(呼出元)」であるPOU(p)の名前に対して、「呼出先POU名1」であるPOU(q)の名前と、「呼出先POU名2」であるPOU(r)の名前と、「呼出先POU名3」であるPOU(s)の名前とが対応付けられていてもよい。
例えば、図6に示した例について、呼出関係データ132において、「POU名(呼出元)」である「Program0」に対して、「呼出先POU名1」である「Function0」と、「呼出先POU名2」である「Function1」とが対応付けられていてもよい。同様に、呼出関係データ132において、「POU名(呼出元)」である「Function0」に対して、「呼出先POU名1」である「Function3」が対応付けられていてもよい。
図7に示した例について、呼出関係データ132において、「POU名(呼出元)」である「Program1」に対して、以下の3つの呼出先POU名が対応付けられていてもよい。すなわち、「Program1」に対して、「呼出先POU名1」である「Function1」と、「呼出先POU名2」である「Function2」と、「呼出先POU名3」である「FunctionBlock0」とが対応付けられていてもよい。
また、前述の通り、解析部160は、例えばプログラムごとに、プログラムを構成する複数のPOUの間の呼出関係を把握し、把握した呼出関係を呼出関係データ132に格納する。そこで、呼出関係データ132において、複数のPOUの間の呼出関係はプログラムに対応付けられて格納されていてもよい。
(プログラム更新時の、呼出-被呼出関係を示す情報の生成について)
図10は、1つ以上のPOUを呼び出しているプログラムが更新された場合に開発支援装置10が実行する「呼出関係データ132の生成処理(更新処理)」について、その概要を示すフロー図である。プログラムが更新されると、解析部160は、更新されたプログラムに対して解析処理を実行し、更新されたプログラムを構成する複数のPOUの間の呼出関係を含む呼出関係データ132を生成し、つまり、呼出関係データ132を更新する。
前述の通り、呼出関係データ132において、プログラムを構成する複数のPOUの間の呼出関係は、例えば、プログラムごとに、格納されている。そこで、プログラムテーブル131に格納されているプログラムが変更された(更新された)ことを確認すると、解析部160は、以下の処理を実行する。すなわち、解析部160は、呼出関係データ132から、更新されたプログラム(以下、「更新プログラム」と称す)に該当する呼出関係を全て削除する(S210)。
そして、解析部160は、更新プログラムにおけるPOU内のプログラム(アルゴリズム)を解析し、呼出関係を記録する(S220)。すなわち、解析部160は、更新プログラムを構成する全てのPOUを列挙し、列挙した全てのPOUの中から、1つずつPOUを取り出して、以下の処理を実行する。すなわち、解析部160は、更新プログラムにおいて、取り出したPOUに記述されているアルゴリズムを解析することにより、取り出したPOUが、更新プログラムにおいて呼び出している別のPOUを全て列挙し、これを記憶する。解析部160は、更新プログラムを構成する全てのPOUについて、上述の処理を実行する。
図10を用いて説明してきた処理について、プログラムテーブル131に格納されているプログラムが更新されると、解析部160は、ユーザによって更新されたプログラムについて、図9を用いて説明した解析処理を実行すると理解してもよい。
(POUのコピー&ペーストを指示された場合に実行する処理の概要について)
図11は、POUをコピー&ペーストするユーザ操作を受け付けた場合に、開発支援装置10が実行する処理の全体概要を示すフロー図である。図11に示すように、先ず受付部110は、コピーの対象とするPOUがユーザによって選択されたかを確認する(S310)。コピーの対象とするPOUがユーザによって選択されたことを確認すると(S310でYES)、受付部110は、コピーの対象として選択されたPOUを第一追加部120に通知する。
コピーの対象として選択されたPOUを受付部110から通知された第一追加部120は、コピー対象一覧133を生成し、つまり、コピーの対象として選択されたPOUをコピー対象一覧133に格納する(第一追加処理)。そして、第一追加部120は、「コピーの対象として選択されたPOUをコピー対象一覧133に格納した」ことを、第二追加部140に通知する。
また、コピーの対象として選択されたPOUをコピー対象一覧133に格納したことを第一追加部120から通知された第二追加部140とは、第二追加処理を実行し、つまり、コピーの対象として追加すべきPOUを、コピー対象一覧133に格納する。
すなわち、第一追加部120および第二追加部140は、コピー対象一覧133を生成する処理であるコピー対象一覧生成処理を実行し(S320)、具体的には、第一追加部120は第一追加処理を実行し、また、第二追加部140は第二追加処理を実行する。コピー対象一覧生成処理については、図12を用いて後述する。
受付部110は、コピーしたPOUをペーストするユーザ操作があったかを確認する(S330)。コピーしたPOUをペーストするユーザ操作があったことを確認すると(S330でYES)、受付部110は、その旨をペースト部150に通知する。
「コピーの対象として選択したPOUをペーストするユーザ操作があった」ことを受付部110から通知されたペースト部150は、コピー対象一覧133に含まれているPOUを全てペーストする(S340)。
コピーの対象とするPOUがユーザによって選択されていない場合(S310でNO)、受付部110は処理を終了する。また、コピーしたPOUをペーストするユーザ操作がないことを確認すると(S330でNO)、受付部110は処理を終了する。
(コピー対象一覧の生成処理について)
図12は、図11におけるコピー対象一覧生成処理の一例を説明するフロー図である。図12に示すように、コピー対象一覧生成処理においては先ず、第一追加部120が、コピーの対象として選択されたPOUをコピー対象一覧133に追加する(S410)。すなわち、第一追加部120は、第一追加処理を実行する。
第一追加部120は、コピーの対象として選択されたPOUをコピー対象一覧133に格納すると、「コピーの対象として選択されたPOUをコピー対象一覧133に格納した」ことを、第二追加部140に通知する。
「コピーの対象として選択されたPOUをコピー対象一覧133に格納した」ことを第一追加部120から通知された第二追加部140は、コピー対象一覧133に格納されている全てのPOUに対して繰り返し、S420からS440までの処理を実行する。言い換えれば、第二追加部140は、選択していないPOUが無くなるまで、コピー対象一覧133に格納されている全てのPOUを一つずつ選択し、S420からS440までの処理を実行する。
第二追加部140は、先ず、記憶部130の呼出関係データ132を参照して、選択したPOUの呼出関係を取得し(S420)、つまり、「選択したPOUを呼出元POUとする呼出先POUが、存在しないか」を確認する呼出先確認処理を実行する。そして、呼出先POUが1つ以上存在する場合、第二追加部140は、その1つ以上の呼出先POUを全て取得し、つまり、選択したPOUによって呼び出されている別のPOU(つまり、呼出先POU)を全て取得する。
次に、第二追加部140は、取得した全ての呼出先POUに対して繰り返し、S430およびS440の処理を実行する。言い換えれば、第二追加部140は、選択していないPOUが無くなるまで、取得した全ての呼出先POUを一つずつ選択し、S420からS440までの処理を実行する。
すなわち、第二追加部140は、「選択した呼出先POUが、未だ、コピー対象一覧133に存在しないか」を確認する(S430)。「選択した呼出先POUが、未だ、コピー対象一覧133に存在しない」ことを確認すると(S430でYES)、第二追加部140は、選択した呼出先POUを、コピー対象一覧133に追加する(S440)。「選択した呼出先POUが既にコピー対象一覧133に存在する」ことを確認すると(S430でNO)、第二追加部140は、選択した呼出先POUを、コピー対象一覧133に追加しない。すなわち、第二追加部140は、第二追加処理を実行する。
第二追加部140は、取得した全ての呼出先POUに対する、S430およびS440の処理の実行が完了すると、「コピー対象一覧133に格納されているPOUであって、未だ選択していないPOUがあるか」を確認する。そして、「コピー対象一覧133に格納されているPOUであって、未だ選択していないPOUがある」と、第二追加部140は、未だ選択していないPOUを選択し、S420の処理を実行する。
「コピー対象一覧133に格納されているPOUであって、未だ選択していないPOUがない」ことを確認すると、第二追加部140は処理を終了する。
(開発支援装置10の実行する制御方法についての整理)
これまで図11および図12を用いて説明してきた開発支援装置10の実行する制御方法は、以下のように整理することができる。すなわち、開発支援装置10の実行する制御方法は、PLC20(制御装置)で実行されるプログラムをユーザが作成するのを支援する開発支援装置の制御方法である。前記制御方法は、第一追加ステップ(S410)と、第二追加部ステップ(S440)と、ペーストステップ(S340)とを含む。
第一追加ステップは、ユーザによって、プログラムを構成する複数の機能上の構成要素であるプログラム要素PE(例えば、POU)の中から、コピーの対象とするPOUが選択されると、選択されたPOUをコピー対象一覧133に含める。
第二追加ステップは、第二追加処理(追加処理)を、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、繰り返し実行する。
第二追加処理は、「プログラムにおいて、コピー対象一覧133に含まれているPOUによって呼び出されている、コピー対象一覧133に含まれていないPOU」を、コピー対象一覧133に含める処理である。例えば、「Program0」というプログラムにおいて、コピー対象一覧133に格納されている「Function0」というPOUによって、「Function3」というPOUが呼び出されていると、第二追加部140は、第二追加処理として、以下の処理を実行する。すなわち、第二追加部140は、『「Function3」というPOUが、未だ、コピー対象一覧133に含まれていない(格納されていない)』ことを確認すると、「Function3」というPOUを、コピー対象一覧133に含める(格納する)。
ペーストステップは、「コピーの対象として選択したPOUを、所望の位置へとペーストする」ユーザ操作があると、コピー対象一覧133に含まれているPOUの全てを、その所望の位置へとペーストする。
前記の構成によれば、前記制御方法は、ユーザによってコピーの対象とするPOUが選択されると、先ず、選択されたPOUをコピー対象一覧133に含める。次に、前記制御方法は、「『コピー対象一覧133に含まれているPOU』によって呼び出されている、『コピー対象一覧133に含まれていないPOU』を、コピー対象一覧133に含める」第二追加処理を、以下の条件が満たされるまで、繰り返し実行する。すなわち、前記制御方法は、第二追加処理を、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、繰り返し実行する。そして、コピーの対象として選択したPOUを所望の位置へとペーストするユーザ操作があると、前記制御方法は、コピー対象一覧133に含まれているPOUの全てを、その所望の位置へとペーストする。
ここで、或るプロジェクト(例えば、PJ1)で作成した或るプログラム(例えば、PRG1)について、PRG1を構成するPOUの一つであるPOU(x)を、以下のように利用(再利用)したいという状況が発生し得る。すなわち、POU(x)を、別のプロジェクト(例えば、PJ2)のためのプログラム(例えば、PRG2)でも利用したいという状況が発生し得る。つまり、PRG1を構成するPOU(x)を、PRG2において再利用したいという状況が発生し得る。
この場合、PRG1において、POU(x)が別のPOU(y)を呼び出している時には、PRG2でPOU(x)を利用(再利用)するには、以下の点に注意する必要がある。すなわち、POU(y)も、POU(x)と一緒に、PRG2にペーストしなければならない点に注意する必要がある。つまり、PRG1を構成するPOU(x)をPRG2で再利用するには、PRG1においてPOU(x)によって呼び出されているPOU(y)も、POU(x)と一緒にコピー&ペーストする必要がある。
そこで従来、ユーザは、POU(x)とPOU(y)との両方を、手作業でコピーの対象として選択し、コピーしたPOU(x)とPOU(y)とを、プログラムPRG2にペーストしていた。
しかしながら、「コピーしたいPOUによって呼び出されている、別のPOU」の調査は、ユーザにとって手間である。特に、コピーしたいPOUの個数が多い場合、それらのPOUの各々について、「コピーしたいPOUによって呼び出されている、別のPOU」を調査するのは、非常に手間である。また、コピーしたいPOUが1つでも、そのPOUによって呼び出されている別のPOUの個数が多い場合、「コピーしたいPOUによって呼び出されている、別のPOU」を全て調べ上げるのは、非常に手間である。
その上、ユーザによる『「POUによって呼び出されている、別のPOU」の調査』には誤りが発生する可能性がある。つまり、「POUによって呼び出されている、別のPOU」を調査する段階で、ユーザによる誤りが発生し得る。
また、ユーザが調査を正確に行えたとしても、コピーの対象を選択する際に、調査した「POUによって呼び出されている、別のPOU」とは異なるPOUを、ユーザが選択してしまう可能性もある。つまり、「POUによって呼び出されている、別のPOU」をコピーの対象として選択する段階で、ユーザによる誤りが発生し得る。
これに対して、前記制御方法は、POU(x)がユーザによって「コピーの対象とするPOU」として選択されると、先ず、POU(x)を、コピー対象一覧133に含める。
さらに、前記制御方法は、「『コピー対象一覧133に含まれているPOU』によって呼び出されている、『コピー対象一覧133に含まれていないPOU』を、コピー対象一覧133に含める」処理である第二追加処理を実行する。例えば、前記制御方法は、「コピー対象一覧133に含まれているPOU(x)」がプログラムPRG1において呼び出しているPOU(y)を、コピー対象一覧133に含める。
前記制御方法は、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、第二追加処理を繰り返し実行する。そして、前記制御方法は、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなったことを確認すると、第二追加処理を終了する。例えば、プログラムPRG1において、POU(x)によって呼び出されているのがPOU(y)のみであり、POU(y)は別のPOUを呼び出していない場合、前記制御方法は、以下の時点で第二追加処理を終了する。すなわち、前記制御方法は、コピー対象一覧133に、POU(x)とPOU(y)とが含まれている(格納されている)ことを確認すると、第二追加処理を終了する。
つまり、前記制御方法は、POU(x)がコピー対象として選択されると、POU(x)と共に、プログラムPRG1においてPOU(x)によって呼び出されているPOU(y)を、コピーの対象とする。
そのため、前記制御方法は、「プログラムにおいて、或るPOUによって呼び出されている、別のPOU」の調査および選択の負担をユーザに課すことなく、当該別のPOUを、当該或るPOUと共に、コピーの対象とすることができる。
また、前記制御方法は、プログラムに基づいて、「或るPOUによって呼び出されている、別のPOU」を調査、選択するから、「或るPOUによって呼び出されている、別のPOU」の調査および選択について、誤りを発生させるおそれがない。
さらに、前記制御方法は、第二追加処理を、「コピー対象一覧133に含まれているPOUによって呼び出されているPOUであって、コピー対象一覧133に未だ含まれていないPOU」が存在しなくなるまで、繰り返し実行する。そのため、前記制御方法は、或るPOUを再利用するのに必要な、全てのPOUを、コピーの対象とすることができる。
したがって、前記制御方法は、プログラムを構成する複数のPOUを、ユーザがより効率的に利用することを可能とするとの効果を奏する。
(コピー対象一覧の一例について)
図13は、コピー対象一覧133の例を示す図である。特に図13は、図6に例示した「Program0」というプログラムについて、「Program0」をコピーの対象として選択するユーザ操作があった場合に生成されるコピー対象一覧133の例を示している。
図6に例示した「Program0」というプログラムについて、「Program0」というプログラム(POU)を構成する、「Program0」、「Function0」、「Function1」、および、「Function3」という4つのPOUについて、以下の呼出関係があった。すなわち、「Program0」というPOUを呼出元とし、「Function0」というPOUと、「Function1」というPOUとを呼出先とする呼出関係があった。また、「Function0」というPOUを呼出元とし、「Function3」というPOUを呼出先とする、呼出関係があった。
そこで、第一追加部120は、コピーの対象として選択された「Program0」というPOUを、コピー対象一覧133に格納する(第一追加処理)。また、第二追加部140は、コピー対象一覧133に格納されている「Program0」というPOUについて、呼出関係データ132を参照して、『「Program0」というPOUを呼出元とする呼出先POUがないか』を確認する。
「Program0」というPOUによって、「Function0」というPOUと、「Function1」というPOUとが呼び出されていることを確認すると、第二追加部140は、これらの呼出先POUの各々について、コピー対象一覧133に格納されていないかを確認する。これらの呼出先POUがいずれもコピー対象一覧133に格納されていないことを確認すると、第二追加部140は、これらの呼出先POU(つまり、「Function0」というPOU、および、「Function1」というPOU)を、コピー対象一覧133に格納する。すなわち、第二追加部140は、第二追加処理として、「Function0」というPOUと、「Function1」というPOUとを、コピー対象一覧133に格納する。
第二追加部140は、再びコピー対象一覧133を参照して、「Function0」というPOUについて、呼出関係データ132を参照して、「Function0」というPOUを呼出元とする呼出先POUがないかを確認する。
「Function0」というPOUによって、「Function3」というPOUが呼び出されていることを確認すると、第二追加部140は、『この呼出先POU(つまり、「Function3」というPOU)が、コピー対象一覧133に格納されていないか』を確認する。「Function3」というPOUがコピー対象一覧133に格納されていないことを確認すると、第二追加部140は、「Function3」というPOUを、コピー対象一覧133に格納する。
すなわち、第二追加部140は、第二追加処理として、「Function3」というPOUを、コピー対象一覧133に格納する。
第二追加部140は、再びコピー対象一覧133を参照して、「Function1」というPOUについて、呼出関係データ132を参照して、「Function1」というPOUを呼出元とする呼出先POUがないかを確認する。
『「Program0」というプログラムにおいて、「Function1」というPOUによって呼び出されているPOUがない』ことを確認すると、第二追加部140は、「Function1」というPOUを呼出元とする呼出先POUの格納を実行しない。
第二追加部140は、再びコピー対象一覧133を参照して、「Function3」というPOUについて、呼出関係データ132を参照して、「Function3」というPOUを呼出元とする呼出先POUがないかを確認する。
『「Program0」というプログラムにおいて、「Function3」というPOUによって呼び出されているPOUがない』ことを確認すると、第二追加部140は、「Function3」というPOUを呼出元とする呼出先POUの格納を実行しない。
第二追加部140は、再びコピー対象一覧133を参照して、「呼出先POUの有無を判定していないPOUは、もはやない」と判定すると、呼出先POUの格納処理を終了する。つまり、第二追加部140は、再びコピー対象一覧133を参照して、「呼出先確認処理を実行していないPOUは、もはやない」ことを確認すると、呼出先POUの格納処理を終了する。
したがって、図13に例示するように、「Program0」というPOUがコピーの対象としてユーザに選択されると、以下の4つのPOUが格納されたコピー対象一覧133が生成される。すなわち、「Program0」、「Function0」、「Function1」、および、「Function3」という4つのPOUが格納されたコピー対象一覧133が生成される。
§4.変形例
これまで、表示制御部170は、呼出関係データ132を表示する際に、ファンクションブロックを、「そのファンクションブロックのインスタンス名」または「そのファンクションブロックの命令名」によって表示する例を説明してきた。しかしながら、表示制御部170は、呼出関係データ132を表示する際に、ファンクションブロックを、「そのファンクションブロックのインスタンス名、および、命令名」によって表示してもよい。
〔ソフトウェアによる実現例〕
開発支援装置10の機能ブロックは、集積回路(ICチップ)等に形成された論理回路(ハードウェア)によって実現してもよいし、CPU(CenTral Processing Unit)を用いてソフトウェアによって実現してもよい。具体的には、受付部110、第一追加部120、第二追加部140、ペースト部150、解析部160、および、表示制御部170は、ハードウェアによって実現してもよいし、ソフトウェアによって実現してもよい。
後者の場合、開発支援装置10は、各機能を実現するソフトウェアであるプログラムの命令を実行するCPU、上記プログラムおよび各種データがコンピュータ(またはCPU)で読み取り可能に記録されたROM(Read Only Memory)または記憶装置(これらを「記録媒体」と称する)、上記プログラムを展開するRAM(Random Access Memory)等を備えている。そして、コンピュータ(またはCPU)が上記プログラムを上記記録媒体から読み取って実行することにより、本発明の目的が達成される。上記記録媒体としては、「一時的でない有形の媒体」、例えば、テープ、ディスク、カード、半導体メモリ、プログラマブルな論理回路等を用いることができる。また、上記プログラムは、該プログラムを伝送可能な任意の伝送媒体(通信ネットワークや放送波等)を介して上記コンピュータに供給されてもよい。なお、本発明は、上記プログラムが電子的な伝送によって具現化された、搬送波に埋め込まれたデータ信号の形態でも実現され得る。
本発明は上述した各実施形態に限定されるものではなく、請求項に示した範囲で種々の変更が可能であり、異なる実施形態にそれぞれ開示された技術的手段を適宜組み合わせて得られる実施形態についても本発明の技術的範囲に含まれる。