2005年08月18日

再帰呼出しの基本は階乗計算ですよ!

再帰呼出しとは、
ある目的のために作られた関数が、
自分自身を再び呼び出すことで目的が達成出来る場合、
自分自身から自分自身を関数呼出しすことを指します。

プログラミングの基礎演習分野で、
大学の講義や新人研修で広く利用される題材を例に、
今回は再帰呼出しプログラミングをDelphiで習得しましょう。

皆さん小中学校時代の算数で、「階乗」について習いましたね。
念のため復習しておきますから、思い出してくださいね。

0の階乗=1
1の階乗=1
2の階乗=2×1
3の階乗=3×2×1
4の階乗=4×3×2×1

言い換えると、
nの階乗=n×(n−1)の階乗となります。
具体的なプログラミングサンプルを見ての通り、
再帰呼出しなんて全然臆する事はありません楽勝です。
あなたも必要なタイミングで再帰呼出しを利用し、
エレガントなプログラミングを心がけてください。

ただし、MS-DOS(歳がバレますね。笑い)や、
組込みソフトウェアなどメモリ制限や制約の多い中で、
再帰呼出しは実行時スタックを消費することをお忘れなく。

See you again!

使用例
procedure TForm1.Button1Click(Sender: TObject);
 //----------------------------------------------
 function _Factorial(pNumber: Integer): Integer;
 begin
  if (pNumber = 0) or (pNumber = 1) then
   Result := 1
  else
   Result := pNumber * _Factorial(pNumber-1);
 end;
begin
 Edit2.Text :=
  IntToStr(_Factorial(StrToIntDef(Edit1.Text,0)));
end;


関連書籍


Copyright guy@かしらもんじ でぇ〜

posted by guy at 22:49 | 教育編

2005年08月17日

インファーノMP7.5カスタマイズ計画

※2005年7月19日の日記より
皆さんはこの3連休をいかがお過ごしでしょうか?
私たち家族は、土曜日の子供たちの
幼稚園夏祭りに始まり、
日曜日にインテックス大阪で開催された
ロボット博覧会に参加し、
月曜日は朝から海水浴へ、
夕方には温泉でべとつく体をリフレッシュ、
晩は天保山の花火大会、
海遊館ナイトツアーと忙しなく動き回っておりました。

家族サービスを口実に毎週末家族をリードしますが、
今回一番楽しんでいたのは、
他でもなく私かもしれません。(笑い)
午前零時過ぎ、子供たちは心地よい疲れの中、
溢れんばかりの思い出を胸に、ようやく眠りに入りました。
ようやくこれから自分の時間が始まります。
只今記事を編集中です。
(さてと、やることが沢山あって大変です。)

3連休は時間を確保できなかったのですが、
私の中で小さなブームになっている遊びがあります。
今回は車好きの私が継続し、
没頭中のラジコンカーを紹介します。
模型とはいえ、実車の基本的な
チューニングに通じる要素が多く、
車を想い通りカスタマイズできる魅力はとても面白いと思います。

皆さんも気の合う仲間と週末、ビール片手に気楽に、
ドライビングやレースを楽しんでみてはいかがではょうか?
(お酒飲んでも飲酒運転で捕まる事はありません。笑い)

【画面イメージ1】

MP7.5P1.jpg
※写真はMP7.5 SPORTSをベース車にカスタマイズしています。

MP7.5 SPORTS
【オススメ度】★★★★★
全長
496 mm
全幅
307 mm
全高
189 mm
ホイールベース
323〜328 mm
重量
3,200 g
エンジン
排気量 / ボア / ストローク
GS−21R
3.49 cc / 16.4 mm / 16.5 mm
最高出力
hp / rpm
1.6 / 19,000

インファーノ MP-7.5 スポーツ レディセットは、
価格¥54,600(税込)で「KYOSHO」が生産しています。
要なラジコン店で実勢価格3万円代後半で販売されており、
セットの他に、送受信機用バッテリー、
グロー燃料、プラグヒーターを
購入すれば、だれでも簡単に走行可能です。

セットに付属のGS−21Rエンジンは、
リコイルスタータ付き1.6馬力と非力ですが、
初心者は、このエンジンで十分に経験を積み、
パワーソースをアップグレードすることをオススメします。

エンジンをはじめ、
豊富なオプションパーツが、
純正メーカーや、
サードベンダーから提供されていますので、
好きな人はカスタマイズに
夢中になりますので注意が必要です。(笑い)

それでは、MP7.5 SPORTSをベース車にした
マイマシーンのチューニング状況を紹介しましょう。

【画面イメージ2】

MP7.5P2.jpg

@
燃料フィルター/エアークリーナーを装着する。
エンジンをゴミやほこりから守り、エンジンの圧縮を長持ちさせるため、燃料フィルターと、エアークリーナーの装着は必須です。 初心者は特に忘れがちですが、エアークリーナーは走行後は予想以上に汚れますので、よく洗浄し必ずエアークリーナーオイルを十分染み込ませてください。 エアクリーナーにオイルが不足していると、エンジン内に砂などが混入し圧縮機能をすぐに奪ってしまいます。
A
25クラス用マフラーを装着する。
キット標準のノーマルマフラーを1クラス上の25エンジン用マフラーへ交換します。 ノーマルマフラー装着時と比べ排気効率がよくなりエンジンの回転が上がります。 エギゾーストノートも2サイクルレーシングバイクかと思わせる心地よいサウンドに変わります。 エンジンのフケがよくなるので、キャブレターのニードルバルブを開きぎみに設定し、多めに燃料を送ることでエンジンを内部から冷却して下さい。 ノーマルマフラー装着時と同じ設定や、それ以上ニードルを絞ると、エンジンがメルトダウンしますので注意してください。 模型エンジンでリーンバーンエンジンは経験上聴いたことがありませんので、パワーがアップするかといって希薄燃焼は厳禁です。
B
3Pクラッチを装着する。
マフラー交換後はエンジンの回転が上がりますので2Pクラッチのクラッチスプリングへの負荷は増大します。 特にギャップの多い路面をフルスロットで走行する場合、タイヤの路面追従能力が低下した一瞬の隙にエンジンの回転が上がり、2Pクラッチのクラッチスプリングが切れます。 私がドライブする場合は、2Pクラッチでは10分と持ちません。 クラッチトラブルの復旧は時間がかかり大変です。是非3Pクラッチの装着をオススメします。
C
スタビライザーを装着する。
スタビライザーは車体の左右のサスペンション間を鉄の棒で連結し、その鉄の棒から発生するねじれ剛性を利用し、車体のロールを押さえる働きを持っています。 スタビライザーの装着により、実車と同様にコーナリングをよりシャープに、ステアリング特性をよりクイックにできる効果があります。 スタビライザーは構造上とてもシンプルで安価ですから、必ず装着し、あなた好みのステアリング特性が出せるようにねじれ剛性を調整してください。
D
LSDを装着する。
キット標準ではフロント、リヤ、センターにディファレンシャルギアが装着されています。 デフギアは左右のタイヤに回転差を与え、滑らかなコーナリングを実現するために必要なのですが、ギャップの多い路面やコーナリング中のイン側タイヤのリフトなどでタイヤが空転しトラクションが逃げてしまいます。 LSD(リミテッドスリップデフ)はコーナリング時や加速時にタイヤの空転を制限し、トラクションロスを防ぐ機能を持ったギアとなります。 実車の場合、1ウェイ、1.5ウェイ、2ウェイと、加速時のみ空転を制限する物から、減速時も空転を制限する物まで3種類のLSDが存在しますが、模型の場合1ウェイで加速時のみ空転を制限するギアになります。 コーナーからの立ち上がりはノーマルより確実に早くなりますが、 コーナリング時常にアクセルオンのままであれば、車はアンダーステアがどうしても強くなります。

