• ベストアンサー

COBOLで検索する方法

03 REC-DA PIC X(200) 03 CHR1 PIC X(30) という定義があるとき REC-DA = "あいうえおABC12345かきくけこさしすefg" というデータに対して CHR1 = "ABC" または "かきくけ" などがあるかどうかなどの検索をしたい場合 どのような命令で調べるのでしょうか? まずCHR1の長さ3または8?4?をはかりREC-DAもこの長さに区切り順に検索していく・・・ とかいわれましたが、そんな無駄な作業が必要なんですか? いままでC++,JAVAとかやっていたので REC-DA.find(CHR1) = TRUE とかそんな具合にできると思ったのですが。 良い方法を教えてください。

  • Mi8
  • お礼率76% (388/506)

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.6

#4,#5です。 INSPECTでは部分文字列参照が使えないかと思っていましたが、使えるようですね。len-chr1 と COUNT を数値型として、 move 0 len-chr1 inspect chr1 tallying len-chr1 for characters before " " move 0 to COUNT inspect REC-DA tallying COUNT for all chr1(1:len-chr1) if COUNT = 0 then display "nakatta" else display "atta" end-if

その他の回答 (5)

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.5

#4です。EXAMINEはINSPECTが出来る前の古い命令です。 >うまい方法ないでしょうか? そもそも、そのプログラムにおいてそういった可変長文字列のハンドリングが本当に必要か見直すことも考えられます(COBOLが得意な別の手段で解決できないか?)。可変長文字列の概念の無い言語なんですから。(オブジェクト指向の概念のない言語でオブジェクト指向プログラミングするよりはましかな) とはいえ、現実には難しいでしょうから、面倒だけど部分文字列参照で正攻法で書くか、Cで書いてそれをCALLで呼ぶのが現実的な解でしょう。

Mi8
質問者

お礼

固定長レコードを読み込みそこからユーザーが入力するものを含む レコードを取り出したいのです。 東京都・・・・ などの固定長から例えば'5-1'を含むものとかです。 SQLが使えれば一瞬なんですが、なんとSQLすらないので とても不便に思っています。 20バイト "ABC123DEF456GHI789 " から 5バイト "123 "だと引っかからないようです。 TRIMして検索ができればいいのですが。 とっても不便に感じます。

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.4

move 0 to COUNT inspect REC-DA tallying COUNT for all "ABC" if COUNT = 0 then display "nakatta" else display "atta" end-if で"ABC"の有無を検索できますが、chr1は固定長文字列なので、 move "ABC" to chr1 して chr1 を検索すると、"ABC" の後ろに27個の空白が続いた文字列を探すことになるので、これは目的の動作とは違うでしょう。 COBOLによっては、可変長文字列を扱えるよう拡張されたものもあるかもしれません。 なお、chr1 の文字列の長さを調べるのにinspectが使えます。 move 0 len-chr1 inspect chr1 tallying len-chr1 for characters before " ". COBOLの文字列処理は、INSPECT,STRING,UNSTRINGの機能がうまくはまれば簡潔に書けますが、そうでないと標準関数が貧弱なので苦しいですね。

Mi8
質問者

お礼

固定長ならできたようですが、可変長だとうまくいきませんね。 trimして検索とかできればいいのですが。 うまい方法ないでしょうか?

回答No.3

>どのような命令で調べるのでしょうか? EXAMINEという命令をマニュアルで調べてください。 あまり使いやすい命令ではないので、自分で探査ロジックを書いても 良いとは思いますが..

Mi8
質問者

お礼

googleで調べるとソースコード内検索とかでてきましたがどのように使えばいいのでしょうか?

  • sam_inoue
  • ベストアンサー率47% (27/57)
回答No.2

もう10年位COBOLからは離れているので記憶が薄いですが、 コンパイラによって「部分参照」ができるものがあり、 それなら文字列の一部の参照は可能です。 ただ、FIND...というわけにはいかないので、 自分で開始位置を変えながらループさせて探すことになります。 「部分参照」ができないコンパイラの場合は、 03 REC-DA 05 REC-DA-C PIC X(1) OCCURS 200 として文字列は集団名にセットして、 これを1バイト単位の配列で取り出して、 1文字ずつ判定することになるでしょう。

