DGET with multiple (compound) keys returns #NUM! error - filter

What is the logic of the DGET function with multiple criteria keys?
I have made two small examples to investigate:
Case 1: we get a value by Date type key only - it works fine.
Case 2: same data, but we add a String type key. Here we have an error!
I agree, there are 2 "М000001735" strings in column B ("Инв" field). But there are also 2 keys to get a unique row in this case. What is wrong? Can I use DGET function for compound keys?

The table should not contain any duplicates. If there are duplicates, you should remove that by using the UNIQUE or SORT function that you can use within the DGET. Because if there are multiple matches, DGET will return an error. The DGET formula returns #VALUE! error if the criterion doesn't match. So you should wrap Google Sheets DGET formula with an IFERROR. Duplicates in the criteria/lookup column are not allowed. This causes #NUM! error in DGET.
if you run: ={{1;2}\{3;4}}
or run this constellation: ={{1\3};{2\4}}
you will get the same result which means either of these will work:
=DGET(A:C; "Рабочее место"; {{"Инв" \ "Дата"}; {"М000001735" \ DATE(2019; 2; 15)}})
=DGET(A:C; "Рабочее место"; {{"Дата"; "Инв"}; {DATE(2019; 2; 15); "М000001735"}})
=DGET(A:C; "Рабочее место"; {{"Инв"; "М000001735"} \ {"Дата"; DATE(2019; 2; 15)}})
demo spreadsheet
note: make sure you use Russian Locale in Spreadsheet Settings
_____________________________________________________________
alternatives to DGET:
=QUERY(A:C; "select C where A = date '2019-2-15' and B = 'М000001735'"; 0)
=FILTER(C:C; A:A=DATE(2019; 2; 15); B:B="М000001735")
=VLOOKUP(VLOOKUP(DATE(2019; 2; 15); A:B; 2; 0); B:C; 2; 0)

It helps if an OP explains what they are trying to achieve (as well as what problem they encountered, and where, data sample in text format and so forth).
Please try:
=DGET(A$1:C;"Рабочее место";{{"Инв";"M00001735"}\{"Дата";DATE(2019;2;15)}})
Your 'default' separator is ; hence in your case this does not serve to stack arrays horizontally.

Related

If Statement error: Expressions that yield variant data-type cannot be used to define calculated columns

I'm new in Power BI and I'm more used to work with Excel. I try to translate following Excel formula:
=IF(A2="UPL";0;IF(MID(D2;FIND("OTP";D2)+3;1)=" ";"1";(MID(D2;FIND("OTP";D2)+3;1))))
in Power Bi as follows:
Algo =
VAR FindIT = FIND("OTP",Fixed_onTop_Data[Delivery Date],1,0)
RETURN
IF(Fixed_onTop_Data[Delivery Type] = "UPL", 0,
IF(FindIT = BLANK(), 1, MID(Fixed_onTop_Data[Delivery Date],FindIT+3,1))
)
Unfortunately I receive following error message:
Expressions that yield variant data-type cannot be used to define calculated columns.
My values are as follows:
Thank you so much for your help!
You cant mix Two datatypes in your output; In one part of if, you return an INT (literally 0/1), and is second you return a STRING
MID(Fixed_onTop_Data[Delivery Date],FindIT+3,1)
You must unify your output datatype -> everything to string or everything to INT
Your code must be returning BLANK in some cells therefore PowerBI isn't able to choose a data type for the column, wrap your code inside CONVERT(,INTEGER).

Array of value from multiple conditions

I wanna return an array of value from multiple conditions.
Currently formula is set to accept one condition.
https://docs.google.com/spreadsheets/d/1pgVlBWYKWtT6AEPyRtZmAYdOXBCjYG_B7pdlvCqYq0A/edit?usp=sharing
The desired result is showed in the ad hoc worksheet
Edit : initial problem solved by player0. Thanks !
Previous post
I'm using curly brace to return an array of value with the IF formula. This works well. I wanted to use IFS function because i wanted to use more conditions.
With a similar table, only the 1st number is returned form the array.
I don't understand why.
https://docs.google.com/spreadsheets/d/1pgVlBWYKWtT6AEPyRtZmAYdOXBCjYG_B7pdlvCqYq0A/edit?usp=sharing
Thanks !
delete range E2:L and use this in E2:
=ARRAYFORMULA(TRANSPOSE(SPLIT(TRANSPOSE(QUERY(
IF((E1:L1=B2:B11)+(E1:L1=C2:C11)+(E1:L1=D2:D11);
"1;2;3;4;5;6;7"; ";");;9^9)); ";"; 1; 0)))

Can we aggregate dynamic number of rows using Talend Open Studio

