自己学習メモインデックス
概要
得意先マスタメンテナンス画面のコーディングを進めており、チェック処理の実装をする中で電話番号のチェック処理に着手しました。
そこで、Javaや.Net開発ではよくやっていた、電話番号の正規表現チェックを行おうと思って色々調べていたのですが、あんまりそういった情報が見当たりませんでした。
色々と試行錯誤して、定位置記入方式での実現にこだわりすぎないように一部妥協して、SQLRPGLEのコードの一部でフリーフォーマットのRPGプログラミングをしてしまいましたが、そのチェック処理を呼び出す元となるRPGは定位置記入方式のコーディングで実現できましたので、記録としてQiita記事に残します。
サンプルソース
チェック処理用のSQLRPGLE
以下は、電話番号の正規表現チェック処理を行うSQLRPGLEプログラムです。
第1引数に指定された電話番号をチェックし、その結果を第2引数のP@RTCD(リターンコード)にセットして処理を終了します。
電話番号はハイフンを含んだ形式のみを許可し、それ以外は全てエラーになるようにしています。
FMT H HKeywords++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*************** Beginning of data *****************************************
0001.00 H
0002.00 * 正規表現用の変数
0003.00 D Regex S 50A Inz Varying
0004.00 * マッチした件数
0005.00 D Cnt S 1S 0
0006.00 * パラメータ:電話番号
0007.00 D P@TEL S 15A
0008.00 * パラメータ:リターンコード
0009.00 D P@RTCD S 2A
0010.00 * パラメータリスト
0011.00 C *ENTRY PLIST
0012.00 C PARM P@TEL
0013.00 C PARM P@RTCD
0014.00 /Free
0015.00 //Regex = '^0¥d{1,3}-¥d{1,4}-¥d{4}$';
0016.00 Regex = '^0[0-9]{1,3}-[0-9]{1,4}-[0-9]{4}$';
0017.00 Exec Sql Set Option Commit = *None;
0018.00 Exec Sql
0019.00 Set :Cnt = RegExp_Count(Trim(:P@TEL), :Regex);
0020.00 If Cnt = 1;
0021.00 P@RTCD = 'OK';
0022.00 Else;
0023.00 P@RTCD = 'NG';
0024.00 EndIf;
0025.00 *INLR = *ON;
0026.00 /End-Free
****************** End of data **********************************************
Inz Varying
と指定しているのは、Regex変数に指定する正規表現文字列に余分な空白文字列が入ってしまい、正規表現として正しい値にならず、正規表現のチェック処理が正常に動作しなくなってしまうので、固定長文字列ではなく可変長文字列の定義とするために指定しています。
0002.00 * 正規表現用の変数
0003.00 D Regex S 50A Inz Varying
-
0016.00 Regex = '^0[0-9]{1,3}-[0-9]{1,4}-[0-9]{4}$';
- 電話番号の正規表現です。
- 本当は0015.00にコメントアウトしている定義を利用したかったのですが、どうやら
\
をPUB400.comの環境では正しく認識してくれないようで、どうやっても正規表現のチェックが正常に動作しませんでした。 - 検証方法としては、STRSQLで
values regexp_count('03-3333-3333', '^0[0-9]{1,3}-[0-9]{1,4}-[0-9]{4}$')
こんな感じで実行すると動作確認が簡単にできます。
-
0019.00 Set :Cnt = RegExp_Count(Trim(:P@TEL), :Regex);
-
P@TEL
は、固定長文字列のためTrim関数をかまして余分な空白を取り除いています。 -
P@TEL
自体もInz Varying
と指定して可変長文字列にすればいいのかなぁと思って指定してみたのですが、パラメータで指定する変数にはこの指定が使えないと怒られてしまいました。
-
0014.00 /Free
0015.00 //Regex = '^0\d{1,3}-\d{1,4}-\d{4}$';
0016.00 Regex = '^0[0-9]{1,3}-[0-9]{1,4}-[0-9]{4}$';
0017.00 Exec Sql Set Option Commit = *None;
0018.00 Exec Sql
0019.00 Set :Cnt = RegExp_Count(Trim(:P@TEL), :Regex);
0020.00 If Cnt = 1;
0021.00 P@RTCD = 'OK';
0022.00 Else;
0023.00 P@RTCD = 'NG';
0024.00 EndIf;
0025.00 *INLR = *ON;
0026.00 /End-Free
電話番号チェック処理を呼び出すRPGLE
上記で定義したCHECK_TELを呼び出すRPGプログラムです。
UnitTestみたいなイメージで、テストデータ(電話番号データ)を配列で定義して、電話番号の正規表現チェック処理が正常に動作しているのかテストするような感じで作ってみました。
FMT * *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
*************** Beginning of data *****************************************
0001.00 * テスト用の電話番号配列定義
0002.00 D @@DSTELS DS
0003.00 D 15 INZ('03-1234-5678')
0004.00 D 15 INZ('090-1234-5678')
0005.00 D 15 INZ('0120-1234-5678')
0006.00 D 15 INZ('0312345678')
0007.00 D 15 INZ('09012345678')
0008.00 D 15 INZ('012012345678')
0009.00 D @@TELS 15 DIM(6) OVERLAY(@@DSTELS)
0010.00 * インデックス変数
0011.00 D i S 1P 0 INZ(1)
0012.00 * デバッグ表示用の文字列
0013.00 D str S 20A
0014.00 * パラメータリストの定義
0015.00 C PL@TEL PLIST
0016.00 C PARM P@TOKTEL 15
0017.00 C PARM P@RTCD 2
0018.00
0019.00 * 電話番号の正規表現チェック処理実行
0020.00 C FOR i = 1 to 6 by 1
0021.00 C EVAL P@TOKTEL = @@TELS(i)
0022.00 C EVAL P@RTCD = ''
0023.00 C CALL 'CHECK_TEL' PL@TEL
0024.00 C @@TELS(i) CAT P@RTCD str
0025.00 C str DSPLY
0026.00 C ENDFOR
0027.00
0028.00 C EVAL *INLR = *ON
****************** End of data ********************************************
これを実行すると以下のような結果となります。
DSPLY 03-1234-5678 OK
DSPLY 090-1234-5678 OK
DSPLY 0120-1234-5678 OK
DSPLY 0312345678 NG
DSPLY 09012345678 NG
DSPLY 012012345678 NG
- PL@TEL : CHECK_TELを実行する際に指定するパラメータリスト
- P@TOKTEL
- テスト用の電話番号を格納するパラメータ
- 後々、得意先マスタの電話番号をセットする予定なのでTOKTELという名称にしています。
- P@RTCD
- リターンコードをセットするためのパラメータ
- ここには
CHECK_TEL
によってOK
/NG
の文字列がセットされます。
- P@TOKTEL
0014.00 * パラメータリストの定義
0015.00 C PL@TEL PLIST
0016.00 C PARM P@TOKTEL 15
0017.00 C PARM P@RTCD 2
配列に定義した6つの電話番号を繰り返し処理によって1つずつCHECK_TELに渡し、チェック処理の結果をDSPLYで表示しています。
DSPLYで出力する文字列は、パラメータで指定した電話番号と、その電話番号でチェックした結果(OK/NG)を出力したかったので、CATで文字列結合してから出力するようにしました。
CATだと2つの文字列を1つに結合するしかできないのが面倒ですね;
できれば 電話番号→結果
と、矢印なんかも付けて、テスト結果を整形して出力したかったのですが、面倒だったのでやめました。
0019.00 * 電話番号の正規表現チェック処理実行
0020.00 C FOR i = 1 to 6 by 1
0021.00 C EVAL P@TOKTEL = @@TELS(i)
0022.00 C EVAL P@RTCD = ''
0023.00 C CALL 'CHECK_TEL' PL@TEL
0024.00 C @@TELS(i) CAT P@RTCD str
0025.00 C str DSPLY
0026.00 C ENDFOR
とりあえず、これで電話番号のチェック処理の実装ができたので、得意先マスタメンテナンス画面の実装も、あとは残りのチェック処理の実装ちょろっとと、登録/更新/削除処理の実装だけなんで、もう少ししたらQiita記事に投稿できるかな。。。