2009年10月28日

(4)プログラム変更 その3


・TClientDataSetの一部フィールド定義を置き換え


TStringFieldをTWideStringFieldに置き換えを行う。
IDEのフォーム上で、定義を一つ一つ確認しながらおこなう。

もしかしたら、
http://homepage1.nifty.com/ht_deko/junkbox.html#DFMCONVEXP
を使ったら、効率的にできるのではないかと思うが、未確認。

(4)プログラム変更 その2

・IBXからDBXへの置き換え

1)データベースコンポ
TIBDataBaseと同じユニットに、TSQLConnectionコンポーネント貼り付け。
TIBDataBaseの名前を変更。TSQLConnectionの名前に、もともとのTIBDataBaseの
名前を変更(特にこだわらなくてもよいが、修正の手間が若干少なくなる)

関連した部分の修正。
DBのOpen/close、トランザクション関係は、メソッド化してあるので、関連メソッドのコードを
書き換え(下記コード参照。下記以外にも、DBOpenイベントで設定情報をiniから読み込ん
でいる処理などがあるが、省略。3層スタイルC/S作成術参照
type
  TDMDataBase = class(TDataModule)
   〜〜
   DB: TSQLConnection;
   〜〜
  private
    FDBXTran : TDBXTransaction; //追加
  public
    procedure DBOpen;
    procedure DBClose;
    function IsDBOpen: boolean;
    procedure TrnStart;
    procedure TrnCommit;
    procedure TrnRollBack;
    procedure TrnCommitRetaining;
    function InTrn: boolean;
  end;
~~~~~~
procedure TDMDataBase.DBOpen;
begin
  if not IsDBOpen then    DB.Open;
end;
function TDMDataBase.IsDBOpen: boolean;
begin
  result := DB.Connected;
end;
procedure TDMDataBase.DBClose;
begin
  DB.Close;
end;
function TDMDataBase.InTrn: boolean;
begin
  // result := Trn.InTransaction;
  result := DB.InTransaction;
end;
procedure TDMDataBase.TrnCommit;
begin
  //  Trn.Commit();
  DB.CommitFreeAndNil( FDBXTran );
end;
procedure TDMDataBase.TrnCommitRetaining;
begin
  //  Trn.CommitRetaining();
end;
procedure TDMDataBase.TrnRollBack;
begin
//  Trn.RollBack();
  DB.RollbackFreeAndNil( FDBXTran );
end;
procedure TDMDataBase.TrnStart;
begin
//  Trn.StartTransaction;
  FDBXTran := DB.BeginTransaction( TDBXIsolations.ReadCommitted );
end;

2)TIBQueryからTSQLQueryへの置き換え
(今回のアプリでは、SQL文は、コンポーネントに記述しているので、
この方法をとっているアプリについての手法となる)

失敗するとDelphiで開けなくなるので、バックアップをとってから行う。
TIBQueryのある、*.dfmと*.pasファイルをテキストエディタで開く。
旧定義
   DB: TIBDataBase;
旧定義
   DB: TSQLConnection;
とする。

・dfmファイルの変更
TIBQueryの定義を変更
 object QryShopInfo: TIBQuery
    Database = DMDataBase.DB
    Transaction = DMDataBase.Trn
となっている部分を
object QryShopInfo: TSQLQuery
  SQLConnection = DMDataBase.DB
クラス定義の変更 TIBQuery=>TSQLQuery
プロパティ名変更 Database=>SQLConnection
Transactionの行は削除

と変更。
すべてファイル内すべて置き換える。

・pasファイルの変更
クラス定義の変更 TIBQuery=>TSQLQuery
 (フィールド定義を生成している場合、再生成したほうがよいと思われる(未確認))

・IDEで開くことができるか確認
すべての変更を終えたら、Delphiで開くことができるか確認する。
修正ミスがあると、フォームが開けなくなることがあるので注意が必要

