3.修正方法3

   新しい属性の追加

a. パーツCollecXYの修正

計算する間隔を線形的に等間隔にしていたが、今回は対数的と逆数的にも

等間隔にできるように変更する。

1.WorkFrame IDEアイコンをクリックし、「既存のオブジェクトを

  オープンします」をクリックする。

2.DataColl.IWPを選択する。

3.WorkFrameのDataColl.vbbをダブルクリックし、ビジュアル・ビルダーを起動する。

4.非ビジュアル・パーツのCollecXYをダブルクリックする。

5.「パーツ・インターフェース・エディター」の属性を選び、属性名typeOfIncrement、

  属性タイプIStringと入力し、「デフォルト」をクリックする。

  「追加」をクリックする。

6.優先のページで、属性typeOfIncrementを追加する。

7.「ファイル」->「保管および生成」->「フィーチャー・ソース」をクリックする。

8.「CollecXY−フィーチャー・ソース・コードを作成します」ダイアログにおいて、

  メンバー関数の

   virtual CollecXY& setTypeOfIncrement(const IString& aTypeOfIncrement)

   virtual IString typeOfIncrement() const

  属性データ・メンバーの

   iTypeOfIncrement

  イベント・データ・メンバーの

   typeOfIncrementId

  を選択し(ctrlキーを押しながらクリックし)、「選択したものの生成」をクリックする。

9.「プロジェクト」->「編集」をクリックし、CollecXY.cpvを開く。

  下記のようなコードが自動作成されている。

  // Feature source code generation begins here....

   最初のコードが書かれている。

  // Feature source code generation ends here.

  の次に、

  自動作成されている。

10.最初に作成されたコードのlong CollecXY::calc()を下記のように修正する。

long CollecXY::calc()
{
 double delta; // dataXの計算間隔
 long iCount=0; // データ数
 DataXY* iResultXY; // DataXY構造のポインターをiResultXYとする。
 
 // resultの全てのデータを削除する。
 removeAll();
 
 //
修正箇所開始
 if( iMaximumDataX<=iMinimumDataX ) // 範囲の値が逆の場合、例外処理を行う。
 {
  IString errorText = IString( "範囲を設定し直してください。" );
  IException exc( errorText, 0, IException::unrecoverable );
  ITHROW( exc );
  } // 例外処理終了
 //
修正箇所終了
 
 // データ数が1以下の場合、例外処理を行う。
 if( iNumber<=1)
 {
  IString errorText = IString( "データ数が1以下です。" );
  IException exc( errorText, 0, IException::unrecoverable);
  ITHROW( exc );
 } // 例外処理終了
 
 // resultのイベント通知機能を禁止する。
 iResult->disableNotification();
 
 if( iTypeOfIncrement=="linear" ) // 等間隔の場合 
修正箇所
 {                      // 
修正箇所
  delta = (iMaximumDataX - iMinimumDataX)/(iNumber - 1); // 計算間隔
  // データ数だけ繰り返す。
  for( int i=0; i<=(iNumber-1); i++ )
  {
   iResultXY = new DataXY; // iResultXYの実体(メモリー領域)を確保する。
   // dataXに数値を代入し、dataXのイベントを発生させる。
   iDataX = iMinimumDataX + delta*i; //
1997年10月30日修正
   notifyObservers(INotificationEvent(CollecXY::dataXId, *this)); //
1997年10月30日修正
   //  1.他のパーツのdataXに対応する属性の値を変更する。
   //  2.dataXのイベントで、他のパーツのdataYに対応する値を計算させる。
   //  3.dataYに対応する値が戻ってくるまで待つ。
   // 変数dataXをiResultXYのdataXに代入する。
   iResultXY->setDataX( iDataX );
   // 関数値dataYをiResultXYのdataYに代入する。
   iResultXY->setDataY( iDataY );
   // シーケンシャルなresultの最後の項に加える。
   iResult->addAsLast( iResultXY );
   iCount++;
  }
 }                  //
修正箇所
 
 //
修正箇所開始
 if( iTypeOfIncrement=="log" ) // 対数的に等間隔の場合
 {
  if( iMinimumDataX<=0 ) // 最小値が0または負のとき、例外処理を行う。
  {
   IString errorText = IString( "最小値が0または負です。" );
   IException exc( errorText, 0, IException::unrecoverable );
   ITHROW( exc );
  } // 例外処理終了
 
  delta = log(iMaximumDataX/iMinimumDataX)/(iNumber - 1); // 計算間隔
  // データ数だけ繰り返す。
  for( int i=0; i<=(iNumber-1); i++ )
  {
   iResultXY = new DataXY; // iResultXYの実体(メモリー領域)を確保する。
   // dataXに数値を代入し、dataXのイベントを発生させる。
   iDataX = exp( log(iMinimumDataX) + delta*i); //
1997年10月30日修正
   notifyObservers(INotificationEvent(CollecXY::dataXId, *this)); //
1997年10月30日修正
   //  1.他のパーツのdataXに対応する属性の値を変更する。
   //  2.dataXのイベントで、他のパーツのdataYに対応する値を計算させる。
   //  3.dataYに対応する値が戻ってくるまで待つ。
   // 変数dataXをiResultXYのdataXに代入する。
   iResultXY->setDataX( iDataX );
   // 関数値dataYをiResultXYのdataYに代入する。
   iResultXY->setDataY( iDataY );
   // シーケンシャルなresultの最後の項に加える。
   iResult->addAsLast( iResultXY );
   iCount++;
  }
 }
 
 if( iTypeOfIncrement=="inverse" ) // 逆数的に等間隔の場合
 {
  if( iMinimumDataX*iMaximumDataX<=0 ) // 例外処理
  {
   IString errorText = IString( "範囲内に0が含まれます。" );
   IException exc( errorText, 0, IException::unrecoverable );
   ITHROW( exc );
  } // 例外処理終了
 
  delta = (1/iMinimumDataX - 1/iMaximumDataX)/(iNumber - 1); // 計算間隔
  // データ数だけ繰り返す。
  for( int i=0; i<=(iNumber-1); i++ )
  {
   iResultXY = new DataXY; // iResultXYの実体(メモリー領域)を確保する。
   // dataXに数値を代入し、dataXのイベントを発生させる。
   iDataX = 1/(1/iMinimumDataX - delta*i); //
1997年10月30日修正
   notifyObservers(INotificationEvent(CollecXY::dataXId, *this)); //
1997年10月30日修正
   //  1.他のパーツのdataXに対応する属性の値を変更する。
   //  2.dataXのイベントで、他のパーツのdataYに対応する値を計算させる。
   //  3.dataYに対応する値が戻ってくるまで待つ。
   // 変数dataXをiResultXYのdataXに代入する。
   iResultXY->setDataX( iDataX );
   // 関数値dataYをiResultXYのdataYに代入する。
   iResultXY->setDataY( iDataY );
   // シーケンシャルなresultの最後の項に加える。
   iResult->addAsLast( iResultXY );
   iCount++;
  }
 }  //
修正箇所終了
 
 // resultのイベント通知機能を回復する。
 iResult->enableNotification();
 // resultが変更されたことを通知する。
 notifyObservers(INotificationEvent(CollecXY::resultId, *this));
 return iCount;
}

