RobertP
11th August 2012, 11:37
Hi

I'm trying to ensure that the file being imported (3gl... not using exchange) has the correct number of fields per record/string (there should only be 3 in this instance)

Is there a simple way to count the number of decimals ? I cant find such a function. String scan works for this purpose but only if the numer of fields is less than 3. If number of fields in the asci file (for the specific record) is greater than 3 it simply concats the last field (in this case # 3) with the extra fields (incl the delimter/s). So the third delimiter is ignored.

example:
file should contain 3 fields (seperated by 2 delimiters)
if the record has 4 fields (and 3 delimiters) e.g.
X|Y|Z|1
then string.scan returns
Field 1 = "X"
Field 2 = "Y"
Field 3 = "Z|1"

What I want is an error stating something like "number of fields in file is incorrect"

One would assume that a simple function should exist, which, could count the number of delimiters in a string. This would be a simple fix to my problem. Does this function exist or do I need some funky work around?

Your input appreciated
Thanks

mark_h
12th August 2012, 23:04
Hmmm - never thought of this, but most of my scripts check for <# of fields. You can run a if pos(field 3, "|") > 0 then send an error message. I can't think of a function that counts just the separators.

shah_bs
13th August 2012, 19:02
You would need to write the function.

For example, here is the one that I use - maybe write a similar one for yourself.




function extern domain tcmcs.long tccomdllzzzz.count.chars(
domain tcmcs.s999 i.string.c,
domain tcmcs.long i.string.length.c,
string i.separator.char.c)
{
domain tcmcs.long p.posn.c
domain tcmcs.long p.chars.c

p.posn.c = 0
p.chars.c = 0

p.posn.c = p.posn.c + 1
while p.posn.c <= i.string.length.c
if i.string.c(p.posn.c;1) = i.separator.char.c
then
p.chars.c = p.chars.c + 1
endif
p.posn.c = p.posn.c + 1
endwhile

return(p.chars.c)
}

vahdani
14th August 2012, 16:41
Hi,

here is my usual solution:


string fields(50, 10)
long number.of.fields
string record.string(200)

....

number.of.fields = string.scan( record.string,
"%s|%s|%s|%s|%s|%s|%s|%s|%s|%s",
fields(1,1), fields(1,2),.....)
if number.of.field = expected then
long.var1 = lval( fields(1,1))
stringvar = trim$(fields(1,2))
etc....
else
|give error
endif
.....

BaanInOhio
16th August 2012, 21:12
Depending on the level of your tools, you can use a repeat/until loop and the 'pos()' call. You will know if your tools set does not support the offset in POS if you get a 'too manu arguments' error during compile. In LN, you have to set the TIV on the script to at least the base for the version (FP).



| 'delimit.count' is the number of 'delimeter' characters in
| the 'buffer' string.

delimit.count = 0
mypos = 1 | Start search at character #1
repeat
mypos = pos(buffer, delimiter, mypos)
if (mypos > 0) then
| Delimiter located, count it.
delimit.count = delimit.count + 1

| Advance start position of next search, avoiding overflow
| when the last character of the string is a delimiter.
mypos = (mypos < len(buffer)) ? mypos + 1 : 0
endif
until mypos = 0


This method doesn't limit your search by number of expected characters (which you have to do in string.scan) and can be used for characters other than delimiters to determine numbers or special characters in a string.

Pieter van de L
18th August 2012, 15:12
Why not use the function stringscan$() then you can extract all the data from the imput string and at the same time check the number of fields.

Regards,

Pieter

BaanInOhio
20th August 2012, 14:49
Why not use the function stringscan$() then you can extract all the data from the imput string and at the same time check the number of fields.

Regards,

Pieter

Can use string.scan when you have a maximum number of fields that you will be expecting since the mask string is fixed, based on the number of fields between the delimiters. In the example that I provided, I could have none, one or a hundred instances of a delimiter/character. This way doesn't depend on the number of characters/delimiters in the mask.

sareen.sachin02
29th August 2012, 13:10
You can use String.scan function for this. We can add as many strings as we want

Like
ret.num = string.scan(rec,"%s,%s,%d,%d,%s,%s,%s,%f,%f,%s",mitm,opro,opno,seqn,tano,cwoc,tano.n,rutm.n,prte.n,exin.n)

mark_h
29th August 2012, 14:36
You can use String.scan function for this. We can add as many strings as we want

Like
ret.num = string.scan(rec,"%s,%s,%d,%d,%s,%s,%s,%f,%f,%s",mitm,opro,opno,seqn,tano,cwoc,tano.n,rutm.n,prte.n,exin.n)

That is not the issue - in this case he wants to confirm that only x number of fields are read. So for example if your record contains a,b,c - when you do ret.num=string.scan(rec,"%s,%s", field1, field2), you get field1 containing a and field2 containing b,c. He was wanting to know if there were more fields than expected. In this case string.scan returns 2 in ret.num, but robert was wanting a way to get 3. So string.scan does not work.

Amit_Jain
30th August 2012, 06:30
Hi Mark/Robertp

Taking Mark's example

if your record contains a,b,c - when you do ret.num=string.scan(rec,"%s,%s", field1, field2), you get field1 containing a and field2 containing b,c.

I would suggest you use string.scan as follows

ret.num=string.scan(rec,"%s,%s,%s", field1, field2, field3) (Add 1 field more than you expect in the input string 'rec')

Now if ret.num contains 2 then you can be sure that 'rec' contains 2 fields and if ret.num contains 3 then certainly 'rec' contain more fields then actually required

I accept this is not a perfect solution and it would be better if you use solution provided by 'Baaninohio' but this is an quick n easy fix for your situation

mark_h
30th August 2012, 14:49
Good solution Amit. In my case this would have worked good if I had coded it that way to start. What I noticed when creating some of my | or , delimited files sometimes excel tosses on extra ,'s at the end. So I usually just pull up an editor and do a replace. I am not sure how our users manager to create some of these files. :)

Baaninohio is good also - just more coding.

RobertP
4th September 2012, 15:44
Thanks for the help folks. I'l try the different options.

Cheers