このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
コマンド ライン API を使用した要件リンクの更新または修復
この例では、1 つ以上のアーティファクトの移動または名前変更後に、設計アーティファクトと要件の間のリンクが古くなるという一般的な状況について説明しています。リンク切れを削除して新しいリンクを作成するのではなく、作成/変更の履歴とその他のプロパティ (説明、キーワード、コメントなど) が保持されるように既存のリンクを更新する必要があります。
プロジェクト ファイル例
始める前に、slreq.clear
コマンドを実行して必ずクリーンな初期状態にしてください。その後、CruiseRequirementsExample
プロジェクトを開きます。これにより、リンクされたアーティファクト ファイルのコレクションが MATLAB/Projects
フォルダーの下の新しいサブフォルダーに解凍されます。
slreq.clear
openProject("CruiseRequirementsExample");
要件にリンクされた Simulink モデル
プロジェクトの依存関係グラフのごく一部に焦点を当てます。外部の Microsoft® Word ドキュメント crs_reqs.docx
へのリンクを数個もつ crs_plant.slx
Simulink® モデルを開きます。
open_system('crs_plant');
いずれかのリンクで移動して、リンクされたドキュメントを開きます。
rmi('view', 'crs_plant/status', 1);
Word ドキュメントの対応するセクションが開きます。
コマンド ライン API の使用方法と、crs_plant.slx
から crs_reqs.docx
へのリンクのチェック方法を以下に示します。
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); links = linkSet.getLinks(); disp('Original Links to Word document:');
Original Links to Word document:
for i = 1:numel(links) linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') source = links(i).source; disp([' found link from ' strrep(getfullname([bdroot source.id]),newline,'') ... ' to crs_req.docx']); end end
found link from crs_plant/Vehicle1/vehiclespeed to crs_req.docx found link from crs_plant/throttDrv to crs_req.docx found link from crs_plant/status to crs_req.docx found link from crs_plant/throttleCC to crs_req.docx
インポートされた参照が存在する場合の直接リンクの移動
MATLAB® コマンド ラインで、「slreq.editor
」と入力して、"要件エディター" を開きます。読み込まれた 2 つの要件セット crs_req.slreqx
と crs_req_func_spec.slreqx
が表示されます。最初の要件セットは crs_req.docx
からインポートされた参照のコレクションであり、2 番目の要件セットは "要件エディター" で手動により作成されました。Word ドキュメントを閉じて、crs_plant/status
Inport ブロックからの同じリンクで移動した場合、インポートされた読み込み済みの要件セットの中で一致する参照が移動アクションによって検出されるため、対応するインポート済みの参照が "要件エディター" で強調表示されます。
この場合でも、[ドキュメントに表示] ボタンを使用して、リンクされた要件を元のドキュメントのコンテキストで表示することができます。
slreq.editor(); rmidotnet.MSWord.application('kill'); rmi('view', 'crs_plant/status', 1);
使用例 1: ドキュメントの名前変更後のリンクのバッチ更新
crs_req_v2.docx
という名前の更新済みバージョンの要件ドキュメントが受信されるとします。ここで、更新済みドキュメントの対応するセクションを対象にするために、crs_plant.slx
内にリンクが必要です。この例では、元のドキュメントのコピーを同じフォルダー内に作成し、変更済みの名前を付けます。次に、slreq.LinkSet
API を使用して特定の LinkSet
内のすべてのリンクをバッチ更新し、ドキュメントの新しいコピーに接続します。
copyfile(fullfile(pwd, 'documents/crs_req.docx'), fullfile(pwd, 'documents/crs_req_v2.docx')); linkSet.updateDocUri('crs_req.docx', 'crs_req_v2.docx');
一致するリンクの更新の検証
同じリンクで移動し、適切なバージョンの外部ドキュメントが開くことを確認できます。前と同じようにすべてのリンクを反復すると、4 つすべてのリンクが意図したとおりに更新されたことが確認されます。
rmi('view', 'crs_plant/status', 1); % updated document opens links = linkSet.getLinks(); disp('Links to Word document after update:');
Links to Word document after update:
for i = 1:numel(links) source = links(i).source; linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') warning(['link from ' source.id ' still points to crs_req.docx']); % should not happen elseif contains(linkTarget.artifact, 'crs_req_v2.docx') disp([' found link from ' strrep(getfullname([bdroot source.id]),newline,' ')... ' to crs_req_v2.docx']); end end
found link from crs_plant/Vehicle1/vehicle speed to crs_req_v2.docx found link from crs_plant/throttDrv to crs_req_v2.docx found link from crs_plant/status to crs_req_v2.docx found link from crs_plant/throttleCC to crs_req_v2.docx
リンクの更新後にインポートされた参照へ移動
上で示したように、インポートされた参照を "要件エディター" で利用できる場合、リンクの移動によって一致する参照オブジェクトが選択されます。ただし、ドキュメント crs_req_v2.docx
の新しいバージョンのリンクを更新したばかりであり、このドキュメントに関してインポートされた参照はありません。"要件エディター" が存在している場合に Simulink ブロックから移動すると、外部の Word ドキュメントに直接移動します。
こうした不整合を回避するには、更新されたドキュメント名との関連付けを維持するために、以前にインポートされた参照を更新する必要があります。slreq.ReqSet
API を使用してこのタスクを達成します。さらに、更新されたドキュメントには変更済みの要件がある場合があるため、updateFromDocument
API を使用して Requirements Toolbox 側に保存されている参照項目の更新を取り込まなければなりません。これが完了したら、Simulink モデルからの移動によって、一致する、インポートされた参照が特定されます。
インポートされた参照をもつ要件セットを見つけます。ソース ファイルの場所を更新し、最上位のインポート ノードを見つけます。
reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req'); reqSet.updateSrcFileLocation('crs_req.docx', 'crs_req_v2.docx'); importNode = reqSet.find('CustomId', 'crs_req_v2');
インポートされた参照を、ソース ファイルから更新します。Microsoft Word を閉じます。次に、"要件エディター" 内の更新された参照に移動します。
importNode.updateFromDocument(); rmidotnet.MSWord.application('kill'); rmi('view', 'crs_plant/status', 1);
使用例 1 の後のクリーンアップ
プロジェクトを閉じるときにプロンプトが表示されるのを防ぐため、リンク データを破棄します。プロジェクトを閉じます (MATLAB パスの変更もクリーンアップされます)。Microsoft Word を閉じます。
slreq.clear();
prj = simulinkproject(); prj.close();
rmidotnet.MSWord.application('kill');
使用例 2: インポートされた参照に完全に依存するようにリンクをバッチ更新
上記の使用例 1 で示したように、ドキュメントの移動や名前変更が行われた場合は、外部ドキュメントへの "直接リンク" を維持するためにさらなる作業が必要です。より適切なワークフローは、既存の "直接リンク" を "参照リンク" に変換することです。参照リンクとは、*
.slreqx
ファイル内のインポートされた References
を指し、元のドキュメントの場所または名前に関する情報を複製しないリンクのことです。このオプションを使用する場合、外部のソース ドキュメントとの関連付けはインポートされた参照をホストする要件セットにのみ保存されます。
このワークフローを示すために、新しいサブフォルダー内で CruiseRequirementsExample
プロジェクトを再度開くことで同じ初期点から再開します。Simulink モデルを自分のディレクトリにコピーし、開きます。
slreqCCProjectStart(); copyfile(fullfile(pwd, 'documents/crs_req.docx'), fullfile(pwd, 'documents/crs_req_v2.docx')); open_system('crs_plant');
インポートされた参照をもつ crs_plant
リンク セットおよび crs_req
要件セットを見つけます。
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req');
その後、slreq.LinkSet
API を使用して crs_plant.slmx
内のすべての直接リンクを更新します。次に、リンク セット内にすべてのリンクの配列を作成します。
linkSet.redirectLinksToImportedReqs(reqSet); links = linkSet.getLinks();
このような方法で LinkSet
を更新した後、すべてのリンクをループして crs_req.docx
ファイルへの "直接" リンクが存在しないことを確認します。
disp('Check for links to original external document:');
Check for links to original external document:
counter = 0; for i = 1:numel(links) linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') source = links(i).source; warning(['link from ' source.id ' still points to crs_req.docx']); counter = counter + 1; end end disp([' Total ' num2str(counter) ' links to external document']);
Total 0 links to external document
Simulink モデルから更新済みの参照に移動します。
rmi('view', 'crs_plant/status', 1);
参照へのリンクと外部ドキュメントの名前変更
すべてのリンクが外部ドキュメントではなくインポートされた参照を指している場合、インポート ノードが新しい外部ドキュメント名で更新されている限り、トレーサビリティ データの整合性はドキュメントの名前変更後も維持されます。使用例 1 のように、Word ドキュメントを新しい名前で再保存することで、更新バージョンの外部要件ドキュメントが存在するように見せかけます。その後、以前と同じ API を使用して、インポート ノードに必要な更新を実行します。ここで、リンクはインポートされた参照に依存しており、インポートされたドキュメントに関する情報を保存しないため、使用例 1 のすべての手順を実行した後のように、Simulink モデルからの移動によって、更新された参照に移動できます。
現在、参照は更新された外部ドキュメントに関連付けられています。[ドキュメントに表示] ボタンは更新された (名前が変更された) ドキュメントを開きます。LinkSet 側ではこれ以上の調整は必要ありません。
インポートされた参照をもつ要件セットを見つけます。ソース ファイルの場所を更新し、最上位のインポート ノードを見つけます。
reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req'); reqSet.updateSrcFileLocation('crs_req.docx', 'crs_req_v2.docx'); importNode = reqSet.find('CustomId', 'crs_req_v2');
インポートされた参照を、ソース ファイルから更新します。次に、"要件エディター" 内の更新された参照に移動します。
importNode.updateFromDocument();
rmi('view', 'crs_plant/status', 1);
使用例 2 の後のクリーンアップ
プロジェクトを閉じるときにプロンプトが表示されるのを防ぐため、リンク データを破棄します。プロジェクトを閉じます (MATLAB パスの変更もクリーンアップされます)。Microsoft Word を閉じます。
slreq.clear();
prj = simulinkproject(); prj.close();
rmidotnet.MSWord.application('kill');
使用例 3: リンクされたアーティファクトを新しいプロジェクトに移動
ここでは、リンクされたアーティファクトをもつ既存のプロジェクトを分岐していて、元のプロジェクトと同じようにすべてのトレーサビリティ リンクをもつ名前変更された新しい一連のアーティファクトを作成する必要があると仮定します。前と同じように、CruiseRequirementsExample
プロジェクトを新しいサブフォルダーに抽出し、上記の使用例 2 で行ったように "直接リンク" を "参照リンク" に変換します。先に進み、それぞれを _
v2.
という名前で再保存することで、リンクされたアーティファクトの "新バージョン" を作成します。
名前を変更した Simulink モデルのコピー、インポートされた外部ドキュメント、およびインポートされた要件を含む要件セットの作成後、問題が 1 つあります。つまり、名前を変更したモデルが、名前を変更した要件セットではなく元の要件セットに含まれる参照にリンクされているということです。元のモデルが読み込まれていないため、[詳細] ペインの [リンク] にはリンクが未解決と表示されます。
CruiseRequirementsExample
プロジェクトを開き、crs_plant
モデルを開きます。crs_plant
のリンク セットと、要件セット crs_req
を見つけます。
slreqCCProjectStart(); open_system('models/crs_plant.slx'); linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req');
直接リンクを参照リンクに変換します。ファイルの名前を変更したコピーを作成し、保存します。
linkSet.redirectLinksToImportedReqs(reqSet); mkdir(fullfile(pwd, 'copied')); save_system('crs_plant', fullfile(pwd, 'copied/crs_plant_v2.slx')); reqSet.save(fullfile(pwd, 'copied/crs_req_v2.slreqx')); copyfile('documents/crs_req.docx', 'copied/crs_req_v2.docx');
名前を変更した要件セットを、名前を変更したドキュメントに関連付けます。最上位のインポート ノードを見つけます。
reqSet.updateSrcFileLocation('crs_req.docx', fullfile(pwd, 'copied/crs_req_v2.docx')); importNode = reqSet.find('CustomId', 'crs_req_v2');
インポートされた参照を更新することにより、名前を変更した要件セットの内容が、名前を変更したドキュメントの内容に一致することを確認します。名前を変更した Simulink モデルから、名前を変更した要件セットの項目に移動します。元の要件セット内の古い項目が強調表示されます。これは正しくありません。
importNode.updateFromDocument();
rmi('view', 'crs_plant_v2/status', 1);
名前を変更したリンク元のリンクを更新して、名前を変更したリンク先をターゲットとして使用する
使用例 1 と同じように、LinkSet.updateDocUri(OLD, NEW)
API を使用して crs_plant_v2.slmx
のリンクを更新し、元の crs_req.slreqx
ではなく名前が変更された要件セット crs_req_v2.slreqx
をリンク ターゲットとして使用することができます。これが完了したら、名前を変更したモデル内のブロックから再度移動します。名前が変更された要件セット中の要件が選択され、[詳細] ペインの [リンク] (右下) のリンクは解決されます。
モデルの新しいコピーである crs_plant_v2
のリンク セットを見つけます。モデルの新しいコピーとリンクされた要件セットの名前を更新します。名前を変更した Simulink モデルから、名前を変更した要件セットの項目に移動します。今回は、正しい項目が強調表示されます。
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant_v2'); linkSet.updateDocUri('crs_req.slreqx', 'crs_req_v2.slreqx');
rmi('view', 'crs_plant_v2/status', 1);