I am trying to create a formula with multiple parameters that may or may not have a value entered - crystal-reports

I am trying to create a formula with multiple parameters that may or may not have a value entered.
The database field and corresponding parameters are:
{DataTableTicket.Master_Account_Code}={?MastNo})
{DataTableTicket.Description}={?RTCode}
{DataTableTicket.Problem_Code}={?ProbCode}
{DataTableTicket.Resolution_Code}={?ResCode}
{DataTableTicket.Customer_Number}={?CustNo}
{DataTableTicket.Master_Account_Code}={?MastNo})
I am trying to write an IF THEN statement that takes into consideration the various combinations, since you can enter in a ?MastNo value but not populate the rest of the parameters.
I think the basic formula would be something like this (if parameter is blank then all records else parameter). What I am struggling with is how to get that basic formula created since there are so many combinations.

For each parameter that "may or may not have a value", set it to a default value.
If the value for the parameter is entered then set the parameter to the entered value.

I usually do something like:
// Assumes that 0 represents all values; single value; numeric
( 0={?Parameter} OR {Table.Field}={?Parameter} )
// Assumes that 0 represents all values; multiple values; numeric
( 0 IN {?Parameter} OR {Table.Field} IN {?Parameter} )
In your situation:
( 0={?MastNo} OR DataTableTicket.Master_Account_Code}={?MastNo} ) AND
( 0={?RTCode} OR {DataTableTicket.Description}={?RTCode} )
...

Related

Check if character varying is between range of numbers

I hava data in my database and i need to select all data where 1 column number is between 1-100.
Im having problems, because i cant use - between 1 and 100; Because that column is character varying, not integer. But all data are numbers (i cant change it to integer).
Code;
dst_db1.eachRow("Select length_to_fault from diags where length_to_fault between 1 AND 100")
Error - operator does not exist: character varying >= integer
Since your column supposed to contain numeric values but is defined as text (or version of text) there will be times when it does not i.e. You need 2 validations: that the column actually contains numeric data and that it falls into your value restriction. So add the following predicates to your query.
and length_to_fault ~ '^\+?\d+(\.\d*)?$'
and length_to_fault::numeric <# ('[1.0,100.0]')::numrange;
The first builds a regexp that insures the column is a valid floating point value. The second insures the numeric value fall within the specified numeric range. See fiddle.
I understand you cannot change the database, but this looks like a good place for a check constraint esp. if n/a is the only non-numeric are allowed. You may want to talk with your DBA ans see about the following constraint.
alter table diags
add constraint length_to_fault_check
check ( lower(length_to_fault) = 'n/a'
or ( length_to_fault ~ '^\+?\d+(\.\d*)?$'
and length_to_fault::numeric <# ('[1.0,100.0]')::numrange
)
);
Then your query need only check that:
lower(lenth_to_fault) != 'n/a'
The below PostgreSQL query will work
SELECT length_to_fault FROM diags WHERE regexp_replace(length_to_fault, '[\s+]', '', 'g')::numeric BETWEEN 1 AND 100;

How to update multiple rows by keeping some column values the same and updating others?