Copyright guy@かしらもんじ でぇ〜

posted by guy at 23:19 | ライフスタイル

2005年08月16日

Windowsのイベントログを書き込む方法

Windowsで24時間365日稼動を保証する
ミッションクリティカルな
アプリケーションを作成する場合などに、
アプリケーションで発生する警告や致命的エラーを、
管理者がすばやく検出し対処できる様に、
適切なソリューションを提供する必要があります。

Windowsのサービスやアプリケーションが出力する
システムエラー、セキュリティ警告、アプリケーションエラーなどは、
主にイベントログに出力される仕組みが出来ています。
しかし、随時発生するイベントを、
「イベントビューア」で確認していては、
管理者の負荷はとても高く、
現実的な運用管理とほど遠いものとなります。

世の中には、Windowsのイベントログにフィルタリングを行い、
必要な情報を管理者へメールで通知するツールや、
Windows XP/Windows Server 2003から
提供された「eventtriggers」コマンドを利用し、
必要なイベントを必要なタイミングで抽出し、
任意のスクリプトを実行できる
便利な運用管理ツール類が存在します。
フィルタリングし通知するツールは別途紹介するとして、

今回は、アプリケーションで、
Windowsイベントログの利用を検討されているあなたに、
WindowsAPI関数の「ReportEvent」を
利用した具体的なソリューションを、
Delphiのサンプルプログラムで紹介します。

サンプルプログラム実行前に
以下の手順を実行してください。


@
EventLog.mcファイルをコンパイルしEventLog.rcを作成する。
MC.EXE EventLog.mc
A
EventLog.rcファイルをコンパイルしEventLog.resを作成する。
BRCC32.EXE -32 EventLog.rc
B
EventLog.resファイルをEventLogTesterUnit.pasに登録する。
{$R EventLog.RES}
C
レジストリにEventLogTesterのエントリを作成する。
・HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
 Services\EventLog\Applicationキー配下に
 「EventLogTester」キーを作成する。
・HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
 Services\EventLog\Application\EventLogTesterキー配下に
 名前=EventMessageFile,種類=REG_SZ,
 データ=<EventLogTester.exeのフルパス>を作成する。
・HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
 Services\EventLog\Application\EventLogTesterキー配下に
 名前=TypesSupported,種類=REG_DWORD,
 データ=0x00000007を作成する。

全ソースは【続きを読む】をクリック!

使用例
procedure TForm1.btnReportEventClick(Sender: TObject);
const
 // イベント識別子
 EVENTID_INFOMATION = $400003E9;
 EVENTID_WARNING = $800003EA;
 EVENTID_ERROR = $C00003EB;
var
 lHdl: THandle;
 lMsg: String;
 lType,
 lEventID: Integer;
begin
 // イベントログのハンドルを取得する
 lHdl := RegisterEventSource(Nil, PChar('EventLogTester'));
 // ログに書込むイベントの種類を決定する
 case rgEventType.ItemIndex of
 0: // Information
  begin
   lType := EVENTLOG_INFORMATION_TYPE;
   lEventID := EVENTID_INFOMATION;
  end;
 1: // Warning
  begin
   lType := EVENTLOG_WARNING_TYPE;
   lEventID := EVENTID_WARNING;
  end;
 2: // Error
  begin
   lType := EVENTLOG_ERROR_TYPE;
   lEventID := EVENTID_ERROR;
  end;
 end;
 // メッセージをイベントログへ書込む
 lMsg := Format('%s', [edtEventMessage.Text]);
 ReportEvent(
  // イベントログのハンドル,
  // ログに書込むイベントの種類,
  // イベントの分類,
  // イベント識別子,
  // ユーザーセキュリティ識別子(省略可能),
  // メッセージにマージする文字列の数,
  // バイナリデータのサイズ(バイト数),
  // メッセージにマージする文字列の配列,
  // バイナリデータのアドレス

  lHdl,
  lType,
  StrToIntDef(edtEventCategory.Text,0),
  lEventID,
  Nil,
  1,
  0,
  @lMsg,
  Nil
 );
 // イベントログのハンドルを閉じる
 DeregisterEventSource(lHdl);
end;


【画面イメージ】

EventLogTester.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 21:21 | 運用管理編

2005年08月15日

XMLデータをアクセスする方法

XML形式の電子データに色々な情報を格納し、
情報を多目的に利用したいというニーズは多いことでしょう。
XMLは、文書コンテンツ管理、デジタル出版、
ナレッジマネジメント、企業間電子商取引などの
インターネットビジネスをはじめ、
アプリケーション間インターフェイスのソリューションとして、
最近では次世代の
ビジネス基盤とし大きな期待が寄せられています。

XML(eXtensible Markup Language)は、
あなたもご存知の通り、
データを構造化し記述するためのマークアップ言語です。
データを作成するユーザーが独自に設定した
「タグ」で、特定の文字列データを囲み、
データを構造的に埋め込んでいく言語のことです。

XMLは全然難しくありません。
あなたもこの機会にXMLをマスターし、
あなたがつくるアプリケーションに応用してください。

今回紹介するサンプルプログラムは、
Delphiの「XMLDoc」「XMLIntf」ユニットを利用し、
XMLデータからXMLタグを指定しそのデータ値を取得したり、
指定したXMLタグ配下のタグ情報を取得するプログラムです。

全ソースは【続きを読む】をクリック!

