Sign up on the Revelation Software website to have access to the most current content, and to be able to ask questions and get answers from the Revelation community

At 29 MAR 2001 01:00:52PM Michael Slack wrote:

I'm working in AREV 3.12. Can I put a variable condition expression in the test expression spot within an 'IF' statement? Is there any way to have a variable evaluated twice in an 'IF' statement? I'm starting to work on a report program that is going to be a bit involved and have to crank thru a good bit of data and I'm trying to find a way to help decrease the amount of processing that will go on. Once the program has the inputs from the user it can get going. Depending on the inputs, a given conditional statement is needed for the combination of user inputs. I'm thinking that if I can build before hand the test expression of the 'IF' statement that will either include or exclude data from the report that it will speed up the processing an simplify the code in that section just a bit.

Let me try to explain. I'm trying to write a report that works with our inventory rows. A single inventory item can be in multiple stockrooms. The user can specify a single stockroon or all stockrooms. independantly, they can specify a single accounting code or all accounting codes. From those two user inputs, I would like to build the test expression that will be used later and put it into a variable.

In my testing so far, no matter what variable I put into it and no matter what string is within the variable, it returns a TRUE value because the variable is not null. What I would like to find is a way to have the variable evalated twice. Once to get the string out of the variable and into the test expression of the IF statement, then have the IF statement evaluate the test expression.

This may shed some light on what I'm trying to do. I wrote this test program to see if I could do what I'm wanting to do.

INITRND TIMEDATE()

TEST_EXPRESSION=R_NUM ⇐ 25"

FOR I=1 TO 3

R_NUM=RND(101)
IF TEST_EXPRESSION THEN
  CALL MSG('RANDON NUMBER=:R_NUM:'"','A','','')
END

NEXT I

CALL MSG('PROGRAM DONE.','A',,)

STOP

Thank you for your time.

Michael Slack


At 29 MAR 2001 02:13PM Don Miller - C3 Inc. wrote:

Michael ..

You can certainly do an evaluation in an IF statement.

The problem in your post is in your test:

INITRND TIMEDATE()

* since the following expression is a literal rather than a comparison

* it will always have a value and thus evaluate to true

TEST_EXPRESSION=R_NUM ⇐ 25" ;* this will always evaluate to TRUE

* because it is non null and non 0

FOR I=1 TO 3

 R_NUM=RND(101) ;* here is where the random is set

* if you did the following:

 TEST_EXPRESSION=R_NUM <= 25  ;* this sets the test exp 1 per loop

* it will evaluate to 0 or 1

 IF TEST_EXPRESSION THEN
    CALL MSG('RANDON NUMBER=:R_NUM:'"','A','','')
 END

NEXT I

CALL MSG('PROGRAM DONE.','A',,)

STOP

I have a similar program that does a different series of selects and sorts based on what is entered in a collector window. Instead of a bunch of "IF" statements, I use a case statement, but the net result is the same.

Don Miller

C3 Inc.


At 29 MAR 2001 06:26PM Michael Slack wrote:

Thanks for the info. I wouldn't have thought of doing it that way but that gets me what I'm after. What it gets me is that once I have the users inputs, I can define the test expression that will be used later. The test expression only needs to be determined once per use. What you helped me with will eliminate the need for the code to determine which test expression will need to be used every single time data has to be evaluated for inclusion or exclusion on the report. It should make for a little cleaner code. I'll just have to make sure that I internally document this trick for anyone who has to look at this code in the future.

Thanks again,

Michael Slack


At 30 MAR 2001 04:01PM Michael Slack wrote:

After responding to Mr. Miller's suggestion where I thought my question had been resolved, the thought occured to me late last might that it won't work. What Mr. Miller suggested definately does work but it's the same as putting the test expression into the IF statement. It just adds an extra step. What I was hoping to find was a way to define the test expression in a whole other part of the program, well way from the actual IF statement. In my test code and Mr. Millers modified version, I was hoping the definition would take place at the top of the code outside of the FOR loop.

Mr. Miller did make a comment that in an example the he has coded that he used a CASE statement to determine which predefined test expresion to use. Staying with his suggestion, that would be the next logical addtion. I'm still wondering if there is a way to avoid even that. I would like to have a one time GOSUB call that once the user has entered their criteria for the report program, that the subroutine will deterime and build the test expression that will be used later and put it into a variable of some kind. Then somewhere much later in the running of the program, the appropriate IF statement some how uses the predefined test expression to determine if the current data is to be included or excluded from the report.

I guess what I'm looking for is something like in C or C++ where you can resolve or double resolve variables (like pointers). It's been a while since I've used either of those.

Thank you for your time.

Michael Slak


At 31 MAR 2001 11:34AM Donald Bakke wrote:

Michael,

I don't believe you can do exactly what you are looking for. No conditional statement I'm aware of can take a variable that contains the logical operators as values and then use them as if you had type them yourself in the code. The closest approach I know of is to create an entire mini-routine in a memory variable, write this to a file, run RPT5 so it will compile, and then call the object code. We do something like this with an application of ours. Then end user is allowed to create their own set of formulas for a report. We take these formulas and do exactly what I just described and then take their output values and display them in a report.

dbakke@srpcs.com

SRP Computer Solutions, Inc.


At 02 APR 2001 03:03AM Curt Putnam wrote:

Maaybe I don't understand (just a quick glance at what you are trying to do), but if the sum total of user input is in a collector, why not have the commuter that runs behind that collector do all the processing and load whatever variables you need into @Pseudo. That way they are computed once and available globally.


At 02 APR 2001 09:17AM Don Miller - C3 Inc. wrote:

Michael ..

It doesn't matter where the conditional is evaluated as long as it is static before your series of comparisons (IF's or CASE STATEMENTS) is executed. For Example:

* get all of the required input in a Collector window into variable @PSEUDO. This is usually an @FM delimited structure. Then you can do something like:

BEGIN CASE

 CASE @PSEUDO=FOO' ; FLAG=1 ; GOSUB PROCESS_IT
 CASE @PSEUDO=XB57D' AND @PSEUDO=12 ; FLAG=2 ; GOSUB

]]PROCESS_IT

