Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

A problem with search statement 5

Status
Not open for further replies.

guirone

Programmer
Apr 1, 2011
8
0
0
CH
Hi All,

I'm new in Cobol and I'm facing a problem while trying to resolve a search over an internal table.I hope you can help me.

I've created an internal table

01 WT-ROLEPLAYERS.
05 WT-ROLEPLAYER OCCURS 10 TIMES
ASCENDING KEY IS WT-CDFILIAC
INDEXED BY WT-INDEX.
10 WT-CODE PIC X(10) VALUE SPACES.
10 WT-FIN-SER-ROL PIC X(23) VALUE SPACES.
10 WT-PHY-OBJ-REL PIC X(11) VALUE SPACES.

where some codes are stored in WT-CODEs.Of these codes I need to know which are the distinct ones and,only for the distinct ones, I need to retrieve other datas from database and inform corresponding WT-FIN-SER-ROL and WT-PHY-OBJ-REL of the table.

I tried to use a binary search but it looks like that it only allows to perform a statement over equal condition.

MOVE WT-CDCODE(WC-1) TO WS-CODE-AUX.
SEARCH ALL WT-ROLEPLAYER
AT END
CONTINUE

WHEN WT-CDCODE (WT-INDEX) IS <> WS-CODE-AUX
COMPUTE WS-INDEX2 = (WT-INDEX) - 1
IF WT-CDCODE(WS-INDEX2) NOT EQUAL SPACES
PERFORM 4314-RETRIEVE-DATA
THRU 4314-RETRIEVE-DATA-EXIT
END-IF
MOVE WT-CDCODE(WT-INDEX) TO
WS-CODE-AUX
END-SEARCH.

Do you know why this code is not correct?There is a way to find out the distincts WT-CODEs?
 
A search statement is for finding distinct and specific values. In other words, does a specific value exist in the table. SEARCH ALL has specific requirements as well, which you are not fulfilling, since you have to have the data sorted on the key and search on the key to make it work.

If you are wanting to find all the values that only occur once, you have to sort the data on the field you are interested in, and then look for the values that only occur once. This will not involve the search statement in any way, shape, or form.

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
Specifically, a SEARCH ALL permits only an = comparison to the search key. As soon as the WHEN condition is satisfied, the WHEN statements are processed and the SEARCH loop is exited.

If your needs are actually to do nothing when a match is found but to do something when no match is found, put a CONTINUE in the WHEN clause and put your non-match logic in the AT END clause.

One more thing: you cannot use an index in a COMPUTE or other arithmetic statement; an index can only be referenced via a SET or IF statement.

Also, last I knew <> is not a valid COBOL code, only <, >, =, >= and <= are permited. I have always used NOT =.
 
You have an ASCENDING KEY clause in your table definition. The key that you are using must be defined as one of the table elements. I don't see WT-CDFILIAC defined in the table anywhere. I assume you really want WT-CODE to be the key.

Also, if you are using the SEARCH ALL, you must be sure that all of your table elements have been put into the table in sequence by the ASCENDING KEY field. You have initialized the table to SPACES. SPACES is not larger than many other alphanumeric values. The best approach would be to initialize to HIGH-VALUES.

Your table has 10 entries. The way you have it set up, if you only fill 4 entries the other 6 have spaces. When the binary search starts it begins at the center of the table and compares that key with the value you are looking for to determine if your key is in the front half of the table or back half. The 5th entry has spaces so COBOL figures that since that entry is less than the key you are looking for, your key must be in the second half of the table. It would never find a match in the first 4 entries. With HIGH-VALUES in the unused entries, the fifth entry is larger than any key value you have and COBOL will assume the key is in the front half of the table and eventually find it (or not if it does not exist).
 
Hi all,

many thanks for you help.With your response I've ideas quite clear now about the SEARCH.Finally,I understood that,for my purpose I can't use that statement(I think...:)).

Finally I've a list of codes.Given these ones I've only to extract other data related with them in case that:

-code is not empty(code= spaces)
-code analyzed has not been previously found in the list

For example,if I've the following list:

1)A
2)B
3)A
4)(spaces)
5)(spaces)
6)C
7)B

I have to extract the information only for A,B,C.
For this reason if I could ordenate it then just with a perform varying I could obtain that information.Now...How to ordenate a list...?


Hope you can help me...
thanks
 
If your version of COBOL does not allow SORT on a table, I have a copybook which, via multiple REPLACING clauses, will do a QuickSort on any one-dimensional table.
 
guirone said:
For this reason if I could ordenate it then just with a perform varying I could obtain that information.Now...How to ordenate a list...?

Samples here:

thread209-1539290

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
Hi Glenn9999,
You reminded me of this older thread named COBOL SORT command.
Your example program TSORT for sorting internal table compiles and runs fine in ILE COBOL for iSeries (I only changed data type COMP-5 to COMP-3).
Now I can answer my question concerning the temporary file SORTTEMP:
There is no need to create the file before compiling/running the program.
Once again, thank you for the great example!
 
Hi all,

thanks for your very useful answers.Among them and due to purpose of my program,I think that I will use a copybook indicated in
thread209-1539290: COBOL SORT command,exactly on message written by webrabbit:the Shell Sort .Just few questions about it...:-(

In the part of the code you can see below,there is a reference to HOLD-ENTRY and HOLD-KEY but these variables are not declared anywhere.

1)Must them be of the same type & lenght than TABLE-ENTRY(INDEX-I)?

If TABLE-KEY(INDEX-1) > TABLE-KEY(INDEX-2)
Move TABLE-ENTRY(INDEX-2) to HOLD-ENTRY
Perform Until INDEX-2 not > GAP
or HOLD-KEY not < TABLE-KEY(INDEX-1)
Move TABLE-ENTRY(INDEX-1) to TABLE-ENTRY(INDEX-2)
Subtract GAP from INDEX-1
Subtract GAP from INDEX-2
End-Perform
Move HOLD-ENTRY to TABLE-ENTRY(INDEX-2)
End-If

2)In my case table contains also other fields.For example:
01.TABLE-A
05 TABLE-AA OCCURS 1000 TIMES
10 TABLE-ENTRY PIC X(10).
10 TABLE-ELEMENT1 PIC X(5).

Can the shell sort code be used over this table?
 
1)Yes. Both of these variables can be the subject of REPLACING as often they may already exist, used it other areas of the program.

2) Yes, just use the REPLACING clause to modify the code as it is copied.

Sorry, it has been a while since I had to use this, I forgot it was ShellSort and not QuickSort. The version of COBOL I am currently using allows the SORT verb to be appliled to an internal table.
 
Hi webrabbit,

the code is working like a king!fantastic.
Many thanks for your help.The only thing I don't understand about it, is the HOLD-KEY variable.It's referenced in this part of the code:

If TABLE-KEY(INDEX-1) > TABLE-KEY(INDEX-2)
Move TABLE-ENTRY(INDEX-2) to HOLD-ENTRY
Perform Until INDEX-2 not > GAP
or HOLD-KEY not < TABLE-KEY(INDEX-1)
Move TABLE-ENTRY(INDEX-1) to TABLE-ENTRY(INDEX-2)
Subtract GAP from INDEX-1
Subtract GAP from INDEX-2
End-Perform
Move HOLD-ENTRY to TABLE-ENTRY(INDEX-2)
End-If

but I can't find where it's defined and what is its use.
Is it really needed?
Many thanks for your help.
 
HOLD-KEY is that portion of HOLD-ENTRY which holds the table key after the statement MOVE TABLE-ENTRY(INDEX-2 TO HOLD-ENTRY.

In other words, HOLD-ENTRY must be defined simularly to TABLE-ENTRY, with the key area defined as HOLD-KEY.

Note that any of these variables can be the subject of the REPLACING clause.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top