使用例
procedure TForm1.btnReadClick(Sender: TObject);
 //------------------------------------------------------------------------------
 procedure Doc2View(pXMLDoc: TXMLDocument);
 var
  lCnt: Integer;
  lMsg: String;
  lXMLNode: IXMLNode;
 begin
  memXML.Clear;
  // <Root.RowData>配下の<Country>タグのデータを抽出し
  // 画面に表示する

  lXMLNode := _XMLFindNode(pXMLDoc.Node, 'Root.RowData');
  if (lXMLNode = Nil) then Exit;
  for lCnt := 0 to lXMLNode.ChildNodes.Count-1 do
  begin
   memXML.Lines.Add('Country');
   lMsg := Format(' Name="%s",Capital="%s",Population="%s"',
    [_XMLGetNodeValue(lXMLNode.ChildNodes[lCnt], 'Name'),
     _XMLGetNodeValue(lXMLNode.ChildNodes[lCnt], 'Capital'),
      _XMLGetNodeValue(
       lXMLNode.ChildNodes[lCnt], 'Population')]);
   memXML.Lines.Add(lMsg);
  end;
 end;
begin
 mXMLDocument := _XMLLoadFromFile(edtXMLFileName.Text);
 Doc2View(mXMLDocument);
end;

//------------------------------------------------------------------------------
procedure TForm1.btnGetNodeValueClick(Sender: TObject);
begin
 // 指定されたタグのデータを取得し画面に表示する
 edtValue.Text :=
  _XMLGetNodeValue(mXMLDocument.Node, edtTag.Text);
end;


【XMLデータ】

country_xml.gif

【画面イメージ】

XMLTester.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 22:29 | XML編

2005年08月14日

Gスポットだけ攻めますか

緑の中を走る1本の道は何処へ続くのだろうか?
道はあぜ道から煉瓦造りの道へと時に姿を変え、
柔らかい日差しと、頬を撫でる心地よい風が、
私の冒険心を刺激する。
かつての主の栄枯盛衰が伺える中世の城や宮殿を、
遠目に見る景色は実に美しい。

ここは世界遺産に指定された首都エジンバラを
中心としたスコットランド地方である。
今もこんな「パブリック・フットパス」が、
たくさんあり、我々の心と体を癒してくれる。

首都エディンバラでは毎年8月から1カ月間、
世界最大の芸術祭「エディンバラ・フェスティバル」が
開催され街は芸術色に染まる。

何度となくエディンバラへ出張していた私は、
現地の仲間に誘われて、このフェスティバルを楽しんだ。
街角のアート、大道芸人のパフォーマンスなどを見て、
昼過ぎからパブへ行き「パイントグラス」片手に、
本場の「ギネスビール」を思う存分飲んでいた。

スコットランド地方の人たちは、ロンドン地方と違い、
のんびりしていて、親切で、意外にもシャイであるが、
祭りが人々の気を大きくするのか、
その夜、立ち寄ったディスコでは、
数人の地元の女の子が、私を取り囲んで服を脱がされ、
気が付けばトランクス1枚で
女の子たちと踊ったなんて思いでもある。

あなたもスコットランドを、
肌で感じてみたいとおもうかもしれません。
現在、UKではG8サミットが開催されており、
G8サミットを狙った同時多発テロ事件も起こりました。
渡英について、
皆様には十分注意していただきたいと思います。

それでは最後に、
テロとG8の話題をご紹介します。

FBI(連邦捜査局)によると、最近の爆破テロ事件は、
爆弾の起爆装置に携帯電話が使われることがあるとのこと。
我々にとって携帯電話は、
小さく手軽で必須の便利アイテムですが、
テロリストにとっても同様、いつでもどこからでも簡単に、
爆弾を起爆できる装置として便利なツールとなるわけです。

実に恐ろしい世の中です...

地球温暖化問題は、
ようやく米中が加わり、地球温暖化防止に向け、
途上国と協力しCO2排出の
削減方法を探るという進展がある一方、
世界貿易機関(WTO)のドーハ・ラウンド
(新多角的貿易交渉)の行方は、
各国とも自国の利益を譲らない姿勢で、
先行きは不透明のようですね。

外交というものはとても難しく思います。
地球規模という全体最適が必要なことと理解しながらも、
自国が利益を得るため、
相手に真面目に嘘をつかないとならないですから...

See you again!

関連書籍


Copyright guy@かしらもんじ でぇ〜

posted by guy at 16:28 | ライフスタイル

2005年08月13日

自己記述型データを名前でアクセスする方法

あなたがクライアント/サーバー型の
アプリケーションをつくる場合、
アプリケーション間で送受信するメッセージの
データ構造はどのように設計し実装していますか?
そんな迷えるあなたに、
自己記述型のデータ構造(Self Describe Data)!
ちょいとかじってみますか。

ひと昔前のプログラムが扱うメッセージのデータ構造は、
データだけを順に連ねたとてもシンプルな構造でした。
このメッセージを送受信するプログラムは、
データ構造を解釈するために、
データ構造をあらわす構造体をデータに被せ、
各項目にアクセスしていました。

このデータ構造はデータ自身から、
その構造を求めることが出来ず、
必ずデータ構造をあらわす入れ物が必要になると同時に、
各項目の並びや長さが厳密に規定されているため、
データ構造の変更に柔軟に対応できませんでした。

最近では、SOAPのXMLやSEMIのSECSといった
データ構造に代表される通り、
データがデータの中身である値と、その構造をあらわす
自己記述型のデータ構造が主流となっています。
今回はこの自己記述型のデータ構造を
実現するサンプルプログラムをDelphiでご紹介します。

サンプルプログラムの作成に当り、
2つのキーとなるクラスを作成しています。
「TDatumNode」はデータ構造内の
1項目(要素)をあらわすオブジェクト、
「TContainerNode」は
「TDatumNode」のオブジェクトや、
「TDatumNode」の派生である
「TContainerNode」のオブジェクトを
複数格納するコンテナオブジェクトとして機能します。
丁度、OSファイルシステムの
「ファイル」と「ディレクトリィ」の概念に相当します。
「ファイル」が「TDatumNode」に、
「ファイル」や「ディレクトリィ」を格納する
「ディレクトリィ」が「TContainerNode」に、
それぞれ対応するイメージだと思ってください。

それでは、お疲れ様です。
じっくりソースを解析し、色々と試して下さい。

全ソースは【続きを読む】をクリック!

尚、サンプルプログラムは
「TContainerNode」オブジェクトのデータを
ストリームに保存したり、読込んだりする
メソッドは実装しておりません。
データ構造内の1項目(要素)をあらわす
「TDatumNode」オブジェクトに、
格納できるデータは便宜上文字型のみとしています。
必要あらば、あなた自身で追加してください。(笑い)

【クラスダイアグラム】

DatumClass.gif

【画面イメージ】

DatumClassTester.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 07:22 | 通信編

2005年08月12日

プログラムに必要なパラメータをINIファイルから読込む方法