.. and so forth

END CASE

PROCESS_IT:

ON FLAG GOSUB DO1,DO2,DO3,DO4

RETURN

You can make your case statement and subroutine as arbitrarily complex as you want or need.

Don Miller

C3 Inc.


At 02 APR 2001 10:22AM J Eagan wrote:

You can construct your own TCL command with all sorts of variety e.g.

 collector stuff to get and count the parameters codes

SELECT_CRITERIA=BY LOCATION_CODE'

  FOR I=1 TO NUMBER_PARAMS                            
      REMOVE CODE FROM CODES AT POS SETTING X       
      IF I=1 THEN                                                                SELECT_CRITERIA:= WITH LOCATION_CODE=:QUOTE(CODE)   
         END ELSE                                    
           SELECT_CRITERIA:= OR WITH LOCATION_CODE=:QUOTE(CODE)
         END                                         
  NEXT I                                            
  CMD=SSELECT INVENTORY ':SELECT_CRITERIA                      
  PERFORM CMD                                       

At 02 APR 2001 10:27AM J Eagan wrote:

Strange - some ":" concatenations were dropped from the previous.

Should read "SELECT_CRITERIA:=


At 02 APR 2001 10:52AM Michael Slack wrote:

Hello Mr. Miller:

I think that you are correct that I'll need to use a CASE statement. My problem seems to be that I want to define my test expression in one part of the program and have it evaluated in another part of the program. From my tests and yours and everyone elses comments indicate that I can't do that. I would have been nice to be able to do that, I was hoping that there might be a way. Since there isn't, I'll just need to do it the straight forward way.

Thank you for all your help.

Michael Slack


At 02 APR 2001 03:30PM Warren wrote:

Why not construct an RBasic If/Then/Else statement and do a Catalyst "C" call setting @ANS or @USERx?


At 03 APR 2001 10:22AM Michael Slack wrote:

Hello Mr. Putnam:

Let me try to explain what I'm trying to do. Ultimately I want to create a report that shows how many items of various types where issues from a given stockroom and a given accounting code. I ask the user for the name of the stockroom and the accounting code and the date range for the report. I then go thru the table containing the issue tickets using the stockroom (one issue ticket can only contain items from one stockroom) and the issue date to get the initial data. Then I go thru each issue ticket row one at a time, the ticket can have one or more stock items. For each stock item I need to get some information from the stock table. A stock item can be stored in more than one stockroom and each stockroom can contain multiple accounting codes, I need to go thru the stock item record and find the matching stockroom and accounting code. From there it's a simple matter of pulling out the associated data I need from the stock item record.

Part of the rub is that the user can select to create the report using a single accounting code or all accounting codes. There is a little more to it but that is the heart of it. The reason for the original question was to see if there was any way to avoid additional processing and code at the point of determining if within a stock item row that a particular stockroom and accounting code combination at a given subvalue position matches the criteria entered by the user. The thought accured to me that if I could define that test expression once, right after the user has finished entering their criteria for the report, that I could save some time and make the code that determines if a stockroom/accounting code combination in the stock item row is to be included or excluded more streamlined. So I'm wondering if I can create a test expression at one point in the program and plug it into the actual IF statement at another point in the program. The IF statement is the one that will determine if the current stoc

kroom/accounting code combination in the stock item rows is to be included or excluded from the report. Since for a single run of the report program, the test expression won't change, no matter how it is determined.

I hope this explains a little better what I'm trying to do.

Thank you for your time.

Michael Slack


At 03 APR 2001 12:42PM Michael Slack wrote:

Warren, could you give me an example of the CATALYST "C" you are suggesting. I ask because, I've been working with it in a test program and haven't figured out a way to make it work yet. I've been able to make the CATALYST "C" work but not in a way that is benificial to the code I'm trying to develop. Here is the abbreviated test code that I'm working with, maybe this can clarify some things. This is as close as I've been able to get but it isn't any better than typing in the expression into the IF statement and it doesn't allow for flexability of the test expression.

INITRND TIMEDATE()

* TEST_EXPRESSION=R_NUM ⇐ 25"

TEST_EXPRESSION= ⇐ 25"

FOR I=1 TO 10

