IBM i で文字フィールドをキーにするとき、基本的にはEBCDIC順にデータが並びます。
今回はDelphi/400で、EBCDIC順での大小チェックを実装する方法をご紹介いたします。
Windows上でDelphi/400を使って範囲検索を行うにあたって
if (edtFROM.Text <> '') and (edtTO.Text <> '') and
(UpperCase(edtFROM.Text) > UpperCase(edtTO.Text)) then
begin
// エラー出力、フォーカスセット、Abortをここで行う
end;
といったロジックを使って大小チェックを行い、
Fromの値の方がToの値より大きい場合にエラーにしたり、
FromとToを入れ替えて後続処理に進めることがあるかと思います。
ここで、上記のロジックではASCII順(Windows順)で大小チェックを行うため、
データをEBCDIC順で管理している場合に正しい大小チェックが行われません。
上図で①EBCDIC順の場合に「KEY_TEST」~「1234567890」までの
3件をヒットさせたい場合に『K ~ 2』といった条件で検索しようとすると、
Windows順においては『K』は『2』よりも大きいためエラーになってしまいます。
このような場合に、大小チェックがEBCDIC順で出来れば正しいデータを抽出できます。
実装ポイントは
① EBCDICのAnsiString型の定義
② 検索処理において①で定義した型を使用
の2箇所です。それぞれ実装方法を解説します。
①EBCDICのAnsiString型の定義
フォームの宣言部(type節)にて、以下のように
IBM EBCDICに準拠したAnsiString型を定義します。
// クラスを継承し、EBCDIC型のstringにキャストすることで利用可能となる。
// (※チェック対象が英数混在の半角項目の場合に利用可能)
type
// IBM EBCDIC(From>ToチェックでA-Z+0-9順のチェックを行う)
EBCDICString = type AnsiString(20290);
type //(ここからは通常の宣言)
TForm1 = class(TForm)
・・・
ここでは「EBCDICString」と定義しておきます。
Delphi/400 Version 2009以降では、AnsiStringにコードページが指定できます。
コードページを指定するには、type節で type AnsiString(CodePage) と宣言します。
※IBM EBCDIC(日本語カタカナ)のコードページは20290です。
※type節での宣言は、当該処理を行うユニットからuses節で参照できればいいので、
各ユニットごとに記述する必要はありません。
②検索処理においてEBCDICのAnsiString型を使用
検索を行う際の大小チェック時には、
対象となる文字列を上記①で定義した「EBCDICString」でキャストします。
以下は本記事の冒頭で紹介したロジックにEBCDICStringキャストを追加したものとなります。
if (edtFROM.Text <> '') and (edtTO.Text <> '') and
(EBCDICString(UpperCase(edtFROM.Text)) > EBCDICString(UpperCase(edtTO.Text))) then
begin
// エラー出力、フォーカスセット、Abortをここで行う
end;
※AnsiString(20290)の文字コードでは半角英小文字を考慮していないため、
ロジックにUpperCaseを含めていないと半角カナと英字の判定が正しく行われません。
<参考リンク>