FIND FIRST

velo85

New Member
Is it posible to get this work




FOR EACH table1,
EACH table 2 where table2.field1 = table1.field1.
FIND FIRST table2
IF table2 AVAILABLE THEN
UPDATE table2.field2 = somthing.

I know this procedure dont work because cant use FIND after FOR EACH.

I hope you guys understand what i want to achieve here, and if there any way to achieve this please help.

Thx for help.
 

velo85

New Member
Can you post code, i try this method and dont work for me

DEF BUFFER rom FOR rromat.
FOR EACH ralmat WHERE ralmat.brdok BEGINS "pft",
EACH rromat WHERE romat.brnal = ralmat.brnal.


FIND FIRST rom WHERE rom.izkol > 20.

DISPLAY rom.izkol.
END.
 

ForEachInvoiceDelete

Active Member
Code:
DEF BUFFER bufrromat FOR rromat.
FOR EACH ralmat NO-LOCK
     WHERE ralmat.brdok BEGINS "pft":

    FOR EACH rromat NO-LOCK
         WHERE rromat.brnal EQ ralmat.brnal:

        FIND bufrromat EXCLUSIVE-LOCK
             WHERE bufrromat."uniqueprimaryindex" EQ rromat."uniqueprimaryindex"
                NO-ERROR.
 
         ASSIGN bufrromat.sillyfieldname = 12.

    END.

END.

cus i hate joins.

Swap in your index's where needed.
 

Cringer

ProgressTalk.com Moderator
Staff member
Maybe if you explain what you are trying to do rather than posting a code snippet and letting us guess.
 

velo85

New Member
I need to update value on table2.field1 with (first found in table2) with conditions in table1 (table1.brnal = table2.brnal)
 

LarryD

Active Member
First of all, something you must do: ALWAYS specify the type of locks (NO-LOCK or EXCLUSIVE-LOCK) when reading records from any database table table. Otherwise you are asking for lock table overflows and locking issues with other users.

as to your code you posted, it makes absolutely no sense since you are always finding the same rom table record.

ForEachInvoiceDelete posted what is a valid method. to accomplish what you wanted.

Another option:

Code:
DEF BUFFER rom FOR rromat.

FOR EACH ralmat NO-LOCK WHERE ralmat.brdok BEGINS "pft",
        EACH rromat NO-LOCK WHERE romat.brnal = ralmat.brnal.

    find rom EXCLUSIVE-LOCK where rowid(rom) = rowid(rromat) no-error.
 
     if available rom
     then do:
                 display rom.izkol.   /* or update or whatever in here */
     end.

END.
 

Cringer

ProgressTalk.com Moderator
Staff member
You could further enhance this to scope the transaction to the named buffer, and thus reduce the risk of transaction issues:

Code:
DEF BUFFER rom FOR rromat.

FOR EACH ralmat NO-LOCK WHERE ralmat.brdok BEGINS "pft",
        EACH rromat NO-LOCK WHERE romat.brnal = ralmat.brnal.

    do for rom transaction:
      find rom EXCLUSIVE-LOCK where rowid(rom) = rowid(rromat) no-error.

       if available rom
       then do:
                 display rom.izkol.   /* or update or whatever in here */
       end.
    end. 

END.
 

TomBascom

Curmudgeon
I do not see how the FIRST keyword is adding any value to or is relevant in any way to achieving your stated goal.

FIRST is not a required part of every FIND statement. It is, in fact, rarely relevant and hardly ever appropriate. Adding FIRST to every FIND is a "worst practice" enshrined in some of the most execrable code bases known. It is not a coding style that anyone should emulate. You will note that neither ForEachInvoiceDelete nor Cringer soiled their code examples with such a heinous thing.

When I see FIND FIRST I immediately think "rookie programmer who has been over-exposed to some very bad habits, serious rehabilitation is needed".
 

LarryD

Active Member
Tom, don't blame Cringer! He got that from my code example which was cut/pasted from the original poster.... I did not retype it just added my .01999 worth to which Cringer added his improvement ... On the upper/lower casing and using abbreviations -- we all have our own styles. ;)
 

velo85

New Member
I do not see how the FIRST keyword is adding any value to or is relevant in any way to achieving your stated goal.

FIRST is not a required part of every FIND statement. It is, in fact, rarely relevant and hardly ever appropriate. Adding FIRST to every FIND is a "worst practice" enshrined in some of the most execrable code bases known. It is not a coding style that anyone should emulate. You will note that neither ForEachInvoiceDelete nor Cringer soiled their code examples with such a heinous thing.

When I see FIND FIRST I immediately think "rookie programmer who has been over-exposed to some very bad habits, serious rehabilitation is needed".


You are apsolute righ, i ended up with unsuported ERP software based on OE 10.1c and i try to learn some basic stuff by my self and google. Im not programmer i have some sql expirience but not even close to do some complicated stuff.

My problem is: in store we have goods, let say 1500 pices, and on orders we have 1637. I need to delete 137 pices, but they on 300+ unike orders 3- 20 on each order. So i want to delete that 137 but problm is last one i need to update for some value, and with condition from table1 delete and update in table2.
Sorry for my englis, i hope you guys understand my problem. I will attach my code so you can check.
 

Attachments

  • Skidanje robe parcijalno FINAL.txt
    1.4 KB · Views: 0

andre42

Member
Some more nitpicks which seem not to have been mentioned:
  • I think it is bad style to use a dot instead of a colon after a for each statement. I suppose this is some ancient syntax. When I first saw this I wondered why the code compiled.
  • I you want to ask if a record is available you have to use find ... no-error. Otherwise the find will just throw an (138) error. (This was silently corrected in the code example by LarryD.)
 

andre42

Member
Unless you're using structured error handling.
Well, you are technically correct, if you refer to catch blocks. I suppose it is useful to catch (138) errors when you are certain that all find statements in a block should actually find a record, ie. it is an error if no record is found. If it is allowed that some records don't exist it is better IMHO to use find ... no-error, check if the record could be found and deal with that condition immediately. In this case the data is valid and the remaining code in the block should be executed.
 
Top