最初のページに戻ります。

総合の目次があるページに戻ります。

よく使うマニュアルです

Wiki

updated on 2004.06.23

a.13. 2000年問題 其の拾参

[ Previous ] [ HOME ] [ Upper ] [ Next ]


なにから、話しましょうか。本当に、ここ2日間で、たくさんの事をしました。ギネスブックものですよ。いや、ほんと。昨日なんて、リモート先の物流の制御装置が朝から立ち上がらなくて、大変だったんですよ、もう。出荷=売上なのでね。

本当にすべてのDDSを修正したのか

もちろん、2000年対象外のソースを一つ一つ見てゆけば、いいのだが、(実際、最初そうしていたのだが、)もういやになった。なにか方法は無いだろうか。早い話、ファイルの怪しい部分に気づくツールがあって、それが勝手に判断してくれれば、いいのだ。とにかく、

すべてのDDSを予め修正して、該当するフィールドを完全に洗い出すこと。

これが、踏み外せない、大事な一歩なのだ。これのために、いくつか、またツールを作成した。

レポータの自動生成

あるファイルの、フィールドの桁を調べて、2,4,6,7,8のものを選び出し、H,F,C,O仕様書を自動生成するツールを作成した。自動生成も結構楽になってきたのだが、フィールド名を見出しに印刷したかったので、どうしても、フィールドの間が10バイトになる。すると、198にしても、一つのプリンターファイルでは、19個まで。さらに、一つのRPGでは、プリンターファイルは8個まで。フィールドを配列にセットして、その数を19で割、切り上げた数字で、F仕様書のプリンターファイルの定義が決まる(O仕様書の前に決めなくてはならない。ソースをキー付きにする手もあるが、SAV/RSTに時間がかかるらしいのでやめた)。さらに、OF標識も別個のものをつけた。(同じものをつけるとコンパイルエラーなので、OA,OB,OC,OD,OE,OF,OG,OV(以上8個)をつけた。01から99にすると、標識はオンにはなるが(当然)、オフは自分でしなくてはならないので、C仕様書の行数が増えるので、やめた。また、このオーバーフロー標識を一つにだけ定義したら、そのほかのプリンターファイルの動きが変になった。オーバーフロー標識をつけたものが、121ページなら、そのほかのプリンターファイルは242ページ(偶数ページが飛ぶ)になってしまった。いろいろいじくったが、うまく行く場合もあり、よく分からないので、すべてに、個別のオーバーフロー標識をつけた。こうすると、今までのおかしな動きがぴたりと無くなった。いままで、オーバーフロー標識を、はしょった、ことなど無かった。) 

O仕様書の桁位置だが、0010と記入して、10としなくても、コンパイルもきちんと通ることが分かったので、先行0消去はしなかった。編集APIで簡単に出来るが、しなくてもいいのなら、しなくてもいいのだ。(ちょっと出来るソースが汚いが)。

さて、自動生成された、RPGをコンパイルして実行すると、結構いい。QRYの様に、無用に編集コードがつかないのも、いい。むしろ見やすい。でも、データが多い。何でもかんでも、桁数が2,4,6,7,8のものは、数字だろうが、文字だろうが、出てくる。中には、一つのファイルだけで、数千頁出てくる。これが、100も200も(一つのファイルで3つプリンターファイル使っているものもある。)出てくるのだから、困る。これじゃあ、だめだ。

そして、昨晩、考えついた。DSPDみたいに、ファイルを読み込んで、フィールドを切り出し、限りなく、日付に近いものを、ファイルに出力したらどうか。

「限りなく」「日付」に近いもの

  1. DSPDをコピーして、修正した。懐かしいプログラム。かれこれ5年以上前にさわったのが最後のプログラムだった。さて、これを修正して、DSPDを作成した頃にはなかった編集語APIを利用した。
  2. 入力ファイルのレコードを、内部記述で、配列に落とす。1バイト×9000くらいにした。また、ファイルは到着順にした。(キー付にする必要を感じなかった)。
  3. ファイルフィールドの情報をAPIで取り出した。
  4. フィールド情報を一件一件、読み込んでは、そのフィールド長を判定する。2,4,6,7,8桁を対象とした。(数字は整数、文字はバイトの長さ。もちろん小数以下が有数ならば対象外)
  5. 対象となるフィールドの出力バッファ(物理ファイルのみ対象とするので、入力も出力も同じ)の開始位置を取り出す。
  6. SUBSTで、フィールドのバイト長を、データの開始位置から、取り出す。このとき、結果は、左詰めでセットされることに注意。「8901       」となるのだ。(右にスペースができる)。
  7. 数字の場合は、このまま、数字編集APIで、編集コード3で変換する。これで、パックやバイナリもきちんとした数字の文字列になる。(編集コードを3にしたのは、APIでは編集コードXは使えなかったから。これは、後でコメントを載せよう)
  8. これを、右詰にするプログラム部品で、フィールド内で、右詰に修正する。「   8901」となる。
  9. XLATEでスペースを’0’に変換する。(「00008901」となる。)
  10. 文字の場合は、取り出したデータを右詰にして、XLATEでスペースを0に変換する。(TESTNで数字であることを確認する)。
  11. これを、パラメータにセットして、日付判定プログラムをCALLする。
  12. 判定プログラムでは、その数字を日付と最初にみなし、年月日の妥当性検査をする。該当した日付形式をYMD,MDY,YYMDなどと「日付形式コード」として戻す。どれにも該当しなければ、その日付形式コードはスペースで戻る。
  13. CALLのあと、その「日付形式コード」がスペースでなければ、「検索結果ファイル」に出力する。
  14. フィールドがあれば、次のフィールドを検索し、最後のフィールドならば、次のレコードへ進む。