・ParamsプロパティのDatatypeの設定
DBXにおいて、paramsのDataTypeは、ftUnknownが許されないので設定する。
IBXでは、許されていたので、元のソースは、すべてftUnknownのままだったので、
すべて再設定。テーブルのフィールド型との同期も必要で結構面倒です。何かよい
方法を考える必要はありかなと思います(今回の宿題です)。


補足)
IDEでなく、エディタで作業するのは、複数ファイル並べて作業ができ便利なためで、
上記作業をIDEのエディタで1ファイルずつ開いて行う方法で可能だと思う。

補足)
”2)TIBQueryからTSQLQueryへの置き換えで使用しているテクニックで、
エディタで、dfmファイルを修正していく方法は、BDEからIBXやDBXに置き換える
ケースでも使えます。
弊社で行うときは、事前にdfmファイルを変更し、その後、コンパイル・テストで、細
かい変更箇所をつぶしていく方法をとっています。

(4)プログラム変更 その1

下記手順で修正を行う。

・プロジェクトファイルを、Del2010で開く。
 プロジェクトファイルをDel2010に移行(Delまかせ)。
 パッケージプロジェクトを先に行ったほうがよい。
・通信コンポーネントのANSI化(今回のターゲットプログラムには、関係ないがのちのち
 使用するので)(*1)
・IBXからDBXへの置き換えを行う(後述
・TClientDataSetの一部フィールド定義を置き換え(後述)
・プロジェクト再構築
・テスト確認

今回の対象プログラムの、”店頭受注登録プログラム”については、ANSI文字列使用部分するコードが
なかったので、この置き換えはなかった。電話受注登録プログラムなどでは、作業が必要になると思わ
れる。

以上

(*1)
 電話受注登録プログラムで使用している。着信電話番号をターミナルアダプタから取得
 するために、シリアル通信を行っていて、通信部分をネットでフリー公開されているコンポー
 ネントを利用させてもらっている。Del2010では、Varchar,Charは、UNICODEとなって
 いる。通信は、ANSI CHARなので、定義等を変更。

(3)データベース移行 その2

2)データ移行

新旧DBとも、IBXを使用。
DBXのTSQLQueryは、ParamsのDataTypeを設定する必要があり、下記のような汎用的な
処理の適用が難しいと考え、IBXのTIBQueryを採用。
IBXのTIBQueryで行えば、値のコピーを基本的に
          aDstQry.Params[i].Value := aSrcQry.FieldByName(f).Value;
で行える。
特に問題なく完了。

・大まかな処理概要とポイント

begin
  try
    //新旧DBオープン
    {テーブル数文繰り返し}
    begin
      try
        //新DBのトランザクションスタート
        //対象新テーブルへのInsertクエリを、QryInsに設定
        //対象新テーブルのデータを全削除(再処理のため)

        //QrySelに旧テーブルデータのSelect文を設定し、オープン
        while not QrySel.Eof do
        begin
          ParamSet(QrySel, QryIns);  //後述
          QryIns.ExecSQL;
          QrySel.Next;
        end;

        //QrySelクローズ
        //トランザクションコミット

      except
        //エラー処理
      end;
    end;

    //新旧DBクローズ
  except
     //エラー処理
  end;
end;



procedure TBaseDM.ParamSet(var aSrcQry, aDstQry: TIBQuery);
var   i : integer;    f : string;
begin
  try
    for i := 0 to aDstQry.Params.Count - 1 do
    begin
      f := aDstQry.Params[i].Name;
      if Nil <> aSrcQry.FindField(f) then
      begin
        if aDstQry.Params[i].DataType = ftTimeStamp then
        begin
          if aSrcQry.FieldByName(f).IsNull then
            aDstQry.Params[i].Clear
          else
            aDstQry.Params[i].AsDateTime
                              := aSrcQry.FieldByName(f).AsDateTime;
        end
        else
          aDstQry.Params[i].Value := aSrcQry.FieldByName(f).Value;
      end;
    end;
  except
    raise;
  end;
end;

(3)データベース移行 その1

