As of December 1, 2020, Focal Point is retired and repurposed as a reference repository. We value the wealth of knowledge that's been shared here over the years. You'll continue to have access to this treasure trove of knowledge, for search purposes only.
Join the TIBCO Community TIBCO Community is a collaborative space for users to share knowledge and support one another in making the best use of TIBCO products and services. There are several TIBCO WebFOCUS resources in the community.
From the Home page, select Predict: WebFOCUS to view articles, questions, and trending articles.
Select Products from the top navigation bar, scroll, and then select the TIBCO WebFOCUS product page to view product overview, articles, and discussions.
Request access to the private WebFOCUS User Group (login required) to network with fellow members.
Former myibi community members should have received an email on 8/3/22 to activate their user accounts to join the community. Check your Spam folder for the email. Please get in touch with us at community@tibco.com for further assistance. Reference the community FAQ to learn more about the community.
I want to use WebFOCUS commands to create a loop (not an external link to another language).
Is this possible ? How ?
For example, I want to pass a string to a function, and spin through it, character by character, to pick it apart.
I've tried "-REPEAT label variable TIMES," but DM can't "see" the variable counter.
I also tried the non-DM "REPEAT" (without the "-") and it's apparently only available in MAINTAIN ?!?!?
Is there another looping mechanism that will let me do this ?
I want to make a library of functions that will require this, so -INCLUDEs won't work (unless it's the only way to accomplish loops ?)
This is what I tried in a DEFINEd FUNCTION : (NOTE This is just PSEUDO-CODE, since it DOES NOT work. Use this code ONLY an example of what I'm trying to accomplish.)
DEFINE FUNCTION CntChars (SourceString/A4028, Character/A1)
StringLength = ARGLEN(4096, SourceString, 'I4');
Count/I4 = 0;
Position/I4 = 0;
REPEAT EndLoop 35 TIMES
Position = Position + 1;
ThisCharacter/A1 = SUBSTR (4028, SourceString, Position, Position, 1, 'A1');
Count = IF ThisCharacter NE Character THEN Count + 1 ELSE ;
EndLoop
CntChars/I4 = Count;
END
Thanks for any hints I might use to accomplish this !This message has been edited. Last edited by: Kerry,
Did you not just post a wonderful technique using ARGLEN and SUBSTR to count the number of spaces in a field that could easily be modified to handle something more generic via a DEFINE FUNCTION without using variables?
Charlie, you might want to check this post. The author is Tomsweb.
Yes, that nifty little routine does work, but ironically, that is the technique that started me on my quest !
I wrote it up and tested it, and then looked "inside" to see how it worked.
This technique would work, but copying the string, extracting the spaces from the copy, and then calculating the length of each and subtracting them, while clever, seemed to make the CPU work overtime and use a lot of string space.
On a small file this may not be noticeable, but it could get very "expensive" in a large file.
I tried to examine each FIELD (in a TABLE FILE request)as a string, passing it to a DEFINEd FUNCTION that would spin though that string, and compare it to whatever character was also passed into the function (as a parameter.)
Using TABLE FILE CAR, each MODEL could be passed to my (elusive) function, as well as a ' ' argument, and a new column would be COMPUTEd, showing the number of spaces in each MODEL name.
Counting spaces (or other characters) may not seem very important, but it's the technique I was tying to find, for other loops as well as the original "count spaces" request.
I was intrigued, and determined to find a way, since it so easy to do in other, even interpreted, languages that I figured it would be workable in WebFOCUS.
I also want to be able to examine each field of a TABLE FILE request during the first traversal, and may need to loop for a variety of other reasons, so this is something of an 'academic exercise' for me to use loops in a lot of other projects where FUNCTIONs would be appropriate.
I'm finding that it is NOT so easy, but I have learned a lot along the way (mostly about DM) !
Any ideas ? Thanks for donating your brain cells to my cause du jour !
That maybe more harder than you think that is why WebFOCUS gives you the ability to create your own subroutines link the one I posted in your quest onb how to count spaces in a string.
I haven't had to worry about making "the CPU work overtime and use a lot of string space" in about 15 years ever since I stopped developing on an IBM mainframe. Perhaps there are other reasons why the CPU is working overtime. Since that can't be the case for the CAR file samples you've created, it must be happening when reading some other large database tables.
If you use the DEFINE function in a DEFINE statement, then the function is applied to each row in the table you're reading. If you use the function in a COMPUTE statement, then the function is applied to only the rows retrieved - after the selection criteria and aggregation.
What are some of the things you need to do? Get a count of a particular character in a field? As previously demonstrated, you don't need to sweep through the field to determine the count. What else?
Francis
Give me code, or give me retirement. In FOCUS since 1991
Production: WF 7.7.05M, Dev Studio, BID, MRE, WebSphere, DB2 / Test: WF 8.1.05M, App Studio, BI Portal, Report Caster, jQuery, HighCharts, Apache Tomcat, MS SQL Server
The CPU 'working overtime' is not actually happening, I just see the processes involved as a matter of efficiency.
The processing time (of the 'find spaces' algorithm) probably scales directly with file and not exponentially, so it's not too bad.
I just noticed all of that string copying and character stripping, and thought there was a quicker way.
That's the reason for my 'academic exercise' - to find another way to accomplish that.
You're quite right, inefficiencies will not be apparent when using something as small as the CAR or EMPDATA files. A routine could be extremely inefficient, and it would still execute in less time than one would notice.
I tried to use DEFINE FUNCTION to spin through the string and look at each character - a common algorithm that I have used many times - but apparently there are roadblocks (and maybe deal-breakers ?) in WebFOCUS that prevent that from happening ?
I think it should be possible without external function calls to other languages, since I am able to DEFINE a FUNCTION to get the length of each field in a TABLE FILE request :
[b][i]This code works, and simplifies the ARGLEN "(
inlength, string, outlength[CODE])function, to allow passing only the string you want measured."</b></i>
[code]
-* Find the Beginning of a Substring :
-* POSIT (parent, inlength, substring, sublength, outfield)
DEFINE FUNCTION Length (String/A2555)
-* Syntax ARGLEN(LengthOriginal, String, Length)
-* Arguments :
-* LengthOriginal
-* Length of original string (may be longer than actual string length)
-* If shorter than actual string length, only uses that many characters
-* String : string to be measured
-* Length : Name of variable to return value to calling program
-* NOTE : Name of return variable is same as FUNCTION name
Length/I4 = ARGLEN(122, String, Length);
END
TABLE FILE CAR
HEADING
"DEFINE FUNCTIONs to find length of a string"
PRINT CAR
COMPUTE Length/I4 = Length (CAR) ;
MODEL
COMPUTE Length/I4 = Length (MODEL) ;
COUNTRY
COMPUTE Length/I4 = Length (COUNTRY) ;
END
Basically I want to perform loops in a function that can be called for each row in a TABLE FILE request, and this was a good example to get that functionality working.
From what I’ve heard, it’s (next to) impossible, and so the ‘string copy, strip and subtract’ method is looking better and better !
Is this a dead end (purely in WebFOCUS) ?
Thanks for any advice ! CharlieThis message has been edited. Last edited by: Charlz,
Yes, DM's interaction with WebFOCUS is one of the lessons that I learned on the forum here ! So, I'm trying to code the apples, without the oranges spoiling the recipe !
DM only processes the code once, before the TABLE FILE request is even started, and it never looks at the DEFINEd FUNCTION again.
Since I had tried (and failed) to write a loop in a DEFINEd FUNCTION with DM (or any other way so far), I showed the example of my failed attempt as pseudo-code to illustrate what I am trying to accomplish.
What I am looking for is a way to define a variable in a DEFINEd FUNCTION that is based on one of the parameters passed into the function.
My most recent post here, illustrates that my DEFINEd FUNCTION Length works fine, but it doesn't use any variables.
My next step is to assign the value returned by ARGLEN to a variable, then assign that temp variable's value to the name of the DEFINEd FUNCTION to return it to the CALLing routine (i.e. : the TABLE FILE request).
I know it seems I'm overcomplicating it, since the technique suggested does in fact work, but I am trying to find another way that would work on values other than text.
This is something I think will be very useful, and would like to solve this intriguing problem !
Thanks for everyone's helpful suggestions and insights in my quest ! CharlieThis message has been edited. Last edited by: Charlz,
My "academic exercise" is not to say that my question has no immediate value, just that it will serve as the basis for a project that will use similar functionality that relies on this technique.
My example is just to develop a function that processes field data from a TABLE FILE request, row by row, and then processes that data using a loop of some kind.
It does not have to be a REPEAT loop; it could be anything that allows code to be repeatedly executed, and controlled by a variable that may change from row to row (in the TABLE.)
What I do like about calls to external routines is that the code can be compiled, and therefore much faster, but I'd prefer to do it within the WebFOCUS language, even if it is a challenge !
I actually need to some bit-wise processing as well, but the text example is a good place to start.
As you have found through your own trials, what you want to do (looping within a function) is not going to be possible due to the lack of a repetative processing syntax within the reporting language. However, you might be able to resort to calling a maintain process perhaps to achieve that which you require, alternatively look for a different way of doing what you need within the confines of the language. Get the old lateral thnking cap on.
For instance, to count the occurence of a particluar character in a string, Francis alluded to utilising a similar function to the one he posted but changing the space to something like the tilde "~" character before changing the target character to a space and etc. etc. This would overcome the code repetition in this instance.
One quick thought on an alternative to your required looping is to create a simple master file to describe the string being passed and then perhaps use the GROUP field attribute? (Mentioned by GamP once I think?). Needs more thought and expansion though.
The point is that WebFOCUS is a rich and quite powerful language and often the solution lies in a slightly different approach to that which is the most "logical". Some might view this as a deficiency within the language - not having power syntax such as repeat loops - and I might agree but language extension is but an NFR away. Who knows, Gerry and his team might think that particular request for an NFR is well founded and provide it. This way WebFOCUS grows and everyone benefits
In the meantime my lateral thinking cap is within arms reach and has been well used in recent years!
T
In FOCUS since 1986
WebFOCUS Server 8.2.01M, thru 8.2.07 on Windows Svr 2008 R2
WebFOCUS App Studio 8.2.06 standalone on Windows 10
Posts: 5694 | Location: United Kingdom | Registered: April 08, 2004
This is a horrendous idea but one that might work. Put all of your TABLE data into a SAVE file and then use Dialogue Manager to loop through the characters.
I have written a few in C. I have also made a few of them available for download at www.moonlightware.com. THe zip files contain the source code, some documentation (readme, fex), an a dll if you cannot compile then in a dll yourself.