Understanding A Block Of Code

HT3

Member
Hi Guys,

I'm just looking at section of code and I think my understanding isn't a 100%.

Code:
 find first bfgitem where bfgitem.inentity = p-inentity and
            bfgitem.itemcode = t-bomcomp.itemcode no-lock no-error.
            if not available bfgitem then next.
            find first darwin.range where range.range = bfgitem.range no-lock no-error.
            

            find first brmitem where brmitem.inentity = p-inentity and
            brmitem.itemcode = t-bomcomp.component no-lock no-error.
            if not available brmitem then next.

            /*component by style records*/
            find first t-compstyle where t-compstyle.itemcode = bfgitem.statisticscode and
            t-compstyle.component = t-bomcomp.component no-lock no-error.
            if not available t-compstyle then do:

                create t-compstyle.
                assign
                t-compstyle.leaditem = bfgitem.statisticscode
                t-compstyle.itemcode = t-bomcomp.itemcode
                t-compstyle.component = upper(t-bomcomp.component)
                t-compstyle.productgroup = upper(brmitem.prodgroup)
                t-compstyle.compcol = substring(brmitem.itemcode,8,3)
                t-compstyle.description = upper(brmitem.description).

I've exported the bfgitem.itemcode to a file and can see there are records.

The next line "if not available bfgitem then next.", my understanding is the code will jump straight to the "create t-compstyle." (Code1.PNG) section as there are records so the section in the middle is skipped.

However I also exported the brmitem.itemcode and that also contains records ...... so I'm clearly not understanding it.

Can anyone assist and clarify?

Thanks,
Hassam
 

Attachments

  • Code1.PNG
    Code1.PNG
    21.3 KB · Views: 6

Stefan

Well-Known Member
next does not jump to a next block, it goes to the end of the currently iterating block.

CABL has a nice rule to flag next statements without a label.
 

HT3

Member
@Stefan would it not only go to the end if a record wasn't available due to the "IF NOT AVAILABLE"?

I know there are records due to the export I entered.
 

Stefan

Well-Known Member
You are not showing any iterating block, here is a simple example to get you started:

Code:
define temp-table tt field ii as int.

create tt. tt.ii = 1.
create tt. tt.ii = 2.
create tt. tt.ii = 3.

ttblock:
for each tt:

    if tt.ii modulo 2 = 0 then
        next ttblock.

    message tt.ii.

end.

 

TomBascom

Curmudgeon
Do you really need all of those FIRST keywords?

I'd quibble a bit about NEXT going to the "end". I would say that it goes to the beginning of the NEXT iteration of the block it is scoped to. If that block (like the procedure block) is non-iterating then it LEAVES that block just as if the final iteration of an iterating block is reached.
 

tamhas

ProgressTalk.com Sponsor
Clearly, a bit more context would make this clearer. Show the enclosing block ... at least the top, possibly skipping any non-problematic code between the top of the block and the code in question.
 

HT3

Member
Code:
for each t-bomcomp
            no-lock.

            if t-bomcomp.qty-req-per + t-bomcomp.qty-req-scrap = 0 then do:
                delete t-bomcomp.
                next.
            end.

            find first bfgitem where bfgitem.inentity = p-inentity and
            bfgitem.itemcode = t-bomcomp.itemcode no-lock no-error.
            if not available bfgitem then next.
            find first darwin.range where range.range = bfgitem.range no-lock no-error.
            

            find first brmitem where brmitem.inentity = p-inentity and
            brmitem.itemcode = t-bomcomp.component no-lock no-error.
            if not available brmitem then next.

            /*component by style records*/
            find first t-compstyle where t-compstyle.itemcode = bfgitem.statisticscode and
            t-compstyle.component = t-bomcomp.component no-lock no-error.
            if not available t-compstyle then do:

                create t-compstyle.
                assign
                t-compstyle.leaditem = bfgitem.statisticscode
                t-compstyle.itemcode = t-bomcomp.itemcode
                t-compstyle.component = upper(t-bomcomp.component)
                t-compstyle.productgroup = upper(brmitem.prodgroup)
                t-compstyle.compcol = substring(brmitem.itemcode,8,3)
                t-compstyle.description = upper(brmitem.description).

            end.

Thank you Stefan I've got a better understanding now. I also got my head around modulo which is a bonus.

@TomBascom @tamhas, that's all the code above, there is another program which uses the code I posted as an Internal Procedure.
 

TomBascom

Curmudgeon
That leading "for each" is an iterating loop. So your NEXT statements are going to iterate the FOR EACH.

Many people consider it a bug that you can use a period rather than a colon here:
Code:
for each t-bomcomp
            no-lock.

And you should be ending that block with an END statement.

Reading t-bomcomp NO-LOCK and then potentially DELETE ing that record is rather jarring. I suppose, therefore, that t-bomcomp must be a temp-table? (Locking doesn't apply to temp-tables since no other session can see them.)

Why are you FIND ing but never using "range" records?

I still wonder if all of your FIRST keywords are necessary. I rather doubt that they are.
 

HT3

Member
Thanks @TomBascom

This code isn't mine, t-bomcomp is a temp table and I'm not sure about the range either but It's not hurting anything so I'm going to leave it in for now.

I will remove the FIRST keywords :).
 

TomBascom

Curmudgeon
Ok, but in terms of "understanding the code" I suggest that you dig into why you are finding a record that isn't being used. It might be a simple copy/paste artifact. Or it could be that there is an undocumented side-effect outside of this block that you have shown that someone is depending on. Figuring out "why it is there" would lead to either removing it, documenting it, or improving it. Likewise with the FIRST keywords - I don't know your schema so I cannot say but if the WHERE clauses properly identify unique criteria then the FIRST is pointless and can be safely removed. If the WHERE is not unique then you need to understand why FIRST is being used and what the implications of that are - is the ordering important? If values are being copied from the found record to another record then it certainly could be. But if that is the case FIND FIRST is a poor way to accomplish that. Lastly, locking (or NO-LOCK ing) a temp-table does nothing. But coding a NO-LOCK sets expectations in a programmers mind that the record ought not to be deletable. Going ahead and deleting it is going to be confusing for the next person to come along. You should strive to make it easy on that next programmer, it could be you six months from now ;)
 
Top