I am trying to bulk update some rows in postgres. Now not all of the rows need to update the same column values. For example, row 1 needs to update column 1 and 3 whereas row 2 needs to update column 2 and 4. so row 1 column 2 and 4 should not change and row 2 column 1 and 3 should not change.
I have tried using CASEs to conditionally SET the correct column values but it doesn't work with multiple rows. It DOES work if I only try to update 1 row at a time.
update topic as tmp set
"from" = (CASE WHEN tmp2."from2"::text = 'OLD_VALUE' THEN tmp."from"::int2 ELSE tmp2."from2"::int2 end),
"text_search" = (CASE WHEN tmp2."text_search2"::text = 'OLD_VALUE' THEN tmp."text_search"::text ELSE tmp2."text_search2"::text end),
"weight" = (CASE WHEN tmp2."weight2"::text = 'OLD_VALUE' THEN tmp."weight"::numeric ELSE tmp2."weight2"::numeric end)
from (values
(1051,1,'Electronic Devices',3),
(1052,'OLD_VALUE','OLD_VALUE',100)
) as tmp2("id2","from2","text_search2","weight2")
where tmp2."id2" = tmp."id"
This is the error message i get
SQL Error [22P02]: ERROR: invalid input syntax for type integer: "OLD_VALUE"
When I try with only 1 FROM value
from (values (1051,1,'Electronic Devices',3))
or
from (values (1052,'OLD_VALUE','OLD_VALUE',100))
it works correctly.
It even works correctly if the same columns need to be updated eg.
from (values
(1051,1,'Electronic Devices',3),
(1052,2,'Topic 2',100)
)
Why is it not working correctly when I need to update different columns for each row?
When you provide the list of values as values (1051,1,'Electronic Devices',3),(1052,'OLD_VALUE','OLD_VALUE',100)), the first set of values is interpreted as the "template" of data types, and in this case (1051,1,'Electronic Devices',3), it's int, int, text, int. Then, any subsequent values provided, will be expected to have the same data type signature. When it parses (1052,'OLD_VALUE','OLD_VALUE',100), it sees int,text,text,int, which doesn't match the data type signature it expects, so it reports an error.
When you omit the first value and provide only (1052,'OLD_VALUE','OLD_VALUE',100), then it identifies int,text,text,int as the "template" data type signature, and it proceeds without complaint.

Cast to int instead of decimal?

I have field that has up to 9 comma separated values each of which have a string value and a numeric value separated by colon. After parsing them all some of the values between 0 and 1 are being set to an integer rather than a numeric as cast. The problem is obviously related to data type but I am unsure what is causing it or how to fix it. The problem only exists in the case statement, the split_part function seems to be working perfect.
Things I have tried:
nvl(split_part(one,':',2),0) = COALESCE types text and integer cannot be matched
nvl(split_part(one,':',2)::numeric,0) => Invalid input syntax for type numeric
numerous other cast/convert variations
(CASE WHEN split_part(one,':',2) = '' THEN 0::numeric ELSE split_part(one,':',2)::numeric END)::numeric => runs but get int value of 0
When using the split_part function outside of case statement it does work correctly. However, I need the result to be zero for null values.
split_part(one,':',2) => 0.02068278096187390979 (expected result)
When running the code above I get zero but expect 0.02068278096187390979
Field "one" has the following value 'xyz: 0.02068278096187390979' before the split_part function.
EXAMPLE:
create table test(one varchar);
insert into test values('XYZ: 0.50000000000000000000')
select
one ,split_part(one,':',2) as correct_value_for_those_that_are_not_null ,
case
when split_part(one,':',2) = '' then null
else split_part(one,':',2)::numeric
end::numeric as this_one_is_the_problem
from test
However, I need the result to be zero for null values.
Your example does not deal with NULL values at all, though. Only addressing the empty string ('').
To replace either with 0 reliably, efficiently and without casting issues:
SELECT part1, CASE WHEN part2 <> '' THEN part2::numeric ELSE numeric '0' END AS part2
FROM (
SELECT split_part(one, ':', 1) AS part1
, split_part(one, ':', 2) AS part2
FROM test
) sub;
See:
Best way to check for "empty or null value"
Also note that all SQL CASE branches must agree on a common data type. There have been minor adjustments in the logic that determines the resulting type in the past, so the version of Postgres may play a role in corner cases. Don't recall the details now.
nvl()is not a Postgres function. You probably meant COALESCE. The manual:
This SQL-standard function provides capabilities similar to NVL and IFNULL, which are used in some other database systems.

RIGHT Function in UPDATE Statement w/ Integer Field