R_NUM=RND(101)
CATALYST("C","@ANS=:R_NUM:TEST_EXPRESSION)
IF @ANS THEN
  CALL MSG('R_NUM=:R_NUM,'A','','')
END

NEXT I

CALL MSG('PROGRAM DONE.','A',,)

STOP

What I'm trying to find is a way to be able to set up the expression like:

TEST_EXPRESSION=R_NUM ⇐ 25'

and then have the catalyst and if statements something like:

CATALYST("C","@ANS=:TEST_EXPRESSION)

IF @ANS THEN …

If I can find a way to do that, then compound test expressions should be easy. It's just finding the trick to the process, assuming there is one.

Thank you,

Michael Slack


At 03 APR 2001 09:45PM Warren wrote:

In your catalyst example R_NUM is a variable. It must be assigned a value somewhere:

Either in the code construct:

TEST_EXP=R_NUM=2&@ANS=R_NUM LE 25"

CALL CATALYST('C',TEST_EXP)

or must be resolved prior to the catalyst call:

TEST_EXP=@ANS=:R_NUM:" LE 25"

CALL CATALYST('C',TEST_EXP)

However I don't see what the difference is if you just do:

TEST_EXP=R_NUM LE 25

TEST_EXP will always evaluate to 1 or 0

Then later on:

IF a EQ b AND TEXT_EXP THEN …

Unless the logical operator in TEST_EXP is user selectable from the query I see no need to use catalyst, which will introduce an enormous amount of overhead.


At 03 APR 2001 11:44PM Bob Carten wrote:

If I understand the problem correctly,

it is finding items fromone list in another list

this is something I would do with

loop

remove a from list_A

while a

 locate a in list_b setting b_pos then
  • process b
 end

Until b_pos

Repeat

Bob


At 04 APR 2001 09:59AM [url=http://www.sprezzatura.com" onMouseOver=window.status=Click here to visit our web site?';return(true)]The Sprezzatura Group[/url] wrote:

Michael

We've been following this thread and believe that Bob has the right idea. We would simply create nested dynamic arrays and use nested locates to identify and add to the totals.

However in view of your statement that the expression needs only be created once per program run you could do something like

NewProg=Function MyFunc(a, B); C=a * B * 1.3 ; Return C'
Convert ';' To @Fm In NewProg
Write NewProg On vProgFile, MyFunc Else Debug
Execute 'BASIC PROGFILE MYFUNC'

Then later in the code

RoutineToCall=MYFUNC'
NewResult=Function(@RoutineToCall(FirstVal, SecondVal))

Note that RoutineToCall is "soft" and can be set on the fly.

This is functionally equivalent to what Warren has suggested with catalyst "C" - we just normally tend not to use that - just personal preference.

FWIW

The Sprezzatura Group

World Leaders in all things RevSoft


At 04 APR 2001 10:42AM Warren wrote:

Actually this is my preferred way to do this too. However if several users are running the same process it could be a problem unless you generate unique names for the RBasic code, but then your files get littered with the program.

Seems to me I recall there was a way to dynamically generate object code in an RBasic program and then insert the object code into the program stack which could then be called as a cataloged program.

Dynamic locates and processing loops is a common solution to multiple parent/child data nesting. One might be able to achieve similar results with creative BTREE and Relational indexing, but again that involves a great deal of processing overhead, however you can always read the Relational index records directly since there is no tree-walking involved.


At 04 APR 2001 12:05PM [url=http://www.sprezzatura.com" onMouseOver=window.status=Click here to visit our web site?';return(true)]The Sprezzatura Group[/url] wrote:

Warren

You da man!

Forgot all about this - but a visit to the Sprezz vaults helped… (only works for programs without passed parameters so you'll have to use global variables)

Code=A=@USER0;B=@USER0;@USER0=A+B'

Convert ';' To @Fm In Code

Call Calcalyst(Code)

note - code must be uppercase.

The Sprezzatura Group

World Leaders in all things RevSoft


At 05 APR 2001 09:57AM Michael Slack wrote:

Hello Bob:

Yes, I plan on using a loop and a locate to help me get close to the data I'm looking for. The way I'm invisioning the process, I'll still need a test expression to determine if the data is to be included or not into the end report. The way the test expression is written will depend on the user inputs. Becuae of those user inputs, one of several generic test expresions can be each time a user runs the program. What I'm looking for is a way to determine that test expression once and insert it into the IF statement later when it comes time to determine if the current data is to go into the report or not. I'm hoping to avoid creating a section of code that is run everytime the program needs to determine if a set of data stays or goes.

Thanks,

Michael Slack


At 05 APR 2001 11:29AM Michael Slack wrote:

Thank you for your help. Your suggestion to use the @USERx variables in the code section of a CATALYST call is what I was looking for. In my initial testing, to make sure I understand how to make it work properly, indicates that I'll be able to easily construct my test expression for later use.

I've never created and used a Function but I'll definitly have to keep that in mind for future use. As a shop, we've tended to use symbolics instead of functions. For the current application and what I want to do and because of Warren's caution about the same program being run at the same time by multiple users, I'll propably not use the function this time but as I said, I'll keep it mind for furture use.

I would like to thank everyone for their patience, understanding and help.

Thank you,

Michael Slack

View this thread on the forum...

  • third_party_content/community/commentary/forums_nonworks/41a8730cab015bb485256a1e005d76c5.txt
  • Last modified: 2023/12/28 07:40
  • by 127.0.0.1