あなたがつくるアプリケーションプログラムは、
プログラムの動作や振舞いなどに必要な
パラメータをどのように読込み設定しているでしょうか?
INI形式やXML形式でファイルに持たせますか、
或いはレジストリに格納したり、
DBに格納したりと方法は幾つか考えられます。

Windowsのアプリケーションであれば、
パラメータをレジストリに格納することも可能ですが、
UnixやLinuxプラットフォーム上では、
レジストリの概念が無いので使用できません。
また、複数の端末で同じアプリケーションを稼動させる場合、
パラメータがDBで一元管理されているか、そうでないかで、
後の運用工数は大きく変わることでしょう。
どのような形でパラメータを設定し読込むかは、
アプリケーションの機能、各種制約、
運用などを十分検討して下さい。

前置はこれくらいにして、
とにかく手っ取り早く済ませたいと思うななたに、
今回はシンプルで使い勝手がよい、
INI形式のファイルを読込む方法を紹介します。

「Delphi」または「Kylix」の「IniFiles」ユニットにある、
「TIniFile」クラスを利用すると、
WindowsやLinuxといったプラットフォームを意識することなく、
いとも容易くINI形式のファイルが読込めます。
早速、お試しあれ!

全ソースは【続きを読む】をクリック!

使用例
procedure TForm1.btnReadIniFileClick(Sender: TObject);
var
 lSec,
 lItm: TStringList;
 lVal: String;
begin
 lSec := Nil;
 lItm := Nil;
 try
  memINI.Clear;
  if (FIni <> Nil) then FIni.Free;
  // INIファイルオブジェクトを作成する
  FIni := TIniFile.Create(
   ExtractFilePath(Application.ExeName) + edtIniFileName.Text);
  // セクション/アイテムデータを格納するため、
  // ストリングオブジェクトを作成する

  lSec := TStringList.Create;
  lItm := TStringList.Create;
  // セクションを読込み、
  // セクション分のループを実行し
  // 画面にINIファイルの内容を表示する

  FIni.ReadSections(lSec);
  while (lSec.Count > 0) do
  begin
   lItm.Clear;
   // セクション配下のアイテム情報を読込み、
   // アイテム分のループを実行し
   // 画面にINIファイルの内容を表示する

   FIni.ReadSection(lSec[0], lItm);
   memINI.Lines.Add(Format('[%s]', [lSec[0]]));
   while (lItm.Count > 0) do
   begin
    lVal := FIni.ReadString(lSec[0], lItm[0], '');
    memINI.Lines.Add(Format(' %s="%s"', [lItm[0], lVal]));
    lItm.Delete(0);
   end;
   lSec.Delete(0);
  end;
 finally
  if (lSec <> Nil) then lSec.Free;
  if (lItm <> Nil) then lItm.Free;
 end;
end;


【画面イメージ】

INIFileTester.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 06:24 | 起動編

2005年08月11日

SQL文をプログラムの実装から開放しチューニングする方法

経験の浅いデータベース
アプリケーションのプログラマは、
しばしばDBMS(ORACLEなどの
データベース管理システム)に対し、
重たいSQL文を発行する厄介なコードを
実装することがあります。
おそらく自分では無意識かつ
無頓着で、コンピュータが消費する
コストやパフォーマンスなど考える頭が無い開発者です。

しかし、あなたのプロジェクトはそんな開発者でも、
猫よりはましと思い協力してもらわなければ
いけない局面があることでしょう。
プログラムのパフォーマンスがSQL文が原因となる場合、
あなたは、どのように対処するのでしょうか?

SQL文の実行結果が遅い場合、
その責任を問うのは設計者にですか、
プログラマにですか?
それとも、幸いDBA(データベース管理者)が
チームメンバに居る時は、
DBAに責任を押し付けるのでしょうか?

その答えは状況によりそれぞれでしょうが、
SQL文がプログラムの中でゴリゴリに実装されていたのでは、
そのパフォーマンスを改善するにしても、
余りに貴重な時間を無駄に消費するこは間違いありません。

今回は前回と同様、
Delphiの「dbExpress」と「ORACLE」
データベースを利用する前提で、
問合せを実行するデータベースアプリケーションのSQL文を、
プログラムの実装から開放し、
SQL文を即座にチューニングできる
アプリケーションアーキテクチャをご紹介します。

全ソースは【続きを読む】をクリック!

この記事が、あなたがつくるプログラムの
アプリケーションアーキテクチャの参考になればと思います。
(Good luck!)

使用例
//------------------------------------------------
procedure CopyQuery2CDS(
 pQuery: TSQLQuery; pCDS: TClientDataSet);
var
 lCnt: Integer;
 lName: String;
begin
 pCDS.Close;
 with pCDS.FieldDefs do
 begin
  Clear;
  for lCnt := 0 to pQuery.FieldCount-1 do
  begin
   with AddFieldDef do
   begin
    Name   := pQuery.Fields[lCnt].FieldName;
    DataType := pQuery.Fields[lCnt].DataType;
    Size   := pQuery.Fields[lCnt].Size;
    Required := pQuery.Fields[lCnt].Required;
   end;
  end;
 end;
 pCDS.CreateDataSet;
 pQuery.First;
 while (not pQuery.Eof) do
 begin
  pCDS.Append;
  for lCnt := 0 to pQuery.FieldCount-1 do
  begin
   lName := pQuery.Fields[lCnt].FieldName;
   pCDS.FieldValues[lName] := pQuery.FieldValues[lName];
  end;
  pCDS.Post;
  pQuery.Next;
 end;
end;

//------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
 // DB接続オブジェクトを初期化する
 mDB := TSQLConnection.Create(Nil);
 mDB.DriverName := 'ORACLE';
 mDB.GetDriverFunc := 'getSQLDriverORACLE';
 mDB.LibraryName := 'dbexpora.dll';
 mDB.VendorLib  := 'oci.dll';
 mDB.LoginPrompt := False;
 mDB.Params.Values['DataBase'] := 'CONNECT_STRINGS';
 mDB.Params.Values['User_Name'] := 'USER';
 mDB.Params.Values['Password'] := 'PASSWORD';
 mDB.Open;
 // 問合せオブジェクトを初期化する
 mSQL := TSQLQuery.Create(Nil);
 mSQL.SQLConnection := mDB;
 // データソースオブジェクトを初期化する
 mDS := TDataSource.Create(Nil);
 mCDS := TClientDataSet.Create(Nil);
 dbgResult.DataSource := mDS;
 mDS.DataSet := mCDS;
end;

