Search code examples
visual-foxpro

Why does this IF FOUND have a condition that is always true?


FoxPro7

Note: The word "record set" is probably not correct but I really don't understand how they work. I'm a SQL guy so I'm trying to translate. Is it a view? Is it a copy of the data? I have no idea.

Questions:

  1. If you are using the 2 record set and make a change does the change show up in the 1 record set? Maybe they both point at the same record set?
  2. How could the IF FOUND ever be false? The code compares a subset of a table to the full table. It should always be true.
  3. Is the DO WHILE affected by SKIP? It's hard to tell if the record set is fixed once you start a DO WHILE or if you can mess with the records in the loop along the way. I'm not grasping the difference between "where you are" in a loop of records and "what you are pointing at" if you change the row.

Thank you!

    Select 1
    Use tblincls    
    
    Select 2
    Use tblincls Again
    Set Filter To CLASS_CODE = '5156'
    Goto Top

    Do While Not Eof()
    
    nagency_code = agency_code
    nindex_no = index_no
    nclass_code = CLASS_CODE
    npys_exp = pys_exp
    namt_exp = amt_exp

    Select 1
    Seek nagency_code + nindex_no + nclass_code
    If Found()
        Replace pys_exp With (pys_exp + npys_exp)
        Select 2
    Else
        Select 2
        Replace CLASS_CODE With '5157'
    Endif
    Select 2
    Skip
    Enddo

    Close Tables All
    Use tblincls Excl
    Delete All For CLASS_CODE = '5156'
    Pack
    Close Tables All

Solution

  • Note: The word "record set" is probably not correct but I really don't understand how they work. I'm a SQL guy so I'm trying to translate. Is it a view? Is it a copy of the data? I have no idea.

    Based on the code sample, the "record set" is most likely a VFP table (but could be a view) that is part of a VFP database container (dbc). The reason I know this is there is one fieldname that exceeds 10 characters: a free table can only have 10 characters; exceeding 10 characters would require the table/view to be in a dbc. I will answer your questions using "table".

    Answers:

    1. The tblincls table is opened twice. Any change made to the table will be reflected in both select areas (1 and 2). Think of it like 2 users opening one shared file. Both are working on the same data file.
    2. FOUND() will never be false if there is data in the filtered table (Select 2). It won't necessarily always be true because there is a possibility that there will not be data in the filtered file in which case, the "If Found()" code doesn't get called.
    3. The DO WHILE is affected by SKIP: the filtered table (Select 2) is moved forward 1 record each loop. For example, if #1 has 20 total records and #2 (filtered) has 4 records, the code you have posted loops through #2 (1st, 2nd, 3rd, 4th). variables are created for each of the 4 records in #2 and updates are made in #1 by finding (SEEK()) the record in #1.

    Having explained all that, it looks as though all the updates made to the table are completely wiped out at the end by deleting all the records (CLASS_CODE='5156') and packing them. CLASS_CODE will never be set to '5157' based on this snippet. It doesn't make sense. This is poorly written. All it seems to do is delete records where CLASS_CODE='5156'.