1)
UTF8のデータベースを作成する。
 下記ツールを使用
  IBExpert personal Edition
  IBConsole for Windows (Unicode Edition)
     どちらも、テーブル名、フィールド名に漢字を使用している場合、うまくいかないケースが
  出るので、場面場面で使い分ける。
  うまくいかないのは、IBXを使用してるからと推測される(調査中)

・現DB(SJIS)のメタデータを抽出し、スクリプトファイルとして保存(IBExpert使用)
・スクリプトファイル中のCharset指定で、SJISを指定している部分を、UTF-8に置き
 換え(エディタ使用)
・DefaultChar=UTF8のデータベースを作成(IBExpert)
・変換後のクエリを、DefaultChar=UTF8のデータベースに対して実行(IBExpert)
・実行結果確認(IBConsole)

 *UTF8のデータベースについて、IBExpertでは、テーブル名・フィールド名が漢字になって
  いると文字化けしてしまう。(テーブル詳細情報は、うまく表示できているので設定がおかしい
  のではないと思うが。。。)
 *IBConsoleについては、テーブル名・フィールド名については、表示できるが、データの
  グリッド表示がうまくいかない。これは、IBXとDBGirdの組み合わせで同様の現象がおき
  たので、IBXが問題と思う。

(2)前準備

・情報収集
 下記サイトで事前に勉強させていただきました。ありがとうございました。
  http://totonica.s41.xrea.com/doc/delphi_tiburon/index.htm
  http://homepage1.nifty.com/ht_deko/techalgo.html

(1)対象システム情報

・対象システム情報
 宅配業者向け電話受注システム。CTI機能あり。
 電話着信、電話受注登録、店頭受注登録、店舗管理、本部管理の6本のプログラムからなる。
 とりあえず、プログラム規模の小さい”店頭受注登録”プログラムをターゲットとし、マイグレーションを行うこととする。その他のプログラムは、後に順次行う。

・開発言語
 Delphi2007で開発。今回、Dlphi2010にマイグレーション。

・データベース
 FireBird2.1.2を使用。 現在、CharSet=SJISで作成されている。
 今回、CharSet=SJISをCharSet=UTF8のデータベースに移行する。
 テーブル名およびフィールド名は、漢字で作成している。ただし、トリガーで使用するフィールドについては、漢字でうまくいかないことがあり、英字となっている。

・プログラム
 3層スタイルC/Sアプリ作成術に基づいて開発。
 DBアクセスは、TIBQueryのみ使用。
 データベースアクセスは、IBXを使用していたが、UNICODEを扱う上で不都合が出たので、DBXに置き換えもあわせて行う。(このあたりの状況は、後述)

 ”店頭受注登録”プログラムについては、4画面、ソースユニット数14本。
 コンポーネントソース9本(”店頭受注登録”プログラムで使用しない、通信コンポーネントのみASCII STRING使用対応の修正)
  

2009年10月27日

3層スタイルC/Sアプリ作成術 サンプルプログラムソース

 業務アプリケーションを作成する際、データベースに何を選択するか。
 データベースコンポーネントに何を使うかは、悩みどころだと思います。
 将来のことまで考えると正解があるようで、ないのが現実だと思います。

 弊社では、とりあえず今ベストだと思われるものを選択。
 ただし、依存部分を極力減らし、将来、上記の変更があった場合にも、なる
べく少ない変更で対応できるようにするように考えました。
 この方法は、”第10回 エンバカデロ・デベロッパーキャンプ”で発表させて
いただきました。

 このサンプルは、下記セッションの内容に基づいたサンプルプログラムです。
大阪会場T6セッション
「業務管理システム開発の実例にみる3層スタイルC/Sアプリ作成術」
資料URL
http://edn.embarcadero.com/jp/article/images/38706/t6.pdf

FireBird+IBX, FireBird+ADO, FireBird+DBX, Oracle+DBX、dBase+BDE(*1)
の組み合わせでのソースを作成しています。
クライアントソースは、そのままに、サーバー側ユニットを切り替えることで
上記、DBとDBアクセスコンポーネントの入れ替えを確認できます。
それおぞれの実装の違いの確認もできます。

