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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Comparing User-Input to Master-Record 1

Status
Not open for further replies.

progolf069

Programmer
Jun 13, 2001
37
US
This is a similar question to the one I posted a few weeks ago about P.O. Boxes, but this time I need to compare data inputed by the user to a field in a file. The application is a e-mail search engine on our main frame at our office. Our employees, if they would like to be able to look up another employee's e-mail address they will be able to by inputing that employee's name, and it would return their address on the screen.

Code:
Example:

Example Data File: (top line not part of file, only for identification purposes)

Employee Name            Employee e-mail
John Doe                 doey@ourname.com
Sue Smith                ssmithy@ourname.com
John Nondoe              notdoey@ourname.com
Sara Smith               ssmith2@ourname.com
Bill Jones               bjones@ourname.com
If the user inputed John, they would get a result that looks like this:
Code:
  Employee Name              Employee e-mail
------------------       -----------------------
John Doe                 doey@ourname.com
John Nondoe              notdoey@ourname.com

If the user inputed Smith, they would get a result that looks like this:
Code:
  Employee Name              Employee e-mail
------------------       -----------------------
Sue Smith                ssmithy@ourname.com
Sara Smith               ssmith2@ourname.com

If you can provide me with any ideas, I would appreciate it! Thanks again for everybodys advice! It is very appreciated!

Ian


Here is the important parts of my program currently: (minus the large screen section that is irrelevent to this post)

Code:
       IDENTIFICATION DIVISION.
       PROGRAM-ID. emaildir.
       AUTHOR. IAN WICKLINE.
       INSTALLATION. K'S MERCHANDISE INC.
       DATE-WRITTEN. JULY 18 2001.

      ******************************************************************
      *      ALLOWS USER TO SEARCH FOR E-MAIL ADDRESSES FOR CORP       *
      ******************************************************************

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT INPUT-FILE
               ASSIGN TO 'C:\EMAIL\ksemail'
           ORGANIZATION IS LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD  INPUT-FILE.
       01  INPUT-REC.
           05  NAME-OUT                    PIC X(30).
           05  ADDRESS-OUT                 PIC X(25).

       WORKING-STORAGE SECTION.
       01  INPUT-RECORD.
           05  NAME-IN                     PIC X(30).
           05  ADDRESS-IN                  PIC X(25).
     
       01  ARE-THERE-MORE-RECORDS          PIC XXX VALUE "YES".
       01  ARE-YOU-SURE                    PIC X. 
       01  SHOW-EMAIL                      PIC X(43).
       01  SHOW-MORE                       PIC X.
       01  L-CTR                           PIC 99 VALUE 4.
       01  WS-NAME.
           05  SEARCH-NAME                 PIC X(30).
       01                   REDEFINES WS-NAME.
           05  NAME-CHAR OCCURS 30 TIMES PIC X.
       01  WS-REC-NAME.
           05  REC-SEARCH-NAME             PIC X(30).
       01                   REDEFINES WS-REC-NAME.
           05  REC-NAME-CHAR OCCURS 30 TIMES PIC X.
       01  CTR                             PIC 99.
       01  INSPECT-CTR                     PIC 9.
       01  EXIT-PROG                       PIC X VALUE " ".


       PROCEDURE DIVISION.
       100-MAIN-MODULE.
           OPEN INPUT INPUT-FILE.
           PERFORM 250-PROMPT-RTN.
           GO TO 999-EXIT.

       250-PROMPT-RTN.
           DISPLAY TITLE-SCREEN
           DISPLAY SEARCH-SCREEN.
           ACCEPT SCR-NAME-IN
      *    IF NAME-IN = " "
      *        GO TO 999-EXIT
           DISPLAY DETAIL-LINE-HEADER-SCREEN
           PERFORM UNTIL ARE-THERE-MORE-RECORDS = "NO "
               READ INPUT-FILE
                   AT END
                        MOVE "NO " TO ARE-THERE-MORE-RECORDS
                        GO TO 500-SEARCH-AGAIN
                   NOT AT END
                        PERFORM 300-COMPARE
               END-READ
           END-PERFORM.

       300-COMPARE.
           MOVE FUNCTION UPPER-CASE (NAME-IN) TO NAME-IN
           MOVE FUNCTION UPPER-CASE (NAME-OUT) TO NAME-OUT
           STRING 
               NAME-IN DELIMITED BY ' '
               INTO WS-NAME
           STRING 
               NAME-OUT DELIMITED BY ' '
               INTO WS-REC-NAME
           MOVE ZEROS TO CTR
           MOVE ZEROS TO INSPECT-CTR
           PERFORM VARYING CTR FROM 1 BY 1
               UNTIL CTR > 30
               IF NAME-CHAR(CTR) = REC-NAME-CHAR(CTR)
                   ADD 1 TO INSPECT-CTR
                   IF INSPECT-CTR > 4 
                       MOVE 50 TO CTR
                       PERFORM 400-ADD-NAME.    

       400-ADD-NAME.
           MOVE SPACES TO SHOW-EMAIL
           STRING 
               ADDRESS-OUT DELIMITED BY ' '
               '@ksmerchandise.com' DELIMITED BY ' ' 
               INTO SHOW-EMAIL
           ADD 1 TO L-CTR
           DISPLAY DETAIL-LINE-RECORD-SCREEN.
 
       500-SEARCH-AGAIN.
           DISPLAY SEARCH-AGAIN-SCREEN
           ACCEPT SCR-MORE
           IF SHOW-MORE = 'Y' OR 'y' OR " "
               PERFORM 250-PROMPT-RTN.

       999-EXIT.
           CLOSE INPUT-FILE.
           STOP RUN.
 
