What does String formatter "<<<&" in Informix 4GL code mean? - string-formatting

I am reading through a legacy 4GL script. In the report section I came across the following:
int_type_variable USING “<<<&”
I understand this is supposed to convert the integer into a String using the String formatter.
According to IBM Informix page,
< : This character left-justifies the numbers in the display field. It changes leading zeros to a null string.
& : This character fills with zeros any positions in the display field that would otherwise be blank.
The int_type_variable is generally 4 digit. I'm confused what it is supposed to do.
I would be grateful, if someone could explain with an example.

For the What or Why, a USING utilising "<" generally indicates that the developer did not want any excess space between the number and whatever was to its left, normally a title or label for the number you are looking at. So in your case, your report might be saying ...
Number of Records Found: 1
as opposed to say ...
Number of Records Found: 1
You might say that is not so bad with an expected maximum value of 9999 but say expected maximum value was 99999999999 then if you did not use "<" then you might end up with ...
Number of Records Found: 1
that is a big space between the number and its label and the possibility that the report reader would not interpret the label as belonging to the number.
You would not use "<" if you wanted the digits to align vertically. Then you would most likely be using "#" instead.
The "&" is used to indicate what to do if value is zero. In this case it is saying that if the value is 0 to display a single 0 ...
Number of Records Found: 0
If you had "<<<<" then no value would be displayed ...
Number of Records Found:
or if you had "&&&&" then leading zeros would be displayed...
Number of Records Found: 0001
Also your link wasn't to an Informix-4gl reference. You can use the Genero link in this instance http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_DataConversions_format_numbers.html for some more examples. I don't think we have added any characters to the 4gl syntax in this area.

It's not very clearly defined, but the idea is that the number should be left-justified, and if it is zero, the zero digit should be displayed. You mention that you saw this in a report, presumably as part of a PRINT statement. You could easily explore what it does with the DISPLAY statement (outside a report):
MAIN
DEFINE i INTEGER
FOR i = -10 TO 1000 STEP 5
DISPLAY "==", i USING "<<<&", "==" # Optionally drop the "==" strings
END FOR
END MAIN
You could experiment with alternative formats to see what the differences are, such as:
"<<<<"
"-<<<"
"-<<&"
"####"
"###&"
"---&"
"-##&"
"-&&&"
"-###"
etc.
You could try them all at once with a single DISPLAY statement, or compile the program repeatedly, or pass the format string to a function which does the display work, or …
If you must do it with a report, then you can write a simple report and test it:
MAIN
DEFINE i INTEGER
START REPORT test_formats
FOR i = -10 TO 1000 STEP 5
OUTPUT TO REPORT test_formats(i)
END FOR
FINISH REPORT test_formats
END MAIN
REPORT test_formats(i)
DEFINE i INTEGER
OUTPUT
TOP MARGIN 0
BOTTOM MARGIN 0
LEFT MARGIN 0
PAGE LENGTH 1
ON EVERY ROW
PRINT COLUMN 1, "==", i USING "<<<&", "==",
COLUMN 11, "==", i USING "-<<<", "==",
COLUMN 21, "==", i USING "-<<&", "==",
COLUMN 31, "==", i USING "####", "==",
COLUMN 41, "==", i USING "###&", "==",
COLUMN 51, "==", i USING "---&", "==",
COLUMN 61, "==", i USING "-##&", "==",
COLUMN 71, "==", i USING "-###", "=="
END REPORT
Warning: No I4GL compiler was consulted about the validity of any of the code shown!

Related

Why is this Loop not working in qlik sense script?