//------------------------------------------------
procedure TForm1.FormDestroy(Sender: TObject);
begin
 // DB接続オブジェクトを廃棄する
 if (mDB <> Nil) then
 begin
  mDB.Close;
  mDB.Free;
 end;
 // 問合せオブジェクトを廃棄する
 if (mSQL <> Nil) then
 begin
  mSQL.Close;
  mSQL.Free;
 end;
 // データソースを廃棄する
 if (mDS <> Nil) then
 begin
  mDS.Free;
 end;
 if (mCDS <> Nil) then
 begin
  mCDS.Free;
 end;
end;

//------------------------------------------------
procedure TForm1.btnReadQueryClick(Sender: TObject);
begin
 // SQLRepositoryよりQueryNameで指定されたSQLを取得する
 mSQL.SQL.Text := Format(
  'select * from SQLREPOSITORY where QueryName = ''%s''',
   [edtQueryName.Text]);
 mSQL.ExecSQL;
 if (mSQL.RecordCount = 0) then
  raise Exception.Create(Format(
   '該当するSQLは見つかりません。(QueryName=''%s'')',
    [edtQueryName.Text]));
 // SQLRepositoryより取得したSQLを画面に表示する
 mSQL.Open;
 edtSQLText.Text := mSQL.FieldByName('SQLTEXT').AsString;
 CopyQuery2CDS(mSQL, mCDS);
 mSQL.Close;
end;

//------------------------------------------------
procedure TForm1.btnExecQueryClick(Sender: TObject);
begin
 // SQLに指定されたパラメータをバインドし実行する
 mSQL.SQL.Text := edtSQLText.Text;
 mSQL.Prepared := True;
 mSQL.Params.ParamByName(edtParameterName.Text).AsString :=
  edtParameterValue.Text;
 mSQL.ExecSQL;
 mSQL.Open;
 CopyQuery2CDS(mSQL, mCDS);
end;

end.


【画面イメージ】

QueryTester.GIF

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 06:41 | データベース編

2005年08月10日

Hも3回目にして妻が満足

男のロマンは
他人に容易く語ることは出来ない。
例え妻や子が増えパパとなっても、
男は自分の大切なロマンを捨てない。
何時までもかっこよく、子供のように純粋な心で、
夢や冒険に満ちた人生を精一杯生きるのである。

平成11年頃、10年近く愛用した
「パジェロ」を手放し新車を購入することにした。
「車は男のロマンだから俺に全て任せろ!」と、
「ハマー」、「レンジローバー」、「ランドクルーザ」の候補から、
妻に気に入った車を選ぶよう相談したところ、

「あんたのロマンかマロンか知らんけど、
トラックみたいな車ばっかり選んで、
ちっちゃい子供が居るのに乗り降りに不便な車はイヤ!
もっと静粛性の高い車にして!
第一どれも大きそうで私が運転でけへんし。」と、
全て反対されしばらく
夫婦の会話が途絶えた時期がありました。

しばらくムシャクシャしていた時、
妻から「エスティマ」を提案され、
子供のために妥協した私は、
深夜自宅へ営業マンを呼び、その場で即決、
結局、「エスティマRVex」
3リットル4WDを購入することになりました。
(一般道での静粛性と乗り心地、
安定性とパワーはとても満足です。)

しかし、男のロマンを捨てきれなかった私は、
「ハマー」を手にするチャンスを伺っていました。
このほど、「三井物産オートモーティブ株式会社」より
「H3」を、2005年秋から正規販売店にて
発売すると発表があり嬉しいかぎりです。

妻も「H1」「H2」は大きすぎてダメ、
「H3」のサイズであればいいかもねと
意外な反応に驚いています。
また価格も450万円からでとてもリーズナブルです。
「H1」「H2」も良いですが
日本の道路事情を考えると「H3」でしょう。
無理に「H1」「H2」を買うくらいなら、
「H3」を選んでインテリアやエクステリアを
充実するのが良いと思います。

今年の秋の発表が待ち遠しい!
現物を見たらまたしても、その場で即決か...

H3.gif

HUMMER H3
【オススメ度】★★★★★
全長
4,720 mm
全幅
1,970 mm
全高
1,850 mm
ホイールベース
2,842 mm
エンジン
Vortec3500
直列5気筒 DOHC 4バルブ
最高出力
kw(hp)/rpm [SAE]
164 (220) / 5,600
最大トルク
N-m/rpm [SAE]
304 / 2,800
燃料タンク容量
87 リットル

Copyright guy@かしらもんじ でぇ〜

posted by guy at 08:13 | ライフスタイル

2005年08月09日

ケラマ諸島での予期せぬ出会い

仕事ができるやつほど遊びは豪快である。
遊びが下手な人間ほどつまらなく、
くだらないものは無い。
仕事は徹底的にやり、遊ぶ時はトコトン遊べ!
先月、我社の社員は研修の冠で沖縄へ、
残念ながら、私は諸事情により沖縄へ飛べなかった。
沖縄と言えば、私の中で蘇る記憶があるので紹介しよう。

1997年11月3日、私の誕生日である。
これまで続いた仕事を終え、一区切り付いた頃、
スキューバダイビングで心と体をリフレッシュするため、
私と妻はケラマ諸島の座間味村
にあるケラマアイランドクラブを訪れた。
(映画「マリリンに会いたい」のシロの子孫は元気かな?)

旅先で出会った仲間と、
今日潜ったポイントや魚介類の話で、
夕食が盛上がっていた頃、
どこか見覚えのある老人がやって来た。
彼は素潜りで水深100mを超える
記録を樹立した「ジャック・マイヨール」、
彼の自伝をもとにした映画「グラン・ブルー」は有名である。

食事の後、ジャックを囲み私と妻、
北海道から来た独身女性2人の計5人で、
夜中まで、スキューバダイビングの危険性や、
閉塞潜水とブラッドシフトのこと、
イルカとの出会いや海に対する想いなどを
熱く語り合ったのが懐かしく思える。
泡盛が気に入ったこともあり、
何時もの酔っ払い状態だった私は、
ジャックや北海道から来た女性2人に遠慮なく意見し、
失礼していたかもしれない。
酔うと自分の思いをズケズケ言う悪い癖が出てしまい、
何時もながら反省するが、
ジャックも北海道から来た女性2人を両手に抱え
熱く口説いていたのには驚いた。
(ジャック君もその歳にしてなかなかやるねって感じだ。)

後から調べてわかったが、
ジャックが座間味に来たのは、
24時間テレビでイルカの「ユキ」ちゃんを
野生へ帰す撮影のためただったとのこと。
ジャックがエロ爺であるか否かは私にとってはどうでも良く、
ジャックと語り合えたあの瞬間は、
今でも貴重で大切な思い出である。

2001年12月23日クリスマスの直前、
ジャックは突然この世を去ったが、
君が海に挑戦するときの想いは今でも私の心に刻まれてる。