さらに、DSPOBJDのAPIを利用して、ライブラリー単位に物理ファイルを取り出し、上記のツールに投げるプログラムも作成した。APIのテンプレートが活躍した。ほんの15分くらいで出来た。

さて、思ったよりもうまくいった。おお、と思うようなフィールドも出てきた。いずれ、ソースもアップしようと思う。QRPGSRCのSRCDATも出てきた。しょうがない。

でも以下のことに気づいた。

  • もし、日付のフィールドがあっても、偶然使われていなくて、すべて0が入っていると、ヒットしない。(たとえば、入金日とか、取引停止日など)

これは、検索結果ファイルに、「全件0だったマーク」をつけようとおもう。これは、人の判断によるしかない。

  • 同じことだが、ファイルが空(記述はあるが、コンパイル用で、実行時にはQTEMPに作成されるために、現存するファイルがデータを持たない)の場合は、当然ヒットしない。

これも、検索結果ファイルに、「データ無かったマーク」をつけようとおもう。これも、人の判断によるしかない。

  • メンバーが複数ある場合、どれを最適内容とするのかの判断。

もう、*FIRSTでいいとおもう。件数がもっとも多いものも考えたが、そんなに差はないと思う。

  • 8バイト以上の長さのフィールド(たとえば20バイトのダウンロード用のフィールド)に、日付が入っている場合。そもそも、8バイト以下が対象なので、ヒットしない。

これは、修正して、20バイトくらいまで可能にしようと思う。30バイトでもいいな。

  • マイナスのデータが一つでもあれば、日付フィールドとして見ないようにすべき。

これは、データ上のニブルを判定する。ゾーンとパックでは場所が違う。または、編集コードで判定すべきか?いったんマイナスなら、どこか配列に移して、そこで判定して、検査からはずそうか。

  • 実際に実行したら、「時間」がヒットした。これは20:20:10を、西暦2020年10月と判定したため。やれやれ。

これは、日付判定プログラムを修正する。1980以上だけではなく、1980から1999の間にする事で、解決する。

「限りなく」は、日付と判定された数の全体からの割合で判断する

あるフィールドを1000レコード分検索して、日付と思われるのが1000データあれば100%、500あれば、50%と扱う。あとは、人間の判断にする。これで、結構、税金などのフィールドが、年月とかと判定されるものが、偶然日付と同じだったか、それとも、限りなく100%に近く日付なのか、が判断できる。最終的に、判断するのは、やはり人間だが、前に比べて、ずっと楽になる。このレポートは「検索結果ファイル」を、QRYで出すが、フィールド単位にヒット件数と検索件数を入れてあるので、%計算も楽だ。また、かなり大きなファイルで、200万件のレコードをすべて検査するのは無駄なので、1000件を最小に、あとは1/3の件数検査にした。それも、10000件を越える場合は、10000件までとした。

日付判定の外部サブルーチン

これは、以前作った、日付移行プログラムとほとんど同じ。あまり同じなので、共有することにした。ただし、8バイトのパラメータではなく、20バイトになる。また、最初のものは、日付だけが入るものだったが、今度は日付以外も入るので、さらに、細かな検査が必要である。いづれ、またアップしようと思う。また、ここで、出てきたフィールドをもう一度検査するば、DDSの修正漏れはないと、信じている。しかし、先は長いなぁ。

1 2 3 4 5 6 7 8 日付フォーマットコード 注意
0 0 0 0 0 0 9 8 Y
80 - 99
0 0 0 0 9 7 0 1 YM
80 - 99 01 - 12
0 0 0 0 1 9 9 7 YY
1980 - 1999
0 0 9 7 1 2 0 1 YMD
80 - 99 01 - 12 01 - 31
0 0 1 9 8 0 1 2 YYM
1980 - 1999 01 - 12
0 0 0 1 1 2 9 8 MDY 5桁と6桁にまたがる
01 - 12 01 - 31 80 - 98
0 9 9 7 1 2 0 1 YMD7
980 - 999 01 - 12 01 - 31
1 9 9 7 1 2 3 1 YYMD
1980 - 1999 01 - 12 01 - 31
0 5 1 2 1 9 9 7 MDYY 7桁と8桁にまたがる
01 - 05 1 - 31 1980 - 1999

※MYYとMDYは識別つかない。121998は12/19/1998とも12/1998ともとれる。でも、12/1998は無いだろう。

今頃、動いているんだろうなぁ。エラーで止まっているかな?

続く...


[ Previous ] [ HOME ] [ Upper ] [ Next ]

You are at K's tips-n-kicks of AS/400

 

Ads by TOK2