Mi8
質問者

お礼

これだと相当時間かかりません? ABC abc AbC などを同様に扱う場合や 123 123 もいっしょに扱うとかそう言うのは標準関数で 常識的に使える物だと思いました。

noname#86752
noname#86752
回答No.1

もしあなたの職場でそういうことをしてくれるライブラリを使っていなければ、そういう無駄な作業が必要です。 アルゴリズムの勉強だと思ってやるしかないですね。

Mi8
質問者

お礼

アルゴリズムの勉強ですか。 なんか今更・・・ってショックです。 こんなにもCOBOLというのが使えない言語とは思いませんでした。 Cも結構使いづらいですけどね。

関連するQ&A

  • COBOLの文字列検索を教えて下さい。

    cobol初心者です。 「100バイトのレコードを複数件読み込み、決まった文字列を検索する」というPGMを作ろうとしています。 03 REC-1 PIC X(100) 03 REC-2 PIC X(05) という定義があるとき REC-1 = "abcdefghijklmnopqrstu…"       というデータに対して、 REC2 = "hijkl"                    の検索をしたい場合 どのようなコーディングで調べることができるのでしょうか? 何レコード目の何バイトでヒットしたかを表示したいので、 INSPECT命令は使用せず、REC-1を1バイト単位で取り出して、 1文字ずつ判定しようと思っています。 レコードを越えてのヒットは行いません。 この場合配列を使うという考え方は正しいですか? 読み込んだ100バイトのレコードを1バイト単位で取り出して比較するには、 REDEFINEを用いて再定義すると考えています。 その場合のREADでの読み込み方がよくわかりません。 コーディング例等を載せてもらえると助かります。 cobolをはじめたばかりで、基本的な知識が抜けているかもしれません・・・ よろしくお願い致します。

  • 富士通COBOLの画面定義について

    何年か前にはNECでプログラムを組んでいたのですが、最近は富士通のCOBOLでプログラムを組んでいます。富士通のCOBOLで画面の定義がよく わかりません。例えば下記の記述で FD DSP-F. 01 GM-REC. 03 GRP001. 05 GM-SYORI-K-COM PIC X(03). 05 GM-SYORI-K PIC 9(01). 上記のGM-SYORI-K-COM PIC X(03)の3バイトは何を定義しているのですか?それとこの3バイトを使ってどんな事ができるのですか? 富士通のマニュアルを見ても説明しているところがなくて困っています。 基本的な質問で申し訳ありませんが、よろしくお願いします

  • VBSで正規表現キーワード複数は?

    すみません、VBSの正規表現で改行をまたぐ検索をしたいのですが キーワードが複数の場合はどう書けばいいのでしょうか? 例:xxxxxabcxxxxxxxx改行 xxxxxefgxxxxxxxxxxx改行 xxxxxxLxxxx xは不定期文字 キーワード abc , efg , L .*abc[^efg][^L]*efg*L.*とやってもだめでした。 よろしくお願いします。

  • VB2008でブロック崩しを作っているのですが、玉は動くようになり次に

    VB2008でブロック崩しを作っているのですが、玉は動くようになり次に自機を動かそうと思いやってみたのですが動きません。 もう一つプロジェクトを作って自機を動かす文だけでやってみるときちんと動きます。 Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown Dim w As Graphics = Pic1.CreateGraphics() w.DrawImage(picback, zikiX, zikiY, rect, GraphicsUnit.Pixel) Select Case e.KeyCode Case Keys.Left : zikiX -= 3 Case Keys.Right : zikiX += 3 End Select w.DrawImage(ziki, zikiX, zikiY) w.Dispose() End Sub Private Sub ballmove() Dim g As Graphics = Pic1.CreateGraphics() tamasita = y + 28 tamawidth = x + 28 zikiwidth = zikiX + 15 zikisita = zikiY + 73 rec.X = x : rec.Y = y : rec.Width = 28 : rec.Height = 28 g.DrawImage(picback, x, y, rec, GraphicsUnit.Pixel) g.DrawImage(ziki, zikiX, zikiY) If x + 28 >= Pic1.Width Then flag_x = False ElseIf x < 1 And flag_x = False Then flag_x = True End If If y + 28 >= Pic1.Height Then flag_y = False ElseIf y < 1 And flag_y = False Then flag_y = True End If If flag_x = True Then x = x + 3 Else x = x - 3 End If If flag_y = True Then y = y + 3 Else y = y - 3 End If g.DrawImage(tama, x, y) g.Dispose() End Sub

  • COBOLのCALL文がいまいちつかめません。

    いつもお世話になっています。 WINDOWSでCOBOL85を使いながら、COBOLの勉強をしています。 JAVAを基本情報試験のために勉強したくらいの初心者です。 シーケンシャルファイルでマッチング処理を行う、 小さなプログラムを課題としている途中、 CALL文を使ってサブプログラムを作ってみてくださいと言われました。 そこで質問なのですが、 メインプログラムの集団項目をUSING指定で引数として、 サブプログラムで受け取り、処理をするまではいいのですが、 戻り値をどのようにして受け取ればいいのかが イメージがつかめません。 ・戻り値を受け取るための命令 ・戻り値は1つだと思うのですが、どの変数?に返ってくるのか (集団項目ごと返ってくる?) など、何かあればご助言をいただけないでしょうか? ソースは次の通りです。 よろしくお願いいたします。 ■メイン IDENTIFICATION DIVISION. PROGRAM-ID. MACHING_TEST. (省略) WORKING-STORAGE SECTION.   01 JUDGE_F.    03 KEY_F     PIC 9(01).    03 CHANGE_F     PIC X(06).    03 EXCEP_M     PIC 9(01). (省略) CALL "JUDGE_FEMALE" USING JUDGE_F ON EXCEPTION   DISPLAY N"エラーです。プログラムを終了します"   STOP RUN   NOT ON EXCEPTION    IF EXCEP_M = 9 THEN MOVE "ERRER!" TO FEMALE_OUT ELSE  IF EXCEP_M = 1 THEN MOVE CHANGE_F TO  FEMALE_OUT  END-IF    END-IF    END-CALL. (以下略) ■サブ IDENTIFICATION DIVISION. PROGRAM-ID. JUDGE_FEMALE. DATA DIVISION. LINKAGE SECTION. 01 JUDGE_F.  03 KEY_F PIC 9(01).  03 CHANGE_F PIC X(06).  03 EXCEP_M PIC 9(01). PROCEDURE DIVISION USING JUDGE_F. IF KEY_F = 1  THEN   MOVE "オトコ" TO CHANGE_F   MOVE 1 TO EXCEP_M  ELSE   IF KEY_F = 2 THEN  MOVE "オンナ" TO CHANGE_F  MOVE 1 TO EXCEP_M ELSE  MOVE 9 TO EXCEP_M END-IF END-IF. PROGRAM-END.  STOP RUN.

  • ファイルの拡張子だけを表示したい

    ファイルの拡張子だけを表示したい こんにちは。 Linuxのコマンドについて質問です。 とあるフォルダ配下にあるファイルをfindコマンドを使い検索し、そのフォルダ配下のファイルがどのような拡張子をもっているかを表示するコマンドを考えております。 たとえば、 /home/hoge/abc.xml /home/def.java /ghi.html /jkl.html というディレクトリとファイルがあったとして、ルートディレクトリからfindで検索をかけた場合、 .xml .java .html というように拡張子だけが抜き出されて表示される(重複した拡張子はのぞく)ようなコマンドです。

  • foreachについて

    ポケットリファレンスより foreach[★](□){■} 配列などの一連のスカラー値を持つリスト□から順に要素を取り出し、スカラー変数★に代入してからブロック内の■を繰り返し実行します。リスト値□がなくなった段階で終了します。 とあります。今解析しているプログラムで下記のようなコードがあり、数点質問があります。(このコードの前にあるDBを呼んで、$RECにデータを返しています) undef @BCOL; my($KU_REC); while ($rc = $DBr->fetchrow_hashref) { $flg_find_ku = 1; foreach $KU_RECt (@BCOL) { if ($KU_RECt->{KU_CODE} eq $REC{KU_CODE}) { $KU_REC = $KU_RECt; $flg_find_ku = 0; last; } $KU_REC = $KU_RECt; } if ($flg_find_ku == 1) { (1) push(@BCOL, {}); (2) $KU_REC = $BCOL[$#BCOL]; } } (1)@BCOLは最初要素を含んでいないように思うのですが、リファレンスの(リストの値がなくなるまで)という部分をみて疑問ですが、リストに値がないのに、foreachの中をとおるのでしょうか? (2)たとえば、とおったとして、このロジックはおなじ区コードを見つけて、見つかればフラグを0にするという処理だと思うのですが、最初の一回目は(1)(2)をとおると思います。この処理が何をしているかわかりません。@BCOLに{}を入れるとどうなるのでしょうか? また、$#BCOLは配列の引数をあらわしているように見えるのですが、いったい何番目の意味なのでしょうか? (3)スカラー変数は基本的にmyなどで宣言するかと思うのですが、foreachで使われる変数$KU_RECtの定義がみつかりません。ということはこの場合変数定義はいらないものと思ってよいのでしょうか? 私が何か勘違いしている部分もあるかと思うのですが、わかる方、どうぞよろしくお願いいたします。

    • ベストアンサー
    • Perl
  • エクセルで複数列の検索をマクロで行いたい

    A列、B列、C列に項目が、D列以降にデータが入っているシートがあります。 具体的には、  A列:商品名  B列:地域名  C列:店舗名 となっていて、ABCの順で昇順にソートがかけられています。 マクロの記録を使って一行だけを検索することは出来たのですが、(Selection.find(What:="商品名"~ となっていました)本当は、"商品名"+"地域名"+"店舗名"が一致するものを検索したいのです。 現在は、一行目で検索をかけて、後はactivecell.offset(*,*).value="地域名"のような感じで、しらみつぶしに探しています。 複数列で検索するよい方法などありましたら教えてください。

  • 正規表現でテキストの中身を置換したい(VBS)

    初心者で、もしかしたらすっごく恥ずかしい事を聞いているかも知れませんが・・・ テキストファイルの中を正規表現を使って検索し、指定(固定)文字列と置換したいのですが、どうもうまく行きません。 ソースは以下のような物です。 ----- Set FS = CreateObject("Scripting.FileSystemObject") Set ts=Fs.OpenTextFile("C:\Program Files\ABC\EFG.txt",1) myStr=ts.ReadAll repStr = "NG_PATH =D:\ABC\HIJ" Set objRE = New RegExp objRE.Pattern = "^NG_PATH.*=C:\\Program\sFiles\\ABC\\HIJ" objRE.IgnoreCase = True objRE.Global = True newStr = objRE.Replace(myStr,repStr) ts.Close Set ts = FS.OpenTextFile("C:\Program Files\ABC\EFG.txt",2) ts.Write newStr ts.Close ------- ●ポケットリファレンスの内容を見て、組み合わせながら作っています ^_^; ●置換対象ファイルの中をobjRE.Patternで指定している内容で検索すると見つかります。 ●置換対象ファイルの更新日時を確認すると、VBS実行時間で更新されています。 それから「myStr」や「newStr」は、任意の変数を宣言して、そっちを使う事って出来ますか?

  • wordマクロで検索⇒フォント変更したいが、結果がとびとびになります。

    MSwordのマクロについてです。マクロはど素人です。 「数式に使うa,b,n,p,q,r,t,u,v,w,x,y,zの文字を検索して、CMUserifというフォントに変え、サイズを2pt大きくする」 つもりで、以下のマクロを見よう見まねで作って実行したところ、うまく変更される文字とされない文字が混在してしまいます。 これはどのような理由によるもので、また、どのようにマクロを訂正すればよいのでしょうか。 --- Sub 数式用フォントに変更() Selection.StartOf wdStory With Selection.Find Do While .Execute(FindText:=\"[a-bn-np-rt-z]\", Forward:=True, Format:=False, MatchWildcards:=True, MatchSoundsLike:=False) = True With Selection Selection.Find.Execute Selection.Font.Name = \"CMU Serif\" Selection.Font.Size = Selection.Font.Size + 2 Selection.Find.ClearFormatting End With Loop End With End

専門家に質問してみよう