グラン・ブルー グレート・ブル
海の人々からの遺産
マイヨール、イルカと海へ還る
ジャック・マイヨールの海と夢

Copyright guy@かしらもんじ でぇ〜

posted by guy at 06:36 | ライフスタイル

2005年08月08日

アプリケーションの二重起動を抑制する方法

同じアプリケーションを複数起動し、
負荷分散や可用性を目的としたシステムもあれば、
同じアプリケーションが
二重起動されると困るシステムもあります。

今回はミューテックス(mutually exclusive)オブジェクトを利用し、
アプリケーションの二重起動を抑制する方法を紹介します。

一般的にミューテックスオブジェクトは、
マルチCPUプラットフォームをターゲットにした
複数のスレッドを並行処理させるアプリケーションで、
共有メモリなどの共有リソースを、
同時にアクセスさせないよう排他制御で使用します。

サンプルプログラムで利用するCreateMutex関数は、
名前付きまたは名前なしの
ミューテックスオブジェクトを作成または開きます。
関数が成功すると、
ミューテックスオブジェクトのハンドルが返ります。
この関数を呼び出す以前に
そのミューテックスオブジェクトが存在する場合は、
この関数は既存のオブジェクトに対するハンドルを返し、
GetLastError関数は「ERROR_ALREADY_EXISTS」を返します。

アプリケーションはCreateMutex関数を呼出す際に、
ミューテックスオブジェクトの名前を指定し、
同じアプリケーションが
この関数を以前に呼び出したか否かを判断し、
アプリケーションの二重起動であるか否かを判定します。

それではサンプルプログラムを参照し、
二重起動させない方法をお試し下さい。

使用例
unit DupCheckUnit;

interface

uses
 Classes, Controls, Dialogs, Forms,
 Graphics, Messages, SysUtils, Variants, Windows;

const
 WM_INITIALIZE = WM_USER + 101;

type
 TForm1 = class(TForm)
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
 private
  FApName: String;
  FMutex: THandle;
  procedure OnMessage(
   var
pMsg: TMsg; var pHandled: Boolean); virtual;
  procedure Initialize;
 public
 end
;

var
 Form1: TForm1;

implementation

{$R *.dfm}

//--------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
 // アプリケーション変数を初期化する
 FMutex := 0;
 FApName := 'YourApplicationName';
 Application.OnMessage := Self.OnMessage;
 // 初期化イベントを自分自身に発生させる
 PostMessage(Self.Handle, WM_INITIALIZE, 0, 0);
end;

//--------------------------------------
procedure TForm1.FormDestroy(Sender: TObject);
begin
 // アプリケーションが使用したリソースを開放する
 if (FMutex <> 0) then
  CloseHandle(FMutex);
end;

//--------------------------------------
procedure TForm1.OnMessage(
 var pMsg: TMsg; var pHandled: Boolean);
begin
 Case pMsg.message of
 // 初期化イベントをハンドリングする
 WM_INITIALIZE:
  begin
   pHandled := True;
   Self.Initialize;
  end;
 end;
end;

//--------------------------------------
procedure TForm1.Initialize;
begin
 FMutex := CreateMutex(0, False, PChar(FApName));
 // この関数を呼び出す以前に
 // ミューテックスオブジェクトが存在する場合、
 // GetLastErrorは
 // ERROR_ALREADY_EXISTSを戻すので、
 // 既に同じアプリケーションが起動されていることになる

 if (GetLastError = ERROR_ALREADY_EXISTS) then
 begin
  MessageDlg(Format(
   'There is another instance of %s of running.',
    [FApName]), mtError, [mbOk], 0);
  PostMessage(Self.Handle, WM_QUIT, 0, 0);
 end;
end;

end.


関連書籍


Copyright guy@かしらもんじ でぇ〜

posted by guy at 07:19 | 起動編

2005年08月07日

パッケージ&ストアドプロシージャでDB更新処理を高速化する方法

オンライントランザクション処理を実行する
プログラムは、複数の端末要求を即座に
処理し結果を応答するプログラムです。
ほとんどの場合、
データベースアクセスを伴うと同時に、
高い信頼性と優れたレスポンスを要求されます。

最近のデータベース管理システム(RDBMS)の大半が、
パッケージやストアドプロシージャをサポートしており、
ちょっとしたアプリケーションアーキテクチャの改善で、
データベースアクセスのパフォーマンスが
大幅に向上する可能性があります。

今回はDelphiの「dbExpress」ルーチンの
「TSQLStoredProc」を利用し、
Oracleストアドプロシージャを呼び出す方法を紹介します。

サンプルプログラムは、
簡単な表にデータを1件更新するだけのものです。
Oracleのストアドプロシージャは、
PL/SQLで記述された
処理手順をOracleが高速に実行できるよう、
コンパイルし中間コードのオブジェクトとして保持しています。
プログラムなどからストアドプロシージャが呼び出される際に、
SQL文の構文解析や再コンパイルといった
オーバーヘッドが発生しません。

従って、パフォーマンスを向上するためには、
更新の度にINSERT、UPDATE、DELETE、SELECTなどの
データ操作SQL文を毎回ちまちま発行するのではなく、
データベース更新の一連の処理をストアドプロシージャに隠蔽し、
パフォーマンスの向上を図るアーキテクチャが有効となります。

一方で複雑なデータベース更新処理を
ストアドプロシージャで実装する場合、
そのデバッグが困難となります。
ストアドプロシージャを効率よく
デバックする開発支援ツールがないと、
デバッグ作業にあなたの貴重な時間が代価として支払われます。

この記事が、あなたがつくるプログラムの
アプリケーションアーキテクチャの参考になればと思います。
(Good luck!)

ここで紹介した方法は、
パフォーマンス向上を目的とした
一つのアプリケーションアーキテクチャにすぎません。
表の正規化、
適切なインデックスの設定、
最適なSQL文の発行など基本的な
パフォーマンスチューニング技術を習得することをお忘れなく。

サンプルソースは【続きを読む】をクリック!

使用例
uses
 DBXpress,
 SqlExpr;

procedure TForm1.Button1Click(Sender: TObject);
var
 lDB: TSQLConnection;
 lSP: TSQLStoredProc;
 lTD: TTransactionDesc;
