Biz/Browserでかいはつ!

Biz/Browserを使った開発について

このBlogは....

2006年08月29日 00時13分02秒 | Weblog
とりあえず今後は、「Biz/Browserを愛でる会」のほうに、記事を書き綴っていくようにしていきます。
なので、こちらのBlogのほうは、しばらく休止ということにいたします。

また、8/29-9/1は、Fullではないですが開発メンバー数人でヨコハマのTech-Ed2006に行ってきます。

「Biz/Browserを愛でる会」発足!

2006年08月27日 14時41分03秒 | Weblog
栗田さんが事務局をやってくださるということで、
「Biz/Browserを愛でる会」
http://blog.goo.ne.jp/kurita_naoki/e/9942363ea5289a4026b071138508c144
http://blog.goo.ne.jp/katakait/e/cfc45974f5f175fb03c615d40cca3a43
が発足いたしました。
8/25は3人で盛り上がりいろんな話をしました。
「Biz/Browserは素晴らしい開発ツールだが、Biz/Browserを使いこなすには最適な三階層システムをまず考えなければならない」
「ユーザインターフェースの画面とサーバ側が1:1のつくりかたはベストではない。Biz側UIとサーバ側がN:1的な考え方でロジックを集約させていかないとレスポンス、開発効率両面でいいシステムはできない」
「Biz/Browserは単なるツールではない。理想的な三階層システムを実現sるためのフロントエンドツールなんだ」

「こんなにいいツールであるBiz/Browserをなんとかもっと広めていきたい。そのためにはAxissoftさんだけではなく、有志を募ってそういった趣旨の会をへつくろうではないか」
栗田さんも非常に真摯で前向きな人で、片貝さんとはまだ今年2月ぐらいからの付き合いなんだそうですが、Biz/Browserに対する情熱は人一倍ある人です。
片貝さんも久しぶりにお会いしましたが、相変わらず元気でした。

。。。「Biz/Browserを愛でる会」には、さっそく入会希望者もでてきているようなので、もし興味があるかたがいれば是非是非参加してみて下さい。


PrintStreamおよびPrintStream Coreについて

2006年08月25日 09時53分03秒 | Weblog

8/24 にAxissoftさんからannounceがあった
マルチプラットフォーム版 Web帳票印刷ツール「PrintStream® Core」を2006年9月26日より出荷開始
今後、アクシスソフトは「PrintStream® Core」を中心とした帳票市場への積極的な製品販売を推進する予定で、初年度は500ライセンスの製品出荷を見込んでいます。
なお、アクシスソフトでは出荷記念キャンペーンとして、出荷開始より2ヶ月間限定にて特別価格の298,000円(税別)にてご提供いたします。
標準提供価格:400,000円(税別)  年間保守価格:60,000円(税別)

これは従来のBiz/PrintServer のコア機能のみをとりだし(というかQFW30.exeとjs32.dllを)、JAVA化したもの(printstream.jar、コマンドラインインターフェースはQFW31.exe)です。
パートナー向け説明会が
(1) 2006年9月19日(火) 13:00~15:00
(2) 2006年9月19日(火) 15:30~17:30
に開催されるので、パートナーの人たちは参加したらよいと思います。


PirntStreamCoreとBiz/Browserを組み合わせて使う場合、開発者側で2つ必要なものがあります。
1)Biz/Browserから呼び出すインターフェース部分(aspxやServletなど)
2)サーバ側スプールの管理

実は、この2つは実際に現在CV.netですでに実現しているので、次のTips004「PrintStreamとの連動」でソースコードを交えて説明しようと思います。

たぶんPirntStreamCoreを実際にどうやって使うのか?ってことが開発者側で知りたい情報だと思うのですが、ここはAxissoftさんとしては自社製品以外の内容が入ってくるのでやりたくない部分だと思うのです。(たぶん)
なので、Axissoftとはまったく関係ないこのBlogで勝手にやっちゃいます

(この前SODECで他社の帳票ソリューションを一通り見て説明も聞きましたが、開発効率、導入コスト、印刷スピードをトータルに考えた場合、PrintStreamが現状ではベストソリューションです。)

【追記1】
コマンドラインインターフェースは調べたら、どうもQFW31.exeではなく、javaから直接起動しろということらしい...
java -jar printstream.jar -form sample.qfm ...
マニュアル(psjinit.pdf P39)にはクラスライブラリとコマンドラインの2通りやれると書いてありますが、コマンドラインでやる方法はpsjinit.pdfには書いてありません
javadocフォルダのindex.htmを参照し、クラスFormWriterのmain()メソッドを見ないとやり方が書いてないのです。
しかし、PrintStream31.chmを見ると、QFW31.exeがコマンドラインインターフェースという説明になっているので、現時点ではよくわからない


Biz/Browser Tips003 class設計について

2006年08月24日 10時37分56秒 | Weblog

Tips002で、Formで現在のカーソル位置のオブジェクトを保存しておく方法を書いたが、CV.netではclassとして定義しているものを大きく次の2つのcarファイルにまとめている。
1.classsatoo.car
どのアプリケーションにも共通に使える部品を集めたもの。汎用class。
2.classsatoo.cvnet.car
業務アプリケショーンで共通に使える部品を集めたもの。たとえば区分一覧や照会ボタンなど。色・フォントの統一や、操作の統一のために使用。

たとえば前回のFormのたぐいはclasssatoo.car内では次のように定義されている。(長くなるので部分的に抜粋)
class SatooSelForm extends Form{
  Array cur_pos; /* カーソル位置のオブジェクトcur_pos[0] .*/
  Array err_pos; /* エラーしたオブジェクトerr_pos[0] .*/
  Function append2(additem) {
   cur_pos[0]=additem;
   if (ClassSatoo.SysTest == 1){
    DebugMessage("-- "+str(sysdate(),"HH24:MI:SS")+"(Append2)Obj:"+additem.name+"(Class:"+additem.classname+")");
    if (!(additem instanceof Flexview)){
     DebugMessage(":"+str(additem.Value));
    }
    DebugMessage("n");
   }
  }
   ...........................
  Function OnGetFocus(e){
   if (FindChild("append2")!= null){
    append2(e.from);
   }
  }
  Function OnKeyDown( e ) { /* キー処理とe.key2の追加 .*/
   ...........................
   if (classsatoo.SysTest == 1){
    DebugMessage("e.from=",e.from.name,",value=",e.from.value,"n");
   }
   /* ボタン系はReturnキーでも実行可 */
   if(e.key =="RETURN"){
    try{
     if(cur_pos[0] instanceof Button){
      if (cur_pos[0].FindChild("OnTouch")!= null){
       cur_pos[0].OnTouch(e);
      }
     }
   ...........................
     else if(cur_pos[0] instanceof SatooFlexView){
      if (cur_pos[0].FindChild("OnZoom")!= null){
       cur_pos[0].OnZoom(e);
      }
     }
   ...........................
  }
 }

このSatooSelFormの中では、Form中に含まれるGUI部品の名前は一切使っていない。Enterキーで複数のボタンのOnTouch処理を走らせたい場合、初心者は最初それぞれのButtonにEnterキーを割り付けようとする。が、それではうまく動かないのである!AltKeyプロパティでは無理
故にFormのKeyDownイベントでReturnキーを捕捉し、カーソルが止まっているのがButtonであればOnTouchを実行する。
こうすることで、Buttonのオブジェクト定義に何もしなくとも、EnterでボタンのOnTouchが走るようになる
しかも、ReturnではなくたとえばF12キーにしたければ、if(e.key=="F12")と変更するだけで、全部変わるようになっている。
DebugMessageを入れているのはここに記述すると全てのところで有効なのでデバッグが楽になるため。
何気なく cur_pos[0].FindChild("OnTouch")などとコードを書いているが、FindChildでは実はオブジェクトだけではなく関数も検索できるのでこれで正しい。
これは一例だが、こんな感じで共通の汎用Classを定義していく。
classsatoo.cvnet.carでは、業務アプリケーションで共通の部品を定義するので、たとえば、
 class CvnetButton extends Button { /* ボタン(サイズ正規化) */
  Width = 90;
  Height = 24;
 }
 class CvnetBtList extends CvnetButton { /* マスタ一覧用ボタン */
  Width = 30;
  Height = 20;
  Title ="<<";
  ToolTip = "一覧取得";
  SkipTabFocus = $TRUE;
  Array ret_pos;
  Function OnTouch(e,v_obj, v_mstname, v_para2){
   ...........................
    }
   ...........................
  }
と、サイズやアプリケーション依存の処理を定義する。
これらのclass化されたGUI,非GUI部品を使うことで個々のCRSプログラムの生産性ははるかに向上する。
システム自体もDB-アプリサーバ-Bizと三階層なのだが、Biz側、アプリサーバ側内部のつくり方も三階層にすべきであるというのが、CV.netの3Tier in 3Tier の思想
ところで、このBlogに書いてある技術的な内容は、Biz/Browserの開発者にとって公開していったほうがいいだろうというようなものを書いていくので、どんどんマネしていって構いません!さすがにソース全部は出せませんが、できるだけオープンにしていきます。逆にもっとよいやり方があれば教えてください。
そしていままでやってたやり方よりいいやり方があれば、ソース全部書き直すべきです。
CV.netはBiz V4になって2004年1月ぐらいにclass化し、2004年7月に一度全面変更しています。V4からXEに変更されたときもFlexView関係の部分など変更しました。
変化をおそれずどんどん進化しないとよいシステムはできませんし、またエンジニアも成長しません。


Biz/Browser Tips002 var変数とarrayオブジェクトの使いこなし

2006年08月23日 13時52分00秒 | Weblog

・var変数を使う場合
[1]一時的なオブジェクト
String wrk_str = "hogehoge";
などの場合、オブジェクトツリーに接続されるため余計な処理が生じるということと、オブジェクトツリーは再計算対象になるので常にスキャンされてしまうためです。

[2]実オブジェクト名の代わり
たとえば
Function OnTouch(e){
var wrk_textbox = ^.^.TabFrame1.TabForm1.TextBox1;
  wrk_textbox.vlue = "hogehoge";
  wrk_textbox.FgColor=$RED;
}
長い実オブジェクト名を使わずにすむのと、もう一つは、オブジェクト名が変わった場合、最初の1行のみの修正ですむためです。
もし、全部に実オブジェクト名を記述すると、全ての箇所の変更が必要になります。

・var変数の注意点 -- 暗黙のオブジェクト生成に注意する
var変数が指し示すオブジェクトの値を変えたければ、必ず.valueをつかって代入します。
var wrk_textbox = ^.TextBox1;
wrk_textbox.value = "hoge2";
たとえば次のようにすると
var wrk_textbox = ^.TextBox1;
wrk_textbox = "hoge2";
これだと、^.TextBox1の値は変化せず、var変数が指し示すオブジェクトが"hoge2"という文字列に変わるだけです。
しかし、
^.TextBox1="hoge2";
は ^.TextBox1の値が変化します。これは、^.TextBoxのデフォルトプロパティが.valueになっているので、CRSスクリプトが暗黙的に ^.TextBox1.value = "hoge2"; と解釈するのです。
var変数と実オブジェクトの扱いが違うので、初心者は混乱しやすいポイントです。

・arrayオブジェクトの本当の価値
arrayオブジェクトはオブジェクトツリーに接続し、リファレンスの配列が格納できる唯一のものです。
CV.netの初期段階(Biz Ver3の頃)において、カーソルがとまっている項目でF5ボタンを押すとダイアログを出すという処理がありました。
しかし、KeydownイベントはFormオブジェクトでしか補足できないため、どう工夫したかというと、
Form form1{
  Array cur_pos;
  TextBox TextBox1{
   ..............
  }
   ..............
  Function OnGetFocus(e){
    cur_pos[0] = e.from;
  }
}
という形で、カーソルが止まっているオブジェクトを判断させたのです。
イベントの伝搬とarrayオブジェクトをうまく組み合わせると、Formに定義するこの数行のみで、必ずcur_pos[0]には現在のオブジェクトのリファレンスが格納されています。(Biz Ver4 の段階ではClassに定義することで汎用的に使えるようになりました)
たとえばBiz初心者の場合、カーソルが止まっているオブジェクトの判断は
Form form1{
  Number cur_pos;
  TextBox TextBox1{
    Function OnGetFocus(e){
      ^.cur_pos[0] = 1;
    }
  TextBox TextBox2{
    Function OnGetFocus(e){
      ^.cur_pos[0] = 2;
    }
   ..............
  TextBox TextBox5{
  Function OnGetFocus(e){
    ^.cur_pos[0] = 5;
  }
   ..............
  }
}
というコードを書いたりします。こんなコードでは全然ダメです!CRSスクリプトでこのような書き方を見つけたら、是非arrayオブジェクトを使う方法を教えてあげてください。
また、arrayオブジェクトの配列には自動拡張という暗黙の拡張があるため、例えば
if (array1[2]==null){
  array1[0]="hogehoge";
}

とすると、array配列はarray1[0]だけではなく、すでにarray1[0],array1[1],array1[2]まで拡張されています
なので配列を勝手に増やしたくない場合には
if (array1.length<3){
}
などという書き方にする必要があります。


Biz/Browser Tips001 月末、月初の求め方

2006年08月18日 09時46分25秒 | Weblog
【月末、月初の求め方について】
Bizの宝箱
http://support.axissoft.co.jp/support/webpages/index.html
には、いろんなサンプルコードがある。
[Bizの宝箱:月末、月初を求めるサンプルコード]
var month_first_date;
var month_last_date;

/* 月の初日の取得 */
month_first_date = new Date().setDate(1);

/* 月の末日の取得 */
month_last_date = new Date(month_first_date);
month_last_date.setFullYear(month_last_date.getFullYear()
	+ int((month_last_date.getMonth() + 1) / 12));  /* 年の設定 */
month_last_date.setMonth((month_last_date.getMonth() + 1) % 12); /* 月の設定 */
month_last_date.value -= 1;  /* 1日引く */

print("月の初日:"+str(month_first_date,"YYYY/MM/DD"),"n");
print("月の末日:"+str(month_last_date,"YYYY/MM/DD"),"n");
----
値が求められるので、これはこれで正しいと思う。
が、例えば次に述べるコードのような計算でも求められる。
----
[CV.net風:月末、月初を求めるサンプルコード]
            var date1 = new Date;
            date1.value = rounddown(sysdate());
            date1.value = date1.value -day(date1);/* 先月末 */
            DebugMessage("先月末",date1,"n");
            var m_first = new Date;
            m_first.value = date1.value + 1; /* 月初 */
            DebugMessage("月初",m_first,"n");
            var m_last = new Date;
            m_last.value = date1.value + 40-day(date1.value + 40); /* 今月末 */
            DebugMessage("月末",m_last,"n");
----
Bizの宝箱のやり方だと、なんか年と月を数値的にバラバラに扱い、最後に月末を求めるところだけ日付型計算をしているのでしっくりこない
個人的には全部日付型で扱っちゃえば楽だろうと思うのだが...
多分、Date型はBizにおいては計算に用いるのにやっかいな型であるから、Bizの宝箱ではあのようなコードになっているのであろう。
なぜなら、var変数にてDate型を使うと、.valueを必ずつけないと途中で数値型に暗黙的に変換されてしまう
また、sysdate()というのも特別な関数で、
var date1 = sysdate();
date1.value = date1.value - day(date1.value);
とやれば同じように先月末が求められるような気がするが、実はこのコードは通らない!
sysdate()で求めた値は、関数を実行されたタイミングによって返される値が変わるので、内部的には変数扱いなのだが、値を変更できない仕様にされている。(固定文字列などと同じ扱い)
ということで、日付型を使う場合にはよく注意しないと、予期しない結果になってしまう。これも初心者がよくハマるポイント。

BizDesginerでの開発2-003

2006年08月16日 13時14分30秒 | Weblog

次に、数量*単価の計算と、合計の計算をしていきます。
その前に前回のロジック OnTitleDClicked OnRClicked ですが、FlexView1オブジェクトの直下に定義していました。TitleDClickedとかRClickedとかのイベントは本来FlexTextBoxオブジェクトから発生するので、素直に作るとFlexTextBox1,2,3,4,5それぞれのところにロジックをおくということになります。しかし、そんなことをすると冗長すぎますので、イベントは上位オブジェクトに向かって伝搬するというCRSプログラムの法則を利用します。
FlexView1オブジェクト直下におけば、下位オブジェクトのイベントは全てcatchできるということです。
同じように、数量*単価の計算をFlexView1オブジェクト直下におきます。
  Function OnTextChanged(e){
   e.Row.FlexTextBox5 = e.Row.FlexTextBox3*e.Row.FlexTextBox4;
  }

また、FlexTextBox3,FlexTextBox4,FlexTextBox5はnumber型に変更します。また金額は修正できないようにするため、FlexLabelに変更します
   FlexTextBox:number FlexTextBox3 {
    Title = "単価";
   }
   FlexTextBox:number FlexTextBox4 {
    Title = "数量";
    Width = 50;
   }
   FlexLabel:number FlexTextBox5 {
    Title = "金額";
   }
Form配列やSpreadの場合、
    value = FlexTextBox3*FlexTextBox4;
のような記述ができますが、FlexViewの場合、表示オブジェクトと実データのオブジェクトが違うので(この辺がForm配列とSpreadとかとの違い。たとえばFlexTextBoxオブジェクトとFlexTextBoxCellオブジェクト)、TextChangedイベントハンドラ内に記述します。
また、合計を計算するロジックもFlexView1オブジェクト直下に定義します。
  Function OnCountTotal(e){
   var su=0;
   var kin=0;
   var crow=FlexView1.GetRow();
   while(!crow.End){
    su += crow.FlexTextBox4;
    kin += crow.FlexTextBox5;
    crow.MoveNext();
   }
   ^.TextBox2= su;
   ^.TextBox3= kin;
  }
OnCountTotal(e)という名前にしていますが、別にHogeHoge(e)でもかまいません。Onなんとかという関数名にするとプロパティビューのイベントタブのところに表示されるようになるので、ちょっと便利な裏機能としてCV.netでは昔から活用していました。その習慣がいまでも残っているので、だいたいOnなんとかという名前をつけています。
また、オブジェクト定義の直前にコメント文を書くと、プロパティビューの下にあるコメントという箇所にその内容が表示されるようになります。
合計計算をやり直さないといけない場合は、明細の数量、単価が変わった場合と、行が削除された場合なので、TextChangedイベントハンドラとRClickedイベントハンドラを修正します。
  Function OnTextChanged(e){
   e.Row.FlexTextBox5 = e.Row.FlexTextBox3*e.Row.FlexTextBox4;
   OnCountTotal(e);
  }
・・・・・
  Function OnRClicked(e){
   var i=popupMenu("現在行の上に挿入","現在行を削除");
   if (i==1){
    FlexView1.InsertRow(1,e.Row);
   }
   else if (i==2){
    FlexView1.DeleteRow(e.Row);
    OnCountTotal(e);
   }
  }
あとは、日付のデフォルト値が空白なので、今日の日付を代入しておきます。
 DateEdit DateEdit1 {
  X = 89;
  Y = 15;
  Width = 95;
  Height = 20;
  Value = sysdate();
 }
ところで、Biz/Designerでデザインをする際、FlexViewやSpreadなどは明細行が表示されていないので、とてもデザインしづらいのです。
そこで、FlexView1オブジェクト直下に、
  if ($DESIGNTIME){
   this << new CSVDocument << CSV{
    111,222,33,45,66
    111,222,33,45,66
    111,222,33,45,66
   };
  }
と記述すると、デザイン時のみ、ダミーの明細行が表示されるようになります。
こうするとデザインしやすくなるので、CV.netではFlexViewやSpreadなどを使う場合、デザイン時のみ走るコードを埋め込んでCRSを作成しています。
あとは、色などを変更すれば、以下のような画面が出来上がりです。


最後に、このCRSスクリプトの全ソースを掲載します。
----------------------------------------------------
Form Form2 {
 X = 0;
 Y = 0;
 Width = 510;
 Height = 460;
 BgColor = $CCCCFF;
 Label Label1 {
  X = 20;
  Y = 15;
  Width = 54;
  Height = 21;
  Value = "入力日";
  BgColor = $CCFFCC;
 }
 DateEdit DateEdit1 {
  X = 89;
  Y = 15;
  Width = 95;
  Height = 20;
  Value = sysdate();
 }
 Label Label2 {
  X = 20;
  Y = 42;
  Width = 67;
  Height = 20;
  Value = "顧客コード";
  BgColor = $CCFFCC;
 }
 ComboBox ComboBox1 {
  X = 89;
  Y = 42;
  Width = 326;
  Height = 19;
  ComboItem ComboItem1[0];
 }
 Label Label3 {
  X = 20;
  Y = 70;
  Width = 59;
  Height = 18;
  Value = "備考";
  BgColor = $CCFFCC;
 }
 TextBox TextBox1 {
  X = 89;
  Y = 70;
  Width = 404;
  Height = 18;
 }
 Label Label4 {
  X = 20;
  Y = 91;
  Width = 69;
  Height = 19;
  Value = "合計数量";
  BgColor = $CCFFCC;
 }
 TextBox:number TextBox2 {
  X = 89;
  Y = 91;
  Width = 80;
  Height = 18;
 }
 Label Label5 {
  X = 216;
  Y = 91;
  Width = 85;
  Height = 16;
  Value = "合計金額";
  BgColor = $CCFFCC;
 }
 TextBox:number TextBox3 {
  X = 302;
  Y = 91;
  Width = 108;
  Height = 19;
 }
 FlexView FlexView1 {
  X = 13;
  Y = 119;
  Width = 484;
  Height = 309;
  FlexRecord FlexRecord1 {
   FlexTextBox FlexTextBox1 {
    Title = "商品CD";
    Width = 80;
    TitleBgColor = $0000CC;
    TitleFgColor = 18;
    
   }
   FlexTextBox FlexTextBox2 {
    Title = "商品名";
    Width = 120;
    TitleBgColor = $0000CC;
    TitleFgColor = 18;
   }
   FlexTextBox:number FlexTextBox3 {
    Title = "単価";
    TitleBgColor = $0000CC;
    TitleFgColor = 18;
   }
   FlexTextBox:number FlexTextBox4 {
    Title = "数量";
    Width = 50;
    TitleBgColor = $0000CC;
    TitleFgColor = 18;
   }
   FlexLabel:number FlexTextBox5 {
    Title = "金額";
    TitleBgColor = $0000CC;
    TitleFgColor = 18;
   }
  }
  Function OnTitleDClicked(e){
   FlexView1.InsertRow(1);
  }
  Function OnRClicked(e){
   var i=popupMenu("現在行の上に挿入","現在行を削除");
   if (i==1){
    FlexView1.InsertRow(1,e.Row);
   }
   else if (i==2){
    FlexView1.DeleteRow(e.Row);
    OnCountTotal(e);
   }
  }
  Function OnTextChanged(e){
   e.Row.FlexTextBox5 = e.Row.FlexTextBox3*e.Row.FlexTextBox4;
   OnCountTotal(e);
  }
  Function OnCountTotal(e){
   var su=0;
   var kin=0;
   var crow=FlexView1.GetRow();
   while(!crow.End){
    su += crow.FlexTextBox4;
    kin += crow.FlexTextBox5;
    crow.MoveNext();
   }
   ^.TextBox2= su;
   ^.TextBox3= kin;
  }
  if ($DESIGNTIME){
   this << new CSVDocument << CSV{
    111,222,33,45,66
    111,222,33,45,66
    111,222,33,45,66
   };
  }
 }
 Button Button1 {
  X = 406;
  Y = 432;
  Width = 93;
  Height = 24;
  Title = "終了";
  Function OnTouch(e){
   //.Delete();
  }
 }
 if ( !$DESIGNTIME ) {
  /* ここに初期化処理を記述してください */
 }
}
----------------------------------------------------


BizDesginerでの開発2-002

2006年08月12日 19時26分15秒 | Weblog

まず、前の記事2-001のBizの画面を参考に左上から右下に順番にGUI部品を配置します。(表示内容等はデザイン画面でF2キーで直接修正できる)
【以下、GUI部品名とValue値かTitle値、オブジェクト名のリスト】
Label「入力日」(Label1)、DateEdit(DateEdit1)、Label「顧客コード」(Label2)、ComboBox(ComboBox1)、Label「備考」(Label3)、TextBox(TextBox1)、Label「合計数量」(Label4)、TextBox(TextBox2)、Label「合計金額」(Label5)、TextBox(TextBox3)、FlexView(FlexView1)、Button「終了」(Button1)。
各オブジェクトの位置とかサイズはだいたい適当に配置します。
FlexView1オブジェクトの中にもオブジェクトを定義しないといけませんが、FlexViewはいわゆるコンテナオブジェクトになっているため、オブジェクトビューからFlexVie1の下のFlexRecord1を選択します。


「子オブジェクトの挿入」を選び、FlexTextBoxを5個追加します。


そして、オブジェクトビューから、今追加したFlexTextBox1から5までのオブジェクトを選択してプロパティビューで表示タイトルを変更していきます。


プロパティビューのTitleに、"商品CD"、"商品名"、"単価"、"数量"、"金額"とFlexTextBox1から5までを変更します。Width値も適当に修正します。

これで画面はだいたい出来上がりました。

しかし実はここで根本的な問題があり、FlexViewを配置しただけでは、デフォルトでは行は1行もなく、行を増やすようなイベントも定義されてないので入力できないんです!
そこでFlexViewにちょっと細工をして、簡単に最終行追加、途中行挿入、行削除ができる機能を追加しておきます。
FlexView1をダブルクリックすると、スクリプトペインに移動します。
現在の状態ではこんなかんじで定義されているハズです。
 FlexView FlexView1 {
  X = 13;
  Y = 119;
  Width = 484;
  Height = 309;
  FlexRecord FlexRecord1 {
   FlexTextBox FlexTextBox1 {
    Title = "商品CD";
    Width = 80;
   }
   FlexTextBox FlexTextBox2 {
    Title = "商品名";
    Width = 120;
   }
   FlexTextBox:number FlexTextBox3 {
    Title = "単価";
   }
   FlexTextBox:number FlexTextBox4 {
    Title = "数量";
    Width = 50;
   }
   FlexTextBox:number FlexTextBox5 {
    Title = "金額";
   }
  }
                    
 } 
オレンジの色のあたりにコードを直接記述しましょう。
FlexView1のタイトル行をクリックしたら1行追加し(OnTitleDClicked)、入力行で右クリックすると(OnRClicked)、その行の上に1行挿入するか、選択行を削除するかのメニュー表示。
  Function OnTitleDClicked(e){
   FlexView1.InsertRow(1);
  }
  Function OnRClicked(e){
   var i=popupMenu("現在行の上に挿入","現在行を削除");
   if (i==1){
    FlexView1.InsertRow(1,e.Row);
   }
   else if (i==2){
    FlexView1.DeleteRow(e.Row);
   }
  }
これでFlexViewの列の中身には関係なく、行を追加したり削除したりできるようになりました。
これはCV.netの中で使っているやりかたです。今はCRSソースに直接記述していますが、同じような処理はどこでもやるので、CV.netは汎用的な処理としてClass化しています。(object名に左右されないやり方で、かつ行コピーなどの処理もやれるようにしている。汎用的な行コピーは多少処理が複雑になるのでここでは触れない)
あとは、Button1オブジェクトのOnTouchイベントに次のように記述します。
  Function OnTouch(e){
   //.Delete();
  }
ボタンを押されたらルートオブジェクト以下を全部Deleteして終了ということです。

次の回で計算部分と合計の再計算処理、あと数量や金額が現在StringになっているのでNumber型への変更などの細かい調整をやっていって終わりです。
(最後にこのCRSスクリプトのソースを全部のせます)
まだ全部説明していませんが、FlexViewなんてわかってみればすごく簡単です。
このように複数明細を入力させるような処理を実現するためには
1.Formオブジェクトの配列を使う
2.Spreadオブジェクトを使う
3.FlexViewオブジェクトを使う
という3通りありますが、CV.netではFlexViewがV4で新たに追加されたのを見て、Spreadオブジェクトのやり方から一気に全部のCRSソースをFlexViewになおしました。未だにFormやSpreadでやっているCRSスクリプトがあるとすれば、それはFlexViewオブジェクトの使い方を知らないか、古い過去のソースを引きずっているからです。
FlexViewオブジェクトのほうがきれいで細かい制御が可能になっています。


BizDesginerでの開発2-001

2006年08月12日 15時12分00秒 | Weblog

今回から始まるシリーズでは、もうちょっとましな入力プログラムを作っていきます。
   (途中段階のイメージ)

日付、顧客コード、備考を入力し、明細に商品CD、商品名、単価、数量、金額を入れるようなヘッダ、明細形式の一般的な伝票入力プログラムです。
これくらいの画面であれば、Biz/Designerでほんの5分程度で作ることが可能です。
つくるロジック部分。
1.明細の金額は数量*単価を自動でセット。ヘッダの合計数量、合計金額も自動
2.明細は新規行を最下行にもつくれるし、途中にも挿入できる。また行削除もできる
3.終了ボタンを押したら、Biz/Browserを終了。
まずは、ここまでの画面とUIロジックを作るところまで。
その後、見栄えの調整で、レイアウトを整えたり、色やフォントを変えたりしてみます。

このプログラムを作りながら思ったこと。
慣れてる人なら見栄えの調整まで全部一気にやって10分ぐらいでできるんですが、ロジックつくる部分と見栄えの調整のやり方の説明を同時に書くとややこしくなります。
それで、まずはロジックがいかに簡単に出来るかという説明を1通り。次にレイアウトなどの調整がいかに簡単にできるかの説明を1通りしていきます。
そんで、作りながらBizにはこーゆーことを実現するのにどのGUI部品を選択するのがよいのか、なんでこんな形でイベントハンドラを定義するのか、ということをCV.net的観点で独断的に説明していきます。もちろん、いろんな作り方があるのでここで説明することが絶対ではありませんよ。
しかし、これから説明するやり方が私の知る限り一番簡単で、使い勝手がよいと思う方法です。


BizDesginerでの開発1-001

2006年08月11日 22時57分44秒 | Weblog

簡単なBiz/Designerでの開発の流れを説明します。
(Biz/Designer , Biz/Browserの評価版ダウンロード)

まず,Biz/Designerを起動し、[ファイル]-[新規プロジェクト]で[空のプロジェクト]を選択。
プロジェクト名に「test1」などと入力。


これでまっさら状態のプロジェクトができました。(^_^)
次にフォームを1個追加してみます。


そしてテキトーにクラスセレクタからオブジェクトをえらんで配置します。

今回はButton、Label、TextBoxを1個づつ選んでForm上においてみます。

こんな感じで。
背景色とかはBgColorなどのプロパティを変更。
ちょっとだけButtonオブジェクトのOnTouchイベントにコードを書きます。
 Button Button1 {
  X = 199;
  Y = 54;
  Width = 151;
  Height = 27;
  Title = "これは終了ボタン";
  Function OnTouch( e ) {
   /* OnTouch イベントハンドラ */
   /* ここにイベント処理を記述してください */
   //.Delete();
  }
 }
つまりボタンを押したら終了というコード。
全部終わったら、[ファイル]-[上書き保存]をする。(いったん保存しないと赤ボタンのテスト実行ができない!)
これで実行すると、Biz/Browserが起動し、実際に今1分ぐらいで思いついたCRSスクリプトが動きます。

こんなかんじでCRSスクリプトを書いて動かします。
....と、ここまではすごく単純でお手軽なイメージでCRSプログラムができるようなことを書きましたが、実際にはこんな何に使うのかわからんようなCRSスクリプトを書く人間はいません。
次回はもうちょっと使えそうなCRSプログラムをしていきます。