I am having a problem trying to do a FOR LOOP as it produces no values.
I am doing 3 steps, but not sure what is the problem, I have attached the APP.
/// 1. These are the FOR values to PASS for the variables below.
for i= -1 to -7 ;
for j=-8 to -15;
for z= -16 to -21
//// 2.These are variable FUNCTIONS with same structure
LET
V_result1=(sum(Peek(Result_1,$i))*0.45+sum(Peek(Result_1,$j))*0.35+sum(Peek(Result_1,$z))*0.2)*1/5;
V_result2=(sum(Peek(Result_2,$i))*0.45+sum(Peek(Result_2,$j))*0.35+sum(Peek(Result_2,$z))*0.2)*1/5;
//// 3. The table where to apply those VARIABLES from a RESIDENT table.
DATE_PRODUCTION_4;
LOAD
"Date",
Sum($(V_result1)) as Forecast1,
sum($(V_result2)) as Forecast2
Resident [DATE_PRODUCTION_3]
GROUP BY "Date";
APP TEST
Couple of things going wrong here:
If we look here, we see this:
Argument Description
field_name Name of the field for which the return value is required. Input value must be given as a string (for example, quoted literals).
"Input value must be given as a string (for example, quoted literals)."
So instead of:
Peek(Result_1,$i)
You should use:
Peek('Result_1', $i)
If we look here, we see this:
When using a variable for text replacement in the script or in an
expression, the following syntax is used:
$(variablename)
So building on step one, instead of this
Peek('Result_1', $i)
You should use:
Peek('Result_1', $(i))
Your for loop starts at -1 and goes to -7, but in the app you added, -7 will always return NULL, since your data only consists of 4 rows. So change your for loop to a smaller range and first start of with one loop, then nest another for loop and then nest another. That way you can solve it step-by-step.

Sybase - how can extract part of a text from a field with repetitive strings?

I have got fields like this:
UPDATE</transactionType><column><name>prio</name><newValue>5</newValue><oldValue>1</oldValue><newValue>aaa<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>
UPDATE</transactionType><column><name>prio</name><newValue>51</newValue><oldValue>11</oldValue><newValue>bbb<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>
and I am trying get extract text after first <newValue> from the left side. It will be either one or two numbers/letters. Also, at the same time I want to get first <oldValue> looking from left. SO the results are:
newValue oldValue
5 1
51 11
The usual mysql commands SUBSTRING_INDEX and REGEXP_SUBSTR do not work.
Please note that I need to do it without defining any variables.

Unpacking set in string format in python only returns first value