begin
 lDB := Nil;
 lSP := Nil;
 try
  // DB接続を初期化する
  lDB := TSQLConnection.Create(Nil);
  lDB.DriverName := 'ORACLE';
  lDB.GetDriverFunc := 'getSQLDriverORACLE';
  lDB.LibraryName := 'dbexpora.dll';
  lDB.VendorLib  := 'oci.dll';
  lDB.Params.Values['DataBase'] :=
   'CONNECT_STRINGS';
  lDB.Params.Values['User_Name'] := 'USER';
  lDB.Params.Values['Password'] := 'PASSWORD';
  lDB.Open;
  // DBトランザクションを開始する
  lTD.TransactionID := 1;
  lTD.IsolationLevel := xilREADCOMMITTED;
  lDB.StartTransaction(lTD);
  // DBストアドプロシージャを呼び出す
  lSP := TSQLStoredProc.Create(Nil);
  lSP.SQLConnection := lDB;
  lSP.PackageName := UpperCase('Test_Pkg');
  lSP.StoredProcName := UpperCase('Update_City');
  lSP.Prepared := True;
  lSP.ParamByName('in_Name').Value := 'Argentina';
  lSP.ParamByName('in_Capital').Value := 'Buenos';
  lSP.ParamByName('in_Population').Value :=
   32300003;
  lSP.ExecProc;
  // DBトランザクションの更新を確定する
  lDB.Commit(lTD);
  lDB.Close;
 finally
  lDB.Free;
  lSP.Free;
 end;
end;

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 06:33 | データベース編

2005年08月06日

2バイト文字コードを変換する方法

ソリューションプロバイダが好き勝手にできる
やりたい放題のITプロジェクトとは別に、
皆さんや皆さんの周りのお客さんは、
H/Wの保守期限切れなどによる
代替えH/Wの導入とプラットフォームの変更、
システムのオープン化や、ダウンサイジング化といった
課題に直面していることの方が多いと思います。

今回はそういったマルチプラットフォーム間の
システムリンケージで必要な文字コード変換関数を
まとめて6パターン紹介しましょう。

文字コード変換関数は
2バイト文字コードを別の2バイト文字コードへ変換します。
1バイトと2バイト文字が混在する
際の変換に対応していませんので、
必要に応じ修正してから利用してください。

全ソースは【続きを読む】をクリック!

関数
説明
function _EUC2JIS(
 pString: String): String;
EUC文字コードをJIS文字コードへ変換します。
function _EUC2SJIS(
 pString: String): String;
EUC文字コードをシフトJIS文字コードへ変換します。
function _JIS2EUC(
 pString: String): String;
JIS文字コードをEUC文字コードへ変換します。
function _JIS2SJIS(
 pString: String): String;
JIS文字コードをシフトJIS文字コードへ変換します。
function _SJIS2EUC(
 pString: String): String;
シフトJIS文字コードをEUC文字コードへ変換します。
function _SJIS2JIS(
 pString: String): String;
シフトJIS文字コードをJIS文字コードへ変換します。

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 07:38 | 文字列操作編

2005年08月05日

組込みソフトウェア産業実態調査について

最近購入したデジタル家電を使っているとき、
組込みソフトウェアが原因の
不具合を経験したことはありませんか?
私の場合、メーカーのフィールドエンジニアを、
何度も自宅に呼付け不具合を対応してもらいました。
(もちろん無料で)

さてこの度、経済産業省の
独立行政法人IPA(情報処理推進機構)より、
「2005年版組込みソフトウェア産業実態調査結果」
が発表されました。
IT業界に関わる皆さんは人事と思わず、
ぜひ一読されることをオススメします。

以降の文章は私の感想です。

組込みソフトウェア関連企業の9割の経営者が、
「顧客満足度の向上」を
重要な経営指標とし挙げる一方で、
組込みソフトウェア技術者は、慢性的な人手不足と、
スキル不足の課題を抱え、不明確な開発プロセスと、
ずさんな開発計画によりプロジェクトが運営される
という実態が浮き彫りとなりました。

年齢構成の調査結果から、
約6割が30歳代前半より若い技術者で構成されている。
という実態より関連企業が現在まで行ってきた
組込みソフトウェアの取組み姿勢や位置付けが伺えます。

この若い技術者が行う
組込みソフトウェアの生産工程を、
単に技術者のマスターベーションで
終わらせることのないよう、
この若い技術者から一部の優秀な人材が生まれ、
大半の技術者と経営陣を巻き込んだプロセス改善が
実行されることを期待したいと思います。

逆にISO9000ファミリにもとづく品質管理基準を
重要と考え実行している企業は、
組込みソフトウェア産業界を独り占めですね。(笑い)

関連書籍


Copyright guy@かしらもんじ でぇ〜

posted by guy at 22:07 | ビジネススタイル

2005年08月04日

zlibを使用しデータを圧縮/解凍する方法

あなたはムーアの法則をご存知でしょうか?
「半導体の集積密度は18〜24ヶ月で2倍になる」
という法則ですが、
現在では「集積密度」を「性能向上」に
置き換え考えられることが多く、
今後の半導体などの
性能向上を予測する指標となっています。

ムーアの法則に従うがごとく
CPUやBUSの性能が向上する一方で、
我々が扱う情報のデータ量も飛躍的に増加しています。
大量のデータ転送はシステムの顕著なボトルネックとして、
しばしば我々が直面する問題となることでしょう。

今回は、データ転送などの制約やボトルネックの
問題を解決する方法としデータの圧縮を取上げます。
zlibはZip、gzip、画像フォーマットPNGで使われている
圧縮アルゴリズムをライブラリ化したものです。
DelphiではBorland社から
「zlib」ユニットとして提供されています。

サンプルプログラムは、
Delphi標準のzlibユニットを利用し、
入力されたファイルをzlib形式で圧縮する機能と、
zlib形式のファイルを解凍する機能を提供します。

サンプルプログラムをよく理解し、
あなたの問題を解決するために役立ててください。

zlib公式サイトは以下のURLを参照してください。

URL:http://www.zlib.net/


全ソースは【続きを読む】をクリック!

使用例
procedure TForm1.btnCompressClick(Sender: TObject);
var
 lSData,
 lDData: Pointer;
 lSSize,
 lDSize,
 lLevel: Integer;
begin
 lSData := Nil;
 lDData := Nil;
 try
  // ファイルのデータを読込みます
  _ReadFile(edtFileName.Text, lSData, lSSize);
  // ファイルのデータを圧縮します
  case rgCompressMode.ItemIndex of
  0:lLevel := Z_NO_COMPRESSION;
  1:lLevel := Z_BEST_SPEED;
  2:lLevel := Z_BEST_COMPRESSION;
  end;
  CompressBuf(lLevel, lSData, lSSize, lDData, lDSize);
  // 圧縮データをファイルへ書き込みます
  _WriteFile(Format('%s.cmp',
   [edtFileName.Text]), lDData, lDSize);
 finally
  if (lSData <> Nil) then FreeMem(lSData);
  if (lDData <> Nil) then FreeMem(lDData);
 end;
end;


【画面イメージ】

ZLIBTester.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 08:13 | データ圧縮編

2005年08月03日