I'm a beginner in Talend Open Studio, and I'm trying to do the transformation below.
From a SQL Table that contains:
DeltaStock Date
------------------------
+50 (initial stock) J0
+80 J1
-30 J2
... ...
I want to produce this table:
Stock Date
-----------
50 J0
130 J1
100 J2
... ...
Do you think this could be possible using TOS? I thought of using tAggregateRow, but I didn't find it appropriate to my issue.
There's probably an easier way to do this using the tMemorizeRows component but the first thought that comes to mind is to use the globalMap to store a rolling sum.
In Talend it is possible to store an object (any value or any type) in the globalMap so that it can be retrieved later on in the job. This is used automatically if you ever use a tFlowToIterate component which allows you to retrieve the values for that row that is being iterated on from the globalMap.
A very basic sample job might look like this:
In this we have a tJava component that only initialises the rolling sum in the globalMap with the following code:
//Initialise the rollingSum global variable
globalMap.put("rollingSum", 0);
After this we connect this component onSubjobOk to make sure we only carry on if we've managed to put the rollingSum into the globalMap.
I then provide my data using a tFixedFlowInput component which allows me to easily hardcode some values for this example job. You could easily replace this with any input. I have used your sample input data from the question:
We then process the data using a tJavaRow which will do some transformations on the data row by row. I've used the following code which works for this example:
//Initialise the operator and the value variables
String operator = "";
Integer value = 0;
//Get the current rolling sum
Integer rollingSum = (Integer) globalMap.get("rollingSum");
//Extract the operator
Pattern p = Pattern.compile("^([+-])([0-9]+)$");
Matcher m = p.matcher(input_row.deltaStock);
//If we have any matches from the regular expression search then extract the operator and the value
if (m.find()) {
operator = m.group(1);
value = Integer.parseInt(m.group(2));
}
//Conditional to use the operator
if ("+".equals(operator)) {
rollingSum += value;
} else if ("-".equals(operator)) {
rollingSum -= value;
} else {
System.out.println("The operator provided wasn't a + or a -");
}
//Put the new rollingSum back into the globalMap
globalMap.put("rollingSum", rollingSum);
//Output the data
output_row.stock = rollingSum;
output_row.date = input_row.date;
There's quite a lot going on there but basically it starts by getting the current rollingSum from the globalMap.
Next, it uses a regular expression to split up the deltaStock string into an operator and a value. From this it uses the operator provided (plus or minus) to either add the deltaStock to the rollingSum or subtract the deltaStock from the rollingSum.
After this it then adds the new rollingSum back into the globalMap and outputs the 2 columns of stock and date (unchanged).
In my sample job I then output the data using a tLogRow which will print the values of the data to the console. I typically select the table formatting option in it and in this case I get the following output:
.-----+----.
|tLogRow_8 |
|=----+---=|
|stock|date|
|=----+---=|
|50 |J0 |
|130 |J1 |
|100 |J2 |
'-----+----'
Which should be what you were looking for.
You should be able to do it in Talend Open Studio.
I attach here an image with the JOB, the content of the tJavaRow and the execution result.
I left under the tFixedFlowInput used to simulate the input a tJDBCInput that you should use to read the data from your DB. Hopefully you can use a specific tXXXInput for your DB instead of the generic JDBC one.
Here is some simple code in the tJavaRow.
//Code generated according to input schema and output schema
output_row.delta = input_row.delta;
output_row.date = input_row.date;
output_row.rollingSum =
Integer.parseInt(globalMap.get("rollingSum").toString());
int delta = Integer.parseInt(input_row.delta);
output_row.rollingSum += delta;
// Save rolling SUM for next round
globalMap.put("rollingSum", output_row.rollingSum);
Beware of the exceptions in the parseInt(). You should handle them the way you feel right.
In my projects I usually have a SafeParse library that does not throws exceptions but returns a default value I can pass together with the vale to be parsed.

What makes Crystal ignore record selection formula?

Crystal 2008. Have record selection formula ending with
and
( ( "Zero" in {?Credit_Debit} and {V_ARHB_BKT_AGING_DETAIL.AMOUNT} = 0)
or ( "Credit" in {?Credit_Debit} and {V_ARHB_BKT_AGING_DETAIL.AMOUNT} < 0)
or ( "Debit" in {?Credit_Debit} and {V_ARHB_BKT_AGING_DETAIL.AMOUNT} > 0) )
but no matter what combination of values is selected for Credit_Debit the result set is the same.
Also without success, I tried joining the parameter array into a single string and using lines like
or ( {#Cred_Deb_Choices} like "*Credit*" and {V_ARHB_BKT_AGING_DETAIL.AMOUNT} < 0)
Using the first method works in the same formula when the parameter values are integers, as:
and ({?Location ID} = 0 or {V_ARHB_BKT_AGING_DETAIL.LOC_ID} in {?Location ID})
I examined the generated SQL, and saw that the part at the beginning that had no effect was not shown.
I changed a part that tested for a hard-coded value to instead test for a parameter value, and looked at the SQL again. No change.
When you try to create a filter that doesn't fit with the datatype of the field then that doesn't get reflected in record selection formula.
For Integer field give integers in record selection for text give text.
E.g:
ID=0 and Name='XXX' works
ID='Zero' and Name='XXX' doesn't
This should solve your issue

DataColumn Expression Divide By Zero

I'm using basic .net DataColumns and the associated Expression property.
I have an application which lets users define which columns to select from a database table. They can also add other columns which perform expressions on the data columns resulting in a custom grid of information.
The problem I have is when they have a calculation column along the lines of "(C2/C3)*100" where C2 and C3 are data columns and the value for C3 is zero. The old "divide by zero" issue.
The simple answer would be to convert the expression to "IIF(C3 = 0, 0, (C2/C3)*100)", however we don't expect the user to know to do that and at compile time I don't know what columns are defined. So I would have to programmatically determine which columns are being used in a division in order to construct the IIF clause. That could get quite tricky.
Is there another way to not throw an error and replace the result with 0 if a "Divide By Zero" error occurs?
Ok, I found a way. The key is to use Double and not Decimal for the column type, e.g. in the example above C3 should be a Double. This will result in a result of Infinity instead, which can be evaluated against using the expression as a whole.
E.g.
IIF(CONVERT(([C4] / [C3] )*100, 'System.String') = 'NaN' OR CONVERT(([C4] / [C3] )*100, 'System.String') = 'Infinity' OR CONVERT(([C4] / [C3] )*100, 'System.String') = '-Infinity', 0, ([C4] / [C3] )*100)
Decimal it seems doesn't provide that Infinity option.

Resources