また、この手法をとることにより、生産性もあげられ、メンテナンスもしやすいシステム構築が可能です(自己評価です)


(*1)2009/3/31バージョンで追加

また、2009/3/31改訂版では、3層SOAP実装のプロジェクトも公開しています。

詳細は、下記圧縮ファイル内のReadMe.txtをご参照ください。


###############################################################
残念ながら、サンプルソースについては、コメントがほとんどありません。
このソースに興味を持っていただき、もう少し詳しく説明がほしい方見えましたら、
交通費+呑み代 にて、ご訪問し、解説させていただきます。
メールにてお問い合わせください.
###############################################################


サンプルソース(Sample.20090404.zip)
2013.01.16 リンク先変更しました(Vectorのサイトにとびます)

初版公開 2009.03.24 Sample.20090324.zip
改定    2009.03.31 Sample.20090331.zip
   dBase+BDE サーバユニット追加
   3層SOAP 実装プロジェクトの追加
   その他、バグ等もろもろ修正
改定    2009.04.04 Sample.20090404.zip
   バグ修正


posted by しんくそふと at 17:08| Comment(0) | TrackBack(0) | 3層スタイルC/Sアプリ作成術

Excel出力コンポーネント

Excel出力VCLコンポーネント(ソースコード付)

 
 データベースの内容を簡単にエクセル出力する機能をもつDelphiコンポーネントです。
 データセットを指定すると、その内容を指定された形式でエクセル出力します。
 出力方法として3つあり、それぞれが別のコンポーネントとなっています。

(1) カードタイプの出力(TXlsCard)

 指定されたテーブルの内容をカード(単票)タイプでエクセル出力します。
 単純なマスタテーブルの内容を1レコード1ページの形式で出力するのに適しています。

(2) リストタイプの出力(TXlsCard)

 指定されたテーブルの内容を一覧形式でエクセル出力します。
 1レコード1行として、複数行を複数ページに出力するのに適しています。

(3) マスタ+詳細タイプの出力(TXlsSlip)

 マスタテーブルと、マスターテーブルとキー結合している別テーブル(詳細)の双方をエクセル出力します。
 あるマスタテーブルとその詳細を表すテーブル(例えば、発注テーブルと発注明細テーブルなど)を1マスタレコードと複数の詳細レコードを1ページにまとめて出力するのに適しています。 (ただし、データが多いと処理時間がかかることがあります)


 詳細は、ダウンロードファイル内の”エクセルコンポーネント説明.txt” を参照してください.
 VCLソースコードとサンプルプログラムもついています。詳細理解は、サンプルプログラムのコードを見ていただくのが一番早いかと思います.
 Delphi Ver7 と、Delphi2007 for Win32 で、動作確認を行っています。
 サンプルも上記のバージョンのものが作成してあります。(ソースは、ほとんど同じで、プロジェクトファイルが異なっています)
 Ver1.1.0で、Delphi2010 for Win32 のパッケージとサンプルを追加しました。

 コンポーネントソース&サンプルソースを公開しておりますので、使用方法についてのお問い合わせにつきましては、有償での対応とさせていただく場合がございます。ご了承ください。


Excel出力コンポーネントVer1.0.0
初版公開 2009.01.25 TSExcel_20090125.ZIP

Excel出力コンポーネントVer1.1.0
Ver1.1.0 2010.04.23 TSExcel_20100423.zip
 *Delphi2010のパッケージとサンプルを追加しました。

Vectorでも公開しています(Ver1.1.0は更新申請中)
http://www.vector.co.jp/soft/cmt/winnt/prog/se471128.html

posted by しんくそふと at 17:01| Comment(0) | TrackBack(0) | Excel出力コンポーネント

ブログ開設


(有)シンクソフト(http://www.thinksoft.co.jp/)にて、Delphiで開発したコンポーネントやアプリケーションおよびDelphi関連の開発情報の中で、公開可能なのものについて紹介させていただきます。

ネットの情報には多々助けられているので、そのお返しでもあります。


posted by しんくそふと at 15:37| Comment(0) | TrackBack(0) | ごあいさつ