11.セーブする。

12.クラス・エディターの必要なインクルード・ファイルに<math.h> _MATH_と

   入力する。

13.「ファイル」->「保管」をクリックする。

14.今後パーツCollecXYを利用できるように、覚え書きCollecXY.htmlを下記のように

   修正する。

パーツCollecXYの説明

DataXの最小値、最大値、データ数を指定する。

接続するパーツでDataYに対応する値を計算して、

(x, y)のデータ対をDataXの最小値から順にならべる。

CollecXYパーツ

属性

タイプ

コメント

優先

dataX

double

変数(横軸X

O

dataY

double

関数値(縦軸Y

O

minimumDataX

double

変数の最小値

O

maximumDataX

double

変数の最大値

O

number

int

変数の分割数

O

stop

IStirng

文字列stopを代入すると、計算が中止される

typeOfIncrement

IString

増加分を線形的、対数的、逆数的に等間隔にする

result

IVSequence<DataXY*>*

全データ

O

set関数の引数のconstを削除

アクション

タイプ

パラメータ

 

calc

long

 

O

removeAll

void

 

O

 

calc()はデータ数を戻り値とする。

 例外処理のメッセージが含まれている。

 接続方法:dataXの値からdataYに対応する値を計算するパーツとは、

       1.dataX -> パーツのxに対応する属性

       2.パーツのyに対応する属性 -> dataY

       3.dataX -> パーツの計算に対応するアクション

      と接続する。

      注意:上記の接続1と3の順番は間違えないこと。

 属性typeOfIncrementは

  linearで線形的に等間隔で増加、

  logで対数的に等間隔に増加、

  inverseで逆数的に等間隔に増加

 する。

 属性stopに文字列stopを代入すると、calc()が停止する。

 

必要なファイル

DataColl.vbb

CollecXY.cpv

CollecXY.hpv

 

DataXY.cpv

DataXY.hpv