Hi Pro,

Stephen is right. If you use seq files you'd need one sorted by last name and one sorted by first name. Then read up the appropriate file (depending on the input) until you find the name. Ugh!

Indexed files is the way to go.

Regards, Jack.
 
Hello!

I essentially agree with the two posters above. Create two parallel indexed files of email addresses. One will have the last name (without the suffix -- see paragraph below) as the key, and the other will have the first initial as the key. Then move the name imput into a Working Storage field and do the string commands so that the incoming last name or incoming first initial has the appropriate email format that matches the format used in both indexed files of email addresses.

You will also have a Working Storage table defined for display purposes.

Looking at your format, which uses suffixes such as '1' or '2' for otherwise identical email addresses (as with Sue and Sara Smith), in your last-name indexed file, you would have to define this trailing byte separately from the last name field and your first initial field. Then use the last name (without the trailing suffix byte) as the primary key.

Do a search of the last-name indexed file. Any time the search hits the primary key, then load that record into a Working Storage table. Also load the suffix byte after the last name into your table so that it can be displayed as part of the email addresss.

After this, do a search of the first-initial indexed file. Any time you get a hit, load these addresses into your Working Storage table.

After you complete both searches, display the contents of your table.

Hope this helps, Nina Too
 
And to add: do you have DB2 (or something similar) available? If you do, then you could create a DB2 table for your master file, and then create two cursors, one for last name, without the suffix. The other indexed on the first initial. Do two fetches, one on each cursor. Each time a fetch is done, load the record into your WS display table. Then display your results.

Hope this helps, Nina Too
 
My question is what if someone has an odd name that is spelled differently; For instance Micheal and Michael. Or possibly the start of the name is different in the examples Aaron and Erren, or Shelly and Chellie.

We have had to solve similar problems, but on the scale of looking at a list of 9,000 students or so. One solution we came up with is using a process that transforms each persons name into the same code that is used for the US Census, and then looking for similar name spelling. We added this to the (vsam) alternate file key to make searching better. The Census Code is about 5 characters, I Think they call it a soundex code. Even with our large amounts of data we can usually get the list down to 1 to 5 pages with screens of 20 each on a character display terminal using CICS if we look at the first and last name. We also added other parameters like Gender and age to sort by.

You may want to be able to look up people by Department. Sometimes you can't remember a name but you know where they work. This can limit the amount quite a bit.

Another approach would be to be able to use an index and a search method that looks for the first occurance of a match and shows the next 20 in the list. Then by using the index you could go 20 back or forward at a time. I know in a database you would use "LIKE A*" to make a list of all of the A's.
 
You really need a relational database, such as DB2, for this sort of thing. That way, you could do SQL commands with cursors and fetches, which get you all the fields which resemble what you are looking for. What sort of data base set-ups do you have available?

In DB2, a cursor is defined in the Data Division. It consists of a SQL "Select" statement which would be designed to get several records (rather than just one record) which resemble the criteria which you want.

In SQL, you can say "Select LastName where IncomingLastName = "Smith." And you'll get all the Smiths. Or you can do a "Select like" where you would say something such as "Select LastName where InComingLastName Like Sm_th_" and this would get not only the Smiths but all the Smyths as well. And the Smythes and Smith2 and Smith3, etc.

You can define more than one cursor. One could be based upon the last name, another on the first name or initial, another on department.

At any rate, after you define the cursor in the Data Division, in the Procedure Division, you "Open" the cursor, then do a "fetch" of each of these records that have been selected in your cursor.

It's sort of like a sequential or VSAM read in that you fetch a record, do something with it, fetch the next record, do something, etc. etc. until you get to the end. You should load each of these records from each cursor that you have defined into a Working Storage table, then decide what to do with each one, decide whether it fits the final criteria for display.

Hope this helps, Nina Too
 
Thinking about this a bit more, if you don't have DB2 or some other database available (and thus don't have the "select like" feature readily available), you could set up a VSAM file so that each letter of the last name is a separate field, or as elements of a table i.e.

05 LAST-NAME OCCURS 9000 TIMES.
10 LAST-NAME-BYTE OCCURS 20 TIMES PIC X(1).
05 FIRST-NAME OCCURS 9000 TIMES.
10 FIRST-NAME-BYTE OCCURS 20 TIMES PIC X(1).

Then of course, each byte (each letter) would be defined in your code as LAST-NAME-BYTE (STUDENT-SUB, BYTE-SUB). You would have to do a byte-by-byte comparison to decide which names to include and which ones not to include. It's a pain to code, but it will work.

Or you could set it up something like this:

05 LAST-NAME OCCURS 9000 TIMES.
10 LAST-NAME-FIRST-3-LETTERS PIC X(3).
10 LAST-NAME-NEXT-4-LETTERS PIC X(4).
10 LAST-NAME-NEXT-5-LETTERS PIC X(5).
10 LAST-NAME-LAST-3-LETTERS PIC X(3).

And do the same with first name, department, etc. This way, it's in "chunks" rather than byte-by-byte. The HUGE problem with this method is that the names might or might not ressemble each other exactly as these "chunks" are set up.

Anyway, hope this might help. But I do hope that you have some sort of database so you don't have to do this. :-s

Nina Too
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top