I have converted a DataFrame Column into a set, and I am trying to format the values into a string using the * to unpack it like a list. However, it only returns the first value.
I am using the python-docx to automatically create reports based on the data.
This code selects a column of a DataFrame, drops blank values and converts it into a set. The idea is to eliminate duplicates. The next step uses the format function to enter the set into a string or the report:
set_unique_statgroup = set(self.internal_df.StatGroup.dropna())
self.document.add_paragraph("{} categories have been found, and they are: {}".format(len(set_unique_statgroup), *set_unique_statgroup)
The code returns the following sentence:
"12 categories have been found, and they are: Temperature"
I was hoping it would display all of the items in the set:
"12 categories have been found, and they are: Temperature, Mood, Time of Day (...)"
I have found a workaround, possibly not the most pythonic:
Use a loop and the add_run function to add to the paragraph for each item in the set:
for item in set_unique_statgroup:
p.add_run("{}".format(item))
p.add_run(".")
If anybody has a more compact/pythonic way of doing it, please feel free to post.

using schema files with decimals for datastage file sequence import

I have a series of CSV's I import into a database via Datastage. I am attempting to do this using RCP and schema files.
I generate the schema files from the CSVs using an accompanied master table list that comes with the CSVs.
I am down to one problem. When I find that a numeral is the last column in a particular table, it is the last entry in a schema file. My problem is null handling. The CSV is comma-delimited, double quoted for strings, and no data for null.
The master list identifies some of these number columns as number(), which is indicative of an oracle description of the output. To that end, I am trying this:
:nullable decimal[38,9] { default=0, text };
in this example, the scale and precision are defaulted, to 38,9....unless specified elsewhere, such as decimal[10,2].
A null entry results in this error:
When validating import/export function: APT_GFIX_Decimal::validateParameters: the decimal "text" format is variable length, and no external length is specified;
you should possibly specify an appropriate "width" property; external format: {text, padchar=32, nofix_zero, precision=38, scale=9, round=trunc_zero, ascii}. [decimal/impexp.C:939]
so I tried:
:nullable decimal[38,9] { default=0, text, width=47 };
in this example, the scale and precision are defaulted, to 38,9. The width is the sum of the two values (38 + 9 = 47...unless specified elsewhere, such as decimal[10,2].
and I got:
ODBC_Connector_3,0: Input buffer overrun at field "", at offset: ### [impexp/group_comp.C:6006]
Lastly, I tried exactly what it said, and did this:
:nullable decimal[38,9] { default=0, text, padchar=32, nofix_zero, precision=, scale=, round=trunc_zero, ascii, width=47 };
in this example, the scale and precision are defaulted, to 38,9. The width is the sum of the two values (38 + 9 = 47...unless specified elsewhere, such as decimal[10,2].
For this third time, I received this error: Input buffer overrun at field "", at offset: ### [impexp/group_comp.C:6006]
Has anyone ran into this? this only happens if decimal is the last column in the table.
my record settings are: {intact, final_delim=none, record_delim='\n', charset='UTF8', delim=','}
Thank you very much.
I had the same issue. I tried to put the solutions mentioned in the above answer as well as question. It didnt work. Turned out, my target column had - decimal(14,10), i.e. 4 digits before decimal point and 10 digits after decimal point. I was getting null values in the target even though i had actual data at the source. But the issue was source had more than 4 digits before the decimal. I modified target and source column to decimal(16.10). On top of this, like mentioned in the question, we shouldn’t put decimal columns in the end when we are using schema files. I put a string column in the end at source, Combined both of these and viola! I could see my data properly loaded in the target.

Tdbf/tdataset sorting multiple fields in delphi

I have a delphi application that uses tdbf which is based on tdataset with the advantage of not requiring bde engine. I needed the table to be sorted and I did this one a single field by adding an indexdef and then specifying the indexfieldnames.
I am trying to now get it to sort on 2 fields ie group men together and then women together and then have each group sorted on salary so that we see females from lowest earner to highest earner followed by men in the same way.
I have read every piece of material stating that you simply specify sortfield of the indexdef as 'gender+salary'. When I try use the index I get told that '+' is not a valid fieldname. I have tried every delimeter from '.'. ','. '&' and ';'. Every delimeter gets picked up as a field that doesn't exist. What is the correct way to sort a table on multiple fields?
Thanks in advance
Clinton Brits
xBASE (dBASE and it's derivatives) requires that fields in an index all be converted to the same data type, typically strings. To do that typically requires some common functions:
DTOS() - Converts an xBASE date to the format CCYYMMDD as a string
STR() - Converts a numeric to a string, with an optional width specifier (default 10) and number of digits to the right of the decimal point. Specifically, the syntax is specified as STR(<numeric> [, <width> [, <decimaldigits>] ]).
SUBSTR() - Extracts a portion of a string from another, with a specified starting position and number of characters
IIF() - Immediate IF, used to convert logicals (eg., IIF(Married = .T., 'Y', 'N')
Index expressions are indeed combined with the + operator. The error you're receiving is probably because you haven't converted to a common data type.
As you've specified the Gender column (probably defined as CHAR 1) and Salary column (probably a NUMERIC of some size), you can use something like
Dbf1.AddIndex('GENDER_SAL', 'GENDER + STR(SALARY, 10, 0)', []);
This creates a index on an expression like F 10000, F 200000, M 12000, where SALARY is converted to the default width of 10 characters (left padded with spaces) and no decimal digits. This should work for you.
I have not used the component, but it looks like they want to use index expressions that are similar to what we used to use in dBase III. On page 7 in the PDF version of the documentation, they offer an example under the Expressions topic:
Dbf1. AddIndex('INDEX1 ', 'DTOS( DATEFIELD)+ SUBSTR ( LONGFIELD ,1 ,10)+ SUBSTR
( LONGFIELD2 ,1 ,20)', []);
You could try their SubStr function on your fields with parameters that would include the whole string and see if that at least gets you a result.

Resources