Technical Questions
 Crystal Reports Forum : Crystal Reports 9 through 2020 : Technical Questions
Message Icon Topic: Multiple selections within the same string Post Reply Post New Topic
Page  of 2 Next >>
Author Message
Dreaming
Newbie
Newbie
Avatar

Joined: 26 Jan 2010
Location: Canada
Online Status: Offline
Posts: 17
Quote Dreaming Replybullet Topic: Multiple selections within the same string
    Posted: 01 Feb 2010 at 12:16pm
Hi,

I'm trying to pull several different bits of text from the same string, but due to how the data is formatted, it's proving to be a headache.

The data is from a memo field that I (think) I've managed to get into a format I can manipulate using an SQL command.  I'm using CR8.5, by the way.

Now that I can call that data in a CR expression, I don't seem to be able to delineate what I need from that rest of what's in there.  Here's a sample of what that data looks like:

EnglishText1 | FrenchText1
EnglishText2 | FrenchText2
EnglishText3 | FrenchText3
...(etc)...


The goal is to get all the English text grouped together and displayed, then all the French text grouped together and displayed.  The difficulty comes from the fact that each English/French grouping seems to be separated by a carriage return and I have no idea how to try to search for this to separate a single grouping from the rest of the string.  If I can do that, I think I can manage to use Right() and Left() to pull the two pieces apart.

I've also considered trying to find the positions of all the "|" characters and just pull the text blocks from between consecutive pairings, then work each as they are pulled.  This would create a situation of having a single English text group at the beginning, several French/English groups through the middle, and one French group at the end.  The trick is that I don't know how many English/French pairings there will be from one data set to another, so knowing when to stop looping through it will be critical.

If anyone has any suggestions or recommendations on how best to approach this problem, I'd be grateful for the input.  I'm a CR novice by the way and have no access to CR's help files (which were never installed).  So I can see the syntax I need to used, just not the logic for how the functions work.

Thanks.


IP IP Logged
kevlray
Admin Group
Admin Group
Avatar

Joined: 29 Oct 2009
Online Status: Offline
Posts: 1587
Quote kevlray Replybullet Posted: 01 Feb 2010 at 12:37pm

You might be able to do while loop and the instr() function.  You basically have to build two string variables (one for english and one for french).  As you go through the for loop, the first string found (with the pipe delimiter) would be the English.  Do a right() function to remove the English part.  Get the French part,  do another right() function and loop until you run out of string.  Of course through each loop you are concationating to the English and French Strings.

 
I hope this helps.


Edited by kevlray - 01 Feb 2010 at 12:38pm
IP IP Logged
Dreaming
Newbie
Newbie
Avatar

Joined: 26 Jan 2010
Location: Canada
Online Status: Offline
Posts: 17
Quote Dreaming Replybullet Posted: 01 Feb 2010 at 1:31pm
I think I understand the logic, but how do I "remove" a selection of text from my source data after I've concatenated it to the English and French strings that I'm building, so that I don't keep pulling the same text?

To bring it down to the most layman of terms, I think I can manage to copy data from my source to my new strings, but how do I cut it?

Also, I snooped around a bit more and found that chr(13) apparently can be used to designate a carriage return.  I tried this:

Stringvar array Pairings;
Pairings := Split({%Select_Root}, chr(13));
Pairings[1] & Pairings[2] & Pairings[3]

// %Select_Root is the SQL expression I'm using to grab the data from the memo field

It gave me partial results but it still didn't come out properly, aside from each pairing being jammed together without a space between them (I can fix that).  I haven't figured out what's wrong with it yet, but could this be viable for getting my English/French pairs together so I can just Right() and Left() them afterwards?

Thanks again.


Edited by Dreaming - 01 Feb 2010 at 1:34pm
IP IP Logged
Dreaming
Newbie
Newbie
Avatar

Joined: 26 Jan 2010
Location: Canada
Online Status: Offline
Posts: 17
Quote Dreaming Replybullet Posted: 01 Feb 2010 at 2:01pm
OK, so I've figured out why my Split() was giving my unexpected results.  The SQL expression I'm using is truncating the memo data down to 255 characters, so I'm only getting two of the four pairings, plus part of the third.

Well, at least it's one step forward and only one step back.  I'll have to give more thought to getting my data out of that wretched memo field.
IP IP Logged
kevlray
Admin Group
Admin Group
Avatar

Joined: 29 Oct 2009
Online Status: Offline
Posts: 1587
Quote kevlray Replybullet Posted: 01 Feb 2010 at 2:05pm
The instr() function returns a number of where it finds the next pipe then you would do a string := right(number+1, string).  The plus one is to get past the pipe and you need to 'replace' your orginal string with the new 'shorter' string.  Again this needs to be in a while loop and it is best to have the len(string) > 0 as your condition.
 