I am attempting to run a simple UPDATE script on an integer field, whereby the trailing 2 numbers are "kept", and the leading numbers are removed. For example, "0440" would be updated as "40." I can get the desired data in a SELECT statement, such as
SELECT RIGHT(field_name::varchar, 2)
FROM table_name;
However, I run into an error when I try to use this same functionality in an UPDATE script, such as:
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::varchar, 2);
The error I receive reads:
column . . . is of type integer but expression is of type text . . .
HINT: You will need to rewrite or cast the expression
You're casting the integer to varchar but you're not casting the result back to integer.
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::TEXT, 2)::INTEGER;
The error is quite straight forward - right returns textual data, which you cannot assign to an integer column. You could, however, explicitly cast it back:
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::varchar, 2)::int;
1 is a digit (or a number - or a string), '123' is a number (or a string).
Your example 0440 does not make sense for an integer value, since leading (insignificant) 0 are not stored.
Strictly speaking data type integer is no good to store the "trailing 2 numbers" - meaning digits - since 00 and 0 both result in the same integer value 0. But I don't think that's what you meant.
For operating on the numeric value, don't use string functions (which requires casting back and forth. The modulo operator % does what you need, exactly: field_name%100. So:
UPDATE schema_name.table_name
SET field_name = field_name%100
WHERE field_name > 99; -- to avoid empty updates

Centura Gupta Team Developer Automation Possibility

Is there a automation tool which can automate the software build on Team Developer (v6.0).
I have tried with multiple automation tools to spy the table object in the application, it identifies it as Gupta ChildTable. But I am not able to retrieve the values from the row.
For example:
1. I have 10 rows in the table(grid) with 12 columns. I need to find the value "AAAAA" contained in first column and select that particular row via Automation.
2. I have 10 rows in the table(grid) with 12 columns. I need to find the value "AAAAA" contained in first column and click on particular cell in that row to input the data via Automation.
Thanks in advance.
Use VisTblFindString . This function ( and many others ) are included into your TD code if include 'VT.apl' in your include libraries .
VisTblFindString will return the Row - so then you simply set context to that row using SalTblSetContext( hWndForm, nRow ) , and then you can refer to the contents of each cell by name to return the value.
Syntax
nRow = VisTblFindString(hWndTable, nStartRow, hWndColumn, sString)
Handle: hWndTable
Number: nStartRow
Number: hWndColumn
String: sString
Description
Locates a string value within a column.
The string must match exactly, but case is ignored. Searching ends when the last row in the table is checked. A SAM_FetchRow message is sent for all rows that have not yet been fetched into the cache.
You can use the pattern matching characters understood by the function SalStrScan. The percent character (%) matches any set of characters. The underscore character ( _ ) matches any single character.
Parameters
hWndTable Table window handle.
nStartRow Row number at which to start the search.
hWndColumn Handle of column to search. Use hWndNULL to search all string columns.
sString String for which to search.
Return Value
Number: The row number if sString is found, or -1 if not found.
Example:
Set nRow = VisTblFindString (twOrders, 0, colDesc, 'AAAAAA')
Call SalTblSetContext( twOrders , nRow )
( Now you can get the value of any cell in nRow by referring to the Column Name )
e.g. Set sCellValue = twOrders.colDesc or Set sCellValue = twOrders.colId etc.
Rows ( or anything what-so-ever in a TableWindow - even the cell borders , backgrounds , lines, row headers etc ) can be treat as an 'Item' or 'Object' by TeamDeveloper . Recommend you use MTbl - it is an invaluable set of add-on functions that make dealing with Tables a breeze. I know of no sites using TableWindows that don't use MTbl. In terms of rows , you can define any row as an Item or Object and manipulate it accordingly. See M!Tbl ( a TableWindows extention ) and specifically fcMTblItem.DefineAsRow( hWndTbl, nRow ).
BTW , you can also use MTbl to completely change the look and feel of your TableWindows , to give them a real modern look.
Very rough napkin code, don't have TD on this computer. Not that you can copy&paste this easily anyway due to the code structure, only line by line.
tbl1 is the name of the table, col1 is the name of the column, substitute to fit your program.
Set nRow = TBL_MinRow
While SalTblFindNextRow( tbl1, nRow, 0, 0 )
Call SalTblSetContext( tbl1, nRow )
If tbl1.col1 = "AAAAA"
Call SalTblSetFocusCell( tbl1, nRow, tbl1.col1, 0, -1 )
Break
This should run through each row, check whether col1 has the chosen value, and then activates edit mode for that cell - provided the column is editable.