Windowsの高分解能タイマを利用し処理時間を計測する方法

あなたが業務でプログラミングを行う場合、
パフォーマンスをシビアに
要求される局面は多々あるかと思います。
闇雲にプログラムをチューニングし、
時間の無駄使いをしないためにも、
ボトルネックとなる処理を
効率よく洗出し対処することが重要になります。

処理が遅いアプリケーションを調査すると、
ほとんどの場合、2割のボトルネックが
遅い原因の8割を占めるという結論に至ります。
効率よく処理速度を向上するには、
この2割のボトルネックにメスを入れ、
他の8割はホドホドに対応するのが良いでしょう。
また運用フェーズなどでは
長期的なパフォーマンスの集計を行い、
パフォーマンスの低下がないか調べる必要もあるでしょう。

というわけで、
今回はプログラムの処理時間を計測する方法をご紹介します。
あなたのプログラムに組み込んで処理時間を計測してください。

計測方法はとても簡単です。
「QueryPerformanceFrequency」API関数を呼び出し、
高分解能パフォーマンスカウンタの
カウンタ周波数を取得します。
計測したい処理の前後で
「QueryPerformanceCounter」API関数を呼び出し、
高分解能パフォーマンスカウンタの値をそれぞれ取得します。
取得したカウンタ値の差を1000倍しカウンタ周波数で
割ってやると処理時間がミリ秒の単位で計測できます。

インストール先のハードウェアが
高分解能パフォーマンスカウンタをサポートしない場合、
関数は0を戻し計測できませんので注意が必要です。

使用例
procedure TForm1.Button1Click(Sender: TObject);
 procedure _Loop;
 var
  lCnt1,
  lCnt2,
  lCnt3: Integer;
 begin
  lCnt3 := 0;
  for lCnt1 := 1 to 10000 do
   for lCnt2 := 1 to 10000 do
    Inc(lCnt3);
 end;
var
 lSPoint,
 lEPoint,
 lFrequency: TLargeInteger;
 lElapse: Double;
begin
 // カウンタ周波数を取得します
 QueryPerformanceFrequency(lFrequency);
 // 計測開始のカウンタ値を取得します
 QueryPerformanceCounter(lSPoint);
 // 計測対象の処理です
 // 10000*10000回のループ処理を実行します
 _Loop;
 // 計測終了のカウンタ値を取得します
 QueryPerformanceCounter(lEPoint);
 // 経過時間をミリ秒単位で算出します。
 lElapse := 1000 * (lEPoint - lSPoint) / lFrequency;
 ShowMessage(Format(
  '経過時間 = %.2f (ms)', [lElapse]));
end;

関連書籍


Copyright guy@かしらもんじ でぇ〜

posted by guy at 07:01 | 運用管理編

2005年08月02日

MSXMLを利用しHTMLを動的に生成する方法

WEBサーバーアプリケーションなどから動的HTMLを
効率よく作成したいとお探しのあなたに便利な
Delphiで作成したサンプルプログラムを紹介します。


今回ご紹介するプログラムは
WindowsOS標準DOMの「MSXML」を利用し、
XMLデータファイルとXSLスタイルシートファイルから
HTML形式のファイルを動的に生成する
コンソールアプリケーションです。


あなたがこのプログラムを利用する場合、
ソース上の必要な部分を切り取って使用して頂くか、
実行モジュールを子プロセスとして起動し利用してください。

掲載したサンプルは
国、首都、人口のXMLデータファイルと
上記の各項目を表形式にするXSLスタイルシートから
HTML形式のファイルを生成します。


ではさっそく、プログラムを紹介しましょう。

XSLTソースは【続きを読む】をクリック!

コマンド
XSLT [xml_file xsl_file [output_file]]
説明
xml_fileで指定したXMLデータファイルと、xsl_fileで指定したスタイルシートファイルから、output_fileで指定したHTMLファイルを生成します。output_fileは省略可能です。省略した場合、生成されるHTMLは画面に出力されます。HTMLの出力結果は、リダイレクトでファイルへ出力することも可能です。
使用例
XSLT country.xml country.xsl > country.htm

【コマンドの実行結果】

Name
Capital
Population
Argentina
Buenos Aires
32300003
Bolivia
La Paz
7300000
Brazil
Brasilia
150400000
Canada
Ottawa
26500000
Chile
Santiago
13200000
Colombia
Bagota
33000000
Cuba
Havana
10600000
Ecuador
Quito
10600000
El Salvador
San Salvador
5300000
Guyana
Georgetown
800000
Jamaica
Kingston
2500000
Mexico
Mexico City
88600000
Nicaragua
Managua
3900000
Paraguay
Asuncion
4660000
Peru
Lima
21600000
United States of America
Washington
249200000
Uruguay
Montevideo
3002000
Venezuela
Caracas
19700000

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 08:14 | XML編

2005年08月01日

入力されたデータの重複検査を簡単に行う方法

あなたが業務でプログラミングを行う場合、
本来の機能を実装するのはもちろんのことですが、
ヒューマンI/FやマシンI/Fから入力された
データの妥当性検査や、処理中のエラー検出と復旧の
処理などを想定出来る限り実装することが重要になります。

気が付けば、これらバカ避け機能のコーディング量が、
本来の機能のコーディング量をはるかに上回ることが
しばしばあることでしょう。

私が業務でプログラミングをはじめた頃に先輩や上司から、
「おまえのプログラムは目の粗いザルのようなものだ。
入れた途端に落ちてしまう。
ザルに入れたものを落とさないよう目を細かくすることが
趣味のプログラムと業務プログラムの違いなんだ。」
と言われました。

さて自分のことはおいといて今回は、
入力されたデータの重複を簡単に検査する方法を紹介します。
DelphiVCLの「TStringList」を利用し、
重複するデータを例外処理で検出します。
あたは既にこの方法をご存知かもしれませんね。
めんどくさがりの私も時々使っています。(笑い)

使用例
procedure TForm1.Button1Click(Sender: TObject);
var
 lList: TStringList;
begin
 // TStringList.Duplicatesの機能を利用し
 // 入力されたデータの重複検索を簡単に行う
 lList := TStringList.Create;
 try
  lList.Duplicates := dupError;
  lList.Sorted := True;
  try
   lList.Add('apple');
   lList.Add('lemon');
   lList.Add('orange');
   lList.Add('strawberry');
   lList.Add('apple');
  except
   // 重複が検出された場合
   // EStringListError例外をキャッチします
   MessageDlg(
    'データが重複しています', mtError, [mbOK], 0);
  end;
 finally
  lList.Free;
 end;
end;

関連書籍


Copyright guy@かしらもんじ でぇ〜

posted by guy at 06:55 | 妥当性検査編

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。