I hope this helps.
 
FYI: This is a form of parsing a string to get tokens, if we were using a full blown language, we would store the 'tokens' in a array.
IP IP Logged
davejwhite
Newbie
Newbie


Joined: 19 Jan 2010
Online Status: Offline
Posts: 34
Quote davejwhite Replybullet Posted: 03 Feb 2010 at 3:17am
Hi there,
 
I would use variables to store the extracted strings in. So the logic looks like this (description, not code):
 
//Set up variables:
StringVar EnglishString;
StringVar FrenchString;
StringVar ExtractedChar;
NumberVar counter;
 
1. Set counter := 1
 
2. Loop through memo field one character at a time
 
3. Load each character into ExtractedChar variable
 
4. If ExtractedChar is not the pipe character,
    a) if counter = 1,add it to the EnglishString variable else
    b) (counter = 2 so) add it to the FrenchString variable
 
5. If ExtractedCharacter is a pipe character,
    a) if counter =1 then
    b) Add a separator of your choice to the EnglishString variable, and
    c) set counter to 2, else
    d) Add a separator of your choice to the FrenchString variable, and
    e) set counter to 1
 
This should work the memo string, switching between English and French pairings and extracting to the respective string variables.
 
You would then need separate formulas to display the results of the EnglishString and FrenchString variables.
 
Food for thought!
IP IP Logged
Dreaming
Newbie
Newbie
Avatar

Joined: 26 Jan 2010
Location: Canada
Online Status: Offline
Posts: 17
Quote Dreaming Replybullet Posted: 03 Feb 2010 at 7:13am
This would probably save me some headaches since what I was playing with depended on locating carriage returns to delineate the sections I wanted to pull, but would probably break down at the last string since I'm not sure the memo even ends in a carriage return.  Some may and some may not.

This is the logic for the SQL expression, right?  Will those variables get passed back the CR form once it's finished running?

Figuring out the SQL stuff has been quite troublesome.  Several of the functions I'm using aren't even recognized by the SQL expression editor, yet still work, and the ones pulled right from the editor throw a syntax error.  Very confusing.  It took me two days to figure out the comment characters were /* */, instead of //.  Hadn't seen that before.

I'll give it a try with variables and see how it goes.  Fingers crossed.  Thanks very much for the tips.


Edited by Dreaming - 03 Feb 2010 at 7:13am
IP IP Logged
kevlray
Admin Group
Admin Group
Avatar

Joined: 29 Oct 2009
Online Status: Offline
Posts: 1587
Quote kevlray Replybullet Posted: 03 Feb 2010 at 7:37am
I was thinking of using a CR function, it gives you the ability to use the instr() function.  If I have time today, I will see if I can build up a function to show you want I mean.  The big issue is always having a delimiter in the string that will be there, so I will be assuming some things.  1. The first part of the string is English up to the pipe.  2nd the rest of the string up to the Carriage return is French (the last section will be handled special).
IP IP Logged
davejwhite
Newbie
Newbie


Joined: 19 Jan 2010
Online Status: Offline
Posts: 34
Quote davejwhite Replybullet Posted: 03 Feb 2010 at 8:12am
No, I would do this in Crystal formulas
IP IP Logged
kevlray
Admin Group
Admin Group
Avatar

Joined: 29 Oct 2009
Online Status: Offline
Posts: 1587
Quote kevlray Replybullet Posted: 03 Feb 2010 at 8:58am
Here is an an example.  Be aware I do not have any data to test this against, thus it could fail.  The syntax is correct and I did not add any spaces to the text (it may be needed).  Lots of luck.
 
stringvar workstr := {memofield};
stringvar englishstr;
stringvar frenchstr;
numbervar del;
while len(workstr) > 0 do
(
    del :=instr(workstr, "|");
    englishstr := englishstr + left(workstr,del -1); // get left part of string minus the delimiter
    workstr := right(workstr, del +1); //  remove english part - delimiter
    del :=instr(workstr, chrw(13));  // look for a carriage return
    if  del = 0 then // no more string
        (
        frenchstr := frenchstr + workstr;
        workstr := "";
        )
    else
        (
        frenchstr := frenchstr + left(workstr, del-1);
        workstr := right(workstr,del+1);
        )
);
IP IP Logged
Page  of 2 Next >>
Post Reply Post New Topic
Printable version Printable version

Forum Jump
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot delete your posts in this forum
You cannot edit your posts in this forum
You cannot create polls in this forum
You cannot vote in polls in this forum



This page was generated in 0.031 seconds.