goo blog サービス終了のお知らせ 

Biz/Browserを愛でる会

我々が感動したことをみなさまに味わって頂きたい、それがBiz/Browserを愛でる会の原点です。(入会員募集!)

Biz/Browserとサーバとの通信(佐藤)

2007-01-23 18:31:04 | プログラミング応用講座(佐藤)
Biz/Browserにサーバからのデータを受け取る場合、たとえば異なる2種類のデータを受け取りたい場合にはどうしたらよいだろうか?

問題:CSVデータと(処理時間などの)追加情報。このように異なる2種類のデータをうまく受けとりたい



CSVデータは通常のResponse.Bodyとして取得すればよいのだが、追加情報はどう渡すか?

X 誤り:追加情報とCSVデータをResponse.Bodyに混在させ、Biz側でまた分割するようなプログラムを作る。

Biz/Browserプログラム初心者ならば、このような作り方をするかもしれない。
しかし、それよりももっとよい方法がある。
Biz/BrowserのhttpResponse ClassにはgetHeader()メソッドがあるので、それを使って、ヘッダに埋め込んで受け渡す。

解答:CSVデータはResponse.Bodyとしてそのまま受け取る。
(処理時間などの)追加情報はGetHeader()メソッドにて受けとる。

このようにすれば、後で仕様変更があって、受け渡すデータが増えた場合でもgetHeader()の処理を1行追加すればよいだけとなる。
ソースの可読性、カスタマイズ対応の柔軟性、全体的なレスポンス
すべてに効率のよい解決策である。

ちなみに、
「追加情報とCSVデータをResponse.Bodyに混在させ、Biz側でまた分割するようなプログラム」
を作ってしまった場合、仕様変更があった場合、
「追加情報1と追加情報2とCSVデータをResponse.Bodyに混在させ、Biz側でまた分割するようなプログラム」
を組まなくてはならなくなり、ソースの可読性、カスタマイズ対応の柔軟性、全体的なレスポンス全てにおいてあまり上手ではない解決策である。
(さらに追加情報があった場合を考えれば自明である...)


Biz/Browser、Biz/Designerはあくまでもツールであり、それを生かすのは開発者である。ゆえに、Biz/Browserの特徴、Classの仕様、3Tierシステムの特性などを熟知した上で、実際のアプリケーション構築をすることが重要になってくる。

何をつかうか(Biz/Browser、Biz/Designerというツールの採用)よりも、どのようにつくるか(アプリケーション構築のノウハウ)で作ったアプリケーションに差がでてくる。

この辺りのノウハウをうまく伝えることができれば、開発者が率先して、Biz/Browser、Biz/Designerをもっと使っていきたいと思うだろう。



Biz/Browserで受け取るサーバデータ(佐藤)

2007-01-18 18:20:42 | プログラミング応用講座(佐藤)
Biz/Browserでサーバから受け取るデータフォーマットは大きくは2種類。
CSVデータかXMLデータか。
それぞれのメリットデメリットは次の通り。
・CSVデータ
    (メリット)データ形式が単純なため、通信料が必要最低限ですむ。
    (デメリット)2次元表形式のデータしかあらわせない。データレイアウトをあわせる必要がある。いくつかやり取りできないコードがある(,や"や改行)(CV.netではサーバアクセス共通クラスに必ずコード変換を通すことで回避し使用可能にしている。このようにアプリケーション側で対応するには作りこみが必要)
・XMLデータ
    (メリット)2次元の表以外のデータでも可能。レイアウト変更に柔軟に対応できる。
    (デメリット)通信量が大きくなってしまう。CV.netで過去テストしたケースでは実データ300件を比較し2-3倍程度になる。

もしBiz/Browserでクローズドな業務システムのみであればCSVデータでもよいかもしれない。
しかし昨今のWeb APIの流れを見てみると、SOAP、XMLという流れが数年前で、現在はREST、XMLとなってきている(あくまでも一般に開放されているWEB APIの話)。
将来的に他社のWebAPIとも連携できるようなシステムにしていくには、データフォーマットはXMLにあわせていったほうがよい。

そして実は業務システムと公開WEB APIをシームレスに接続するようなアプリケーションはBiz/Browserのような3Tierシステムでしか実現できない。

サーバを仮想化させクラサバのシステムをメタフレーム等のソフトで動かし、WEB化といっている事例もある。が、そのようなシステムは今述べたようなシステムは構築不可能になってくる。

WEB2.0,SOAP,REST,XML,SaaS,SOA....これらのキーワードが意味するところは、UI画面とサーバロジックの分離であり、それが徐々に底辺部分で浸透していっている。
浴槽に水を貯めるように、これがある時点を越えるとその波がいっせいに溢れ出して来る。
それが今年である。

であるので、上のような理由で昨年末からCV.netもCSVとXML両方のインターフェースをもつようにしたのである。


[Tips : Biz/BrowserにおけるCSVドキュメントの扱い。列名を使うメリット]
CSVDocument Classは、通常そのまま扱うと、列名なしの状態になってしまう。この状態ではデータレイアウトを固定にせざるを得ない。
CSVのこのデメリットを回避するために、setColumnName()を使って列名つきのCSVDocumentにする。
そうすると、Ver4.1.2から追加されたメソッドgetCellbyName(),setCellbyName()によって列名でのアクセスが可能になりある程度データレイアウトに依存しない作りかたが可能になる。

[Tips : Biz/Browserで通信するCSVデータの中に,"改行などを含めたい場合]
これはサーバ側、Biz側双方で同じ変換ロジックを使うことで回避する。例えば以下のようなコード(CV.netのclasssatoo.carより抜粋)

        if(p_flag == 0){ /* Biz側→サーバー */
            ret_str.replace(",",String.fromCharCode(27));
            ret_str.replace(""",String.fromCharCode(28));
            ret_str.replace(String.fromCharCode(10),String.fromCharCode(29));
            ret_str.replace(String.fromCharCode(13),String.fromCharCode(30));
        }
        else if(p_flag == 1){ /* サーバー→Biz */
            ret_str.replace(String.fromCharCode(27), ",");
            ret_str.replace(String.fromCharCode(28), """);
            ret_str.replace(String.fromCharCode(29), String.fromCharCode(10));
            ret_str.replace(String.fromCharCode(30), String.fromCharCode(13));
        }
追記:いうまでもないことだが、この変換はCSVDocumentにしてから中の1cell単位に変換をかけないと意味ない。


FlexViewの扱い(佐藤)

2006-12-12 21:56:53 | プログラミング応用講座(佐藤)
「Bizの宝箱」にアップされている技術レポートの「FlexView資料 (FlexViewTechnical.pdf)」はよくできており、わかりやすい。
表形式のデータの表現方法は、以前 Blogにて書いたように、
1.Formクラスの配列を使う
2.Spreadクラスを使う
3.FlexViewクラスを使う
の3通り。
それを踏まえつつ、FlexViewを使うの に参考になる。

ただし、FlexViewの表示クラスについては...

実は、FlexView関係のクラスには、主にFlexItemからの派生クラスとFlexCellから派生クラスの2つがある。
表示するデータ=FlexItem派生クラスに関しては上記資料に記述されているが、保存される個々のCell= FlexCell派生クラスに関しては少ししか触れてない。
<FlexItem派生クラス>


<FlexCell派生クラス>


FlexItem派生クラスでなぜ同じオブジェクト名を名づけてはいけないかという理由 が、この特殊なデータの持ち方にある。
クラス定義上はFlexTextBoxクラスであっても、
var row = FlexView.GetRow(0);
var data = row.FlexTextBox1.Value;
とした場合のdata変数がさしているのは、FlexTextBoxCellクラス となる。
<FlexItemクラスによる表示データ保持イメージ>
FlexViewオブジェクト
   ---> FlexRecord FlexTextBox1, FlexTextBox2, FlexTextBox3
    (単一行のデータ。Rowset,Columnsetなどの下位にも配置可能)

<FlexCellクラスによる実データ保持イメージ>
FlexViewオブジェク ト
   ---> FlexRow1行目 FlexTextBox1, FlexTextBox2, FlexTextBox3
   ---> FlexRow2行目 FlexTextBox1, FlexTextBox2, FlexTextBox3
   ---> FlexRow3行目 FlexTextBox1, FlexTextBox2, FlexTextBox3
   ---> (... 複数行。必ずFlexRowの直下)

FlexCell派生クラスは、固有のCellデータの保持に特化している。
標準のプロパティでは、 Value,FgColor,BgColor,Dataの4つの値を保持可能である。




Biz/Browser によるファイルアップロード(佐藤)

2006-12-01 12:02:14 | プログラミング応用講座(佐藤)

一般的にファイルアップロードはFTPで行うが、これをBiz/Browserで行うことによって以下のメリットが生まれる。
・FTPクライアントソフトが不要になる
・FTPのパスワードを教える必要がない(パスワード漏洩の予防になる)
・FTPのポートを不特定多数に開放する必要がない(セキュリティがより強固)
・Bizアプリケーションの機能の一部として組み込むことができる(操作性、機能の向上)

<例1:商品画像のアップロード>
エンドユーザがドラッグ&ドロップにより画像をアップロードすることができる



<例2:CRS,QFMファイルのアップロード>
外注先などに直接サーバ上にBiz/Designerで作成したCRSやPrintStreamのQFMファイルをアップロードさせる。(完全に同一環境での検証が可能)




Biz側CRSでは以下のようにしている。
Base64エンコードを使って実現。ASP.NETサーバ側ではBASE64でデコードしてデータを取り出す。

 Function AspxUpload(fname, f_data, v_ht, v_design){
 /* ===================================================
  ■関数 AspxUpload = .Netサーバーへファイルをアップロードする
   引数1:I String = ファイル名
   引数2:I (Readメソッドを持つオブジェクト) = D&Dのe.DataやFileオブジェクトなど
   引数3:I String = nullか "1"か"souko"か"tenpo"=HHT用Uploadパラメータ
   引数4:I String = nullか "CRS"か"PSS"=Biz/Designer用Uploadパラメータ
   戻値  0=成功, -1=失敗
  =================================================== */
  var fn2 = new string(fname).split("");
  var v_enc = new Base64Encoder(f_data).Read();
  var session = AspxFindHTTPSession();
  var req = session.createRequest(AspxPath+AspxAddPath+"uploaddata.aspx");
  req.addParam("rd",ClassSatoo.AspxRandId);
  req.addParam("fname",fn2[fn2.length-1]);
  req.addParam("file",v_enc);
  if (v_ht!= null){
   if (v_ht=="img"){
    req.addParam("img",v_ht);
   } else {
    req.addParam("hht",v_ht);
   }
  }
  if (v_design!= null){
   req.addParam("DIR",v_design);
  }
  var res = session.post(req);
  var res2 = new string(res).toUpperCase();
  if (find(res2,"OK",0)>=0){
   Classsatoo.CrsSessionLastDate=sysdate();
   return 0;
  }
  return -1;
 }


FelicaとBiz/Browserの連動(佐藤)

2006-11-21 17:21:32 | プログラミング応用講座(佐藤)
FelicaとBiz/Browserを連動するには2通り方法がある。
1.Biz用のDLLを作成
2.外部EXEとBiz/Browserを連携
このうち2番目の方法でCV.netはFelica連携を実現している。
1番目の方法の場合にはレジストリにDLLを登録する必要があるためである。
Biz/Browserのソースからは以下のように外部イベントを使用して呼び出している。
        /* Felica読取可能にする */
        var wrk_ev = new EventSender;
        try{
            wrk_ev.PostExternalEvent("cvnet_felica","biz","Start","");
        }
        catch(e){
            MessageBox("Pasoriが立ち上がっておりません。n終了します。");
        }
        /* Felicaにカードがおかれたらイベントを取得する */
    EventListener bizfelica{
     /* CvnetFelica.exeからのイベントを受け取る */
            Service="cvnet_biz";
            PortID="biz2"; /* PortIDはなんでもよい */
            Function OnCardSet(e){ /* FelicaID専用 */
              /* カードがおかれたときの処理 ログインなど  e.param にFelicaのIDが入っている */
            }
            Function OnCardReset(e){
              /* カードがはずされたときの処理 通常なにもしない */
            }
            if(!$DESIGNTIME){
                try{
                    StartListen();
                }
                catch(e){
                }
            }
        }

Biz/Browserの技術者が見たらお分かりのとおり、単純にイベントリスナーで受け取るだけである。
受け取ったe.paramにFelica固有のIDが入っているので、それをアプリ側で利用する。
(例えばLOGINの変わりにFelicaを使えば、ID,PASSで認証させるよりはるかにセキュリティが高くなる。セキュリティ意識の高くないユーザはID=社員ID,PASS=同じなどの設定で使ってしまいがち。Felicaなら確実に一意のIDが振られかつカードにはそのIDは印字されていないのでユーザが自分のIDを知ることなく本人認証させることが可能)
CVnetFelica.exeはエンドユーザに販売するアプリケーションに組み込まない限りフリーとしている。
ダウンロード先は以下のとおり。
(Biz/BrowserとFelicaのドライバ両方インストール済の環境でなければ動作しない)
http://www.dtpnet.jp/download/CvnetFelica.exe
MD5チェックサム
(308bd9c93b5cc2884af4ef2280cad5ea  CvnetFelica.exe)
236 KB (241,664 バイト) Win2K,WinXP両用


JAVAと.NETの3Tierシステム(佐藤)

2006-10-11 16:39:22 | プログラミング応用講座(佐藤)

一般的な3Tierシステムは、以下のような構造を持つ

クライアントにはBiz/Browserを前提として、サーバ側はJAVAか.NETかの選択に事実上なってくる。
まず、JAVAの場合だが、元々J2SEという規格があり、そこからサーバ用に派生したのがJ2EEという規格である。また、JDBCはJAVA自体の実装とは別に各DBMSベンダーから提供されているのが普通である。
そのJ2EEの中にまたEJBという規格があり、EJBにもまた歴史があり、EJB 2.1があまりにも重すぎる規格であったため、軽量JAVAというものがでてきたりした。その反省をふまえEJB3.0という規格になって現在に至るわけだが、まずEJBコンテナを使う場合のアーキテクチャを以下に示す。

Biz/Browserを使った3Tierシステム(Java : EJBコンテナ EJB2.0or3.0)


EJBコンテナを使った場合、このような形になるが、EJBはインターフェースが変わると各モジュールが連鎖的に変更する必要がある。
また、EJBコンポーネント1つくるのに下の5つが必要になる。
・Enterprise Beanクラス
・コンポーネント・インターフェイス
・ホーム・インターフェイス
・EJB DDファイル
・ベンダー固有のEJB DDファイル
このようなことから、DI(依存性の注入)という方法が注目されるようになった。
DIxAOPコンテナを使った場合、下のようになる。

Biz/Browserを使った3Tierシステム(Java : DIxAOPコンテナ)


JAVAを使う場合には、通常この2つのうちのどちらかになる。(プラス自社or他社のフレームワーク)
次に、.NETを使った場合のアーキテクチャを下に示す。

Biz/Browserを使った3Tierシステム(.NET)

.NET Frameworkは現実的にJAVAをより進化させた形で登場したことから、JAVAではJ2SE,J2EE(サーブレット,JSP,EJB...),JDBC,DIコンポーネントなどの技術を組み合わせで使わなければならないものが、.NET Frameworkという統一された形で提供されています。
そのため、ビジネスロジック層の記述が非常に楽になっており、配布も単純にコピーするだけで動作させることができます。
.NETのメリットは
・ビジネスロジックの作りやすさ
・配布orバージョンアップのしやすさ
・OS,Webサーバと統合されているためパフォーマンスがよい
ということです。

私は2000年ぐらいに、サーバ系プログラムをJAVAのサーブレットで組んだ経験がありますが、当時はサーバ系はJAVAしか選択枝がないのが現実でした。
しかし、.NETが1.0,1.1,2.0と急速にバージョンアップをし、言語仕様、動作アーキテクチャなどを検討した結果、現在.NETを採用しています。

もちろん、技術的なもの以外の要素もあるので、一概に.NETがよいというわけではありませんが、おすすめは.NETで、JAVAであれば、DIコンテナを使う方法がよいと思います。
DIのよさに関しては、いろんな人が意見を言っています。
Spring Framework」開発者は、「EJBは存在自体が間違いだった」と言い切ってます。Entity Beansもだめだといってますので、J2EEのほとんど全部否定しているようなものです。
私もこの意見には賛成で、J2EEの規格はあまりにも後付で頭でっかちの仕様のような気がします。EJB3.0でやっとまともになってきた感じですが、まだまだ仕様が確定しきれてない部分もあるように思います。


Bizの宝箱(2006/09/06)TIPS追加について

2006-09-08 16:19:52 | プログラミング応用講座(佐藤)
http://support.axissoft.co.jp/support/freearea/jsp/index.html
[TIPS集] Biz/Browser・Biz/Designer
Spread、TabFrame/TabForm にTIPSを追加

配列化されたTabForm上でのSpreadシートに対するSetLabelの注意点
[内容]
配列化されたTabForm上でSpreadSheetに対するSetLabelを行うと、
最後に追加したLabelの内容が0番目の配列のLabelにも反映されてしまう
---------------------------------
これは1ヶ月ほど前、DTPの開発から投げた質問と回答そのものです。

TabForm配列中でSpreadオブジェクトを使用する場合の注意点です。
実際には、以下の在庫問い合わせ画面で、商品を選択する度にどんどんTABが追加されていくのですが、SpreadのLabelに表示されている文字列がおかしかったのです。


最初のTABのみに不具合が発生していたので、サポートから指摘されるまで気づきませんでした。
とりあえず、CRSスクリプトを部分的にわけることで対応しました。
もし、同じような画面をつくられるのであれば、このようなこともあるということで。


Biz/BrowserとAPサーバ間のI/Fについて2(佐藤)

2006-09-06 23:13:17 | プログラミング応用講座(佐藤)

BizからSQL文を直接発行するというやり方を前回述べた。
クラサバと同じセキュリティレベルで使うアプリケーションの場合はこれで問題ないが、SQL文をBiz側に記述できないケースも当然ある。
たとえば一般顧客にBizを使わせる場合やASPサービスとしてBizを展開する場合などである。
しかし、この場合もテスト段階ではBizでSQL文を記述し、SQL文が確定したらサーバ側に埋め込めばよい。
1.Biz側でSQL文を記述しながらテスト
    var wrk_para=new array;
    wrk_para[0] = new string(^.CodeNen.OnGet());
    wrk_para[1] = new string(^.CodeTenpo1.OnGet());
    wrk_para[1] = new string(^.CodeTenpo2.OnGet());
    var ret_csv;
    ret_csv= ClassSatoo.AspxSqlQuery("select * from HC$TEST where 年月=:1 and 店舗CD between :1 and :2", wrk_para, "cvnettana003.qfm");
2.SQL文が確定したらサーバ側に埋め込む
  [Biz側プログラム]
    var wrk_para=new array;
    wrk_para[0] = new string(^.CodeNen.OnGet());
    wrk_para[1] = new string(^.CodeTenpo1.OnGet());
    wrk_para[1] = new string(^.CodeTenpo2.OnGet());
    var ret_csv;
    ret_csv= ClassSatoo.AspxSqlQuery("_bizsql01", wrk_para, "cvnettana003.qfm");
  [サーバ側プログラム]
   .....
   if (qs = "_bzsql01"){
    qs="select * from HC$TEST where 年月=:1 and 店舗CD between :1 and :2";
   }
   .....
   (SQL文を実行し、結果をBizに返す)

こうすれば、開発効率を下げず、かつSQL文をBiz側CRSに記述せずに済む。
結果的にCSVデータをBizに返すような処理であれば、サーバ側I/Fは基本的に1つでよくなる。


Biz/BrowserとAPサーバ間のI/Fについて(佐藤)

2006-09-04 22:59:15 | プログラミング応用講座(佐藤)

既存のC/Sシステムを3Tierに移行する際の一般的な問題点として以下のものがある
1.LogicとUIがPG中に混在しているため、そのままLogicとUIを3Tierに分解した場合やりとりが頻繁に発生してしまう。(→レスポンスの悪化
2.ロック制御はクラサバの場合DBの機能に依存しているため、そのままでは排他制御(楽観的ロック、悲観的ロック)が実現できない。(→機能の低下
3.Logic層のPG言語とUI層のPG言語が異なるため、それぞれのスキルが必要。かつ工数が増える(→生産性の低下)  
これをいかに解決するか?ということが課題である。
【生産性の低下の問題】
Biz/Designerは生産性が高い。それに対しサーバ側の開発ツールは一般的に生産性が低い。


つまり、Biz/Browserだけでほとんどのプログラムが作れれば生産性が高くなるのではないか?というのが最初の着想。
たとえば、通常のクラサバでは、クライアントのプログラムはLANを通してDBサーバと信頼された通信を確立しているものとして、SQL文を発行している。
この考え方をBizとアプリケーションサーバ(APサーバ)、DBサーバに当てはめてみると、BizとAPサーバが信頼された通信が確立されていれば、APサーバを通してDBサーバに対してSQL文が発行され、戻されたデータセットがAPサーバを通してBizに返されればいいのではないか?(この場合のSQL文はselect文)


無条件にSQL文が実行されると危険であるため、必ずloginさせるようにする。HTTPSなどのセキュアな通信と組み合わせればこれで十分である。

この場合のメリットは他にもある。Biz/BrowserでほとんどのSQL文が発行可能にすることで、ユーザにBiz/Browserの画面のみのプロトタイプを見せ、そのままロジックをSQL文で記述すれば、究極のプロトタイプ開発ができてしまう。


BizからPrintStreamを呼び出す(佐藤)

2006-08-31 21:30:34 | プログラミング応用講座(佐藤)

BizとPrintStreamの連携例

CV.netの場合はSQL文を直接発行しPrintStreamを起動する場合、下記のようにする。(CV.netの場合、ログイン情報などのテーブルはBiz側からアクセス不可にしてあるので、SQLで呼び出せるのはアプリケーションに許可されたテーブルのみ)
----------------------------------------
    SatooPrintStreamDocument pss;
    pss.PreviewFlg=cvnet.Preview;
    var pp = cvnet.DispBar();
    var wrk_para=new array;
    wrk_para[0] = new string(^.CodeHin1.OnGet());
    wrk_para[1] = new string(^.CodeHin2.OnGet());
    var wrk_sql = "select A.社員CD,A.名前,'__DATA__'||A.携帯TEL 画像";
    wrk_sql += ",A.店舗CD";
    wrk_sql += ",NVL((select H.得意先名 from HC$master_tokui H where H.得意先CD=A.店舗CD),'.') 店舗名";
    wrk_sql += ",NVL((Select 自社名 From HC$MASTER_SYSKANRI where rownum<2),'.') 自社名";
    wrk_sql += " from HC$master_shain A where A.社員CD between :1 and :2 order by A.社員CD";
    var qfm_file = "cvnetfelica.qfm";
    var ret_csv = ClassSatoo.AspxSqlQuery(wrk_sql,wrk_para,qfm_file); /* ① */
    total_cnt = ret_csv.GetCell(1,0);
    if (total_cnt<=0){
     ^.OnMess2("印刷データがありませんでした");
     pp.popupClose();
     return;
    }
    pss.AddUrl(ClassSatoo.AspxPath+ ret_csv.GetCell(0,0)+"/000000[01-99].pss",ret_csv.GetCell(1,0)); /* ② */
    pp.popupClose();
----------------------------------------
①のClassSatoo.AspxSqlQuery(wrk_sql,wrk_para,qfm_file) で
SQL文、パラメータ、サーバ上のqfmファイル名を指定する
②のpss.AddUrl()で スプールファイルのダウンロード(とclass中で表示)

例えばこんな感じの帳票が印刷される。(全部で191ページ。これをDocクラスのみで実装するとかなり重くなる)


サーバ側、Biz側両方で汎用的に使えるモジュールを用意しておくことで、Biz側のSQL文とPrintStreamのフォームレイアウトを作るだけでどんな帳票でも作成できてしまう。

もし、現在帳票ごとにサーバもBizも1から作りこんでいるのであれば、ご参考にしてください。こんなやり方もあるということで。