When values below zero, return as zero - spotfire

I have a calculated column which has some negative values, how can I make values below zero be returned as 0 only?
Here is what I tried:
case
when [Date] - DateTimeNow() > "0" then "0"
else [Date] - DateTimeNow()
end

If you calculate simply [Date]-DateTimeNow() you will see it is returned as type TimeSpan, which is neither a number nor a string. So in your case statement what you are effectively doing is defining a result of two different types (string when “0" and TimeSpan otherwise) depending on the condition (which compares a TimeSpan to a string), which will not work.
This will output a TimeSpan:
case
when LongInteger([Date] - DateTimeNow())>0 then TimeSpan(“0.0:0:0.0")
else [Date] - DateTimeNow()
end
Gaia

Related

Power Query - Converting whole number to text in a CUSTOM COLUMN

I need to convert 3 whole number columns to text in a formula when adding a new column inside power query. I know how to do this in dax using FORMAT function but I can't make it work inside power query.
3 columns are - click to veiw
Then below is my CUSTOM COLUMN:
= Table.AddColumn(RefNo.3, "Refernce Number", each
if Text.Length([RefNo.3]) > 1 and Text.Length([RefNo.3]) < 11 then [RefNo.3]
else if Text.Length([RefNo.2]) > 1 and Text.Length([RefNo.2]) < 11 then [RefNo.2]
else if Text.Length([RefNo.1]) > 1 and Text.Length([RefNo.1]) < 11 then [RefNo.1]
else null)
However, at the moment I'm getting this error:
Expression.Error: We cannot convert a value of type Table to type Number.
Details:
Value=[Table]
Type=[Type]
So I know I need to convert the whole number columns to text first inside the formula. Also, I had to intentionally convert those 3 columns from text to whole number previously to get rid of redundant values (so that's not an option for me to revert that). thanks in advance guys.
There are any number of ways to solve this, depending on your real data.
Just set the columns to Type.Text before executing your AddColumn function.
If you do this, you would also have to check for null as they will cause the script, as you've written it, to fail
Or you could precede your testing with another line to replace the nulls with an empty string (""): Table.ReplaceValue(table_name,null,"",Replacer.ReplaceValue,{"RefNo", "RefNo2", "RefNo3"}),
If they are all positive integers, compare the values rather than the string lengths: eg >=0 and <10000000000
Construct a numeric array, and return the last value that passes the filter
= Table.AddColumn(your_table_name, "Reference Number",
each List.Accumulate(List.Reverse(List.RemoveNulls({[RefNo],[RefNo2],[RefNo3]})),
null,(state,current)=> if state = null then
let
x = Text.Length(Text.From(current))
in
if x > 1 and x < 11 then current else state
else state))

Equation to find minimum difference between given date and array of dates

I am attempting to write an equation that compares a date to an array of other dates given the same ID and then returns the minimum value found between 0 and 42 or returns a zero if the criteria does not match.
My current equation can identify whether a date pair matches the above criteria and returns a 1 if there is a match and a 0 for no match.
=IF(E15<>"",IFERROR(--(AGGREGATE(15,7,(E15-$H$2:$H$8000)/(($C$1:$C$8000=C15)*(E15-$H$2:$H$8000>=0)),1)<43),0),0)
I need to modify this equation to return the actual difference between the dates rather than just a 1 or 0.
I have been playing around with an equation like this:
=IF(E3<>"", IFERROR(IF(--(AGGREGATE(15, 6, (E3-$H$2:$H$8000)/(--($C$2:$C$8000=C3)*--(E3-$H$2:$H$8000>=0)), 1)<43)=1, MIN(--($C$2:$C$8000=C3)*(E3-$H$2:$H$8000)), ""), 0), 0)
But it returns nothing but zeros.
Please find sample data and expected values below.
For what you want you only need to move the check for less than 43 into the Aggregate and return blanks instead of 0:
=IF(E15<>"",IFERROR(AGGREGATE(15,7,(E15-$H$2:$H$8000)/(($C$1:$C$8000=C15)*(E15-$H$2:$H$8000>=0)*(E15-$H$2:$H$8000<43)),1),""),"")

If statement returning not equal to 0 when value equals 0

I have a variable, Diff as a double. (values are a sample from my Workbook)
Dim Diff As Double
Sheets(Sheet1).Activate
Diff = 4382.98-4117.34-265.64
Values for calculating Diff come from cells formatted as numbers.
I then use Diff as an argument in an if statement.
If Diff <> 0 Then
ActiveSheet.Range(A2).Value = 265.64 + Diff
End If
Diff should equal 0, but the if statement is proceeding as if the condition is true. I have similar if statements that do not have problems like this. Do I need to format my values differently?
Edit: Had 43892.98 instead of 4382.98
Edit2: Had 256.64 instead of 265.64
Never, NEVER, NE-VER compare doubles on equity! (vars of floating point type)
Let even just in the mind only - never...
And you do right - your compare is "<>" - and you got the right result.
Currency is INTEGER type, i.e. not-floating point var.
values, exceeded 4 digits after point, are rounding internally;
compare on equity is correct.
.
I stored Diff As Currency instead of Double and the issue cleared up.

Date status function to displays Overdue, Due Later and Due Soon

I am currently working on function in Excel that will display the status of an activity based on the due date provided.
This function would display:
"Overdue" if Today()> Due Date;
"Due Soon" If the Due date was within one week
"Due Later" if Today() < Due Date +7
Below is an example of what I was able to muster up:
Function Status_of_Date()
If Sheets("Issue_Log").Range("Due_Date").Value < Date Then
Sheets("Issue_Log").Range("Date_Status").Value = "Overdue" 'overdue
ElseIf Sheets("Issue_Log").Range("Due_Date").Value < 7 + Date Then
Sheets("Issue_Log").Range("Date_Status").Value = "Due Later" ' Due Soon
ElseIf Sheets("Issue_Log").Range("Due_Date").Value > 7 + Date Then
Sheets("Issue_Log").Range("Date_Status").Value = "Due Later" ' Due Later
Else
End If
End Function
Codeless Solution
Add a column to your table, to count the days left - since anything negative is overdue anyway, make all negatives -1:
Use a table formula to calculate it:
=IF([#[Due Date]]-TODAY()<0,-1,[#[Due Date]]-TODAY())
Next, have another table to hold the status given a number of days:
Since you have 3 statuses, and they're really ranges of values, to achieve the values you're after you'll need:
A row with -1 for everything Overdue
A row with 0 for everything due Soon
A row with 7 for everything due Later
Now your "Date Status" column can be a simple VLOOKUP formula:
Again, a table formula is used; note the "approximate match" last parameter:
=VLOOKUP([#Days],tblStatusLookup,2,TRUE)
Adjust tblStatusLookup to whatever you've named your lookup table.
Look 'ma, not a single line of code!
Then you can hide the [Days] column if you don't need it shown, and the lookup table can be anywhere you want - and if the thresholds need to change, or if new statuses need to be added, you just tweak the lookup table (important: keep the [Days] sorted ascending, that's how approximate match VLOOKUP works!)
Bugs in OP
Your function needs to know what row to work with. That should be a parameter; change the signature to accept one - or even better, change it to accept a DueDate parameter - then you simply don't need to care about anything other than the date you're given:
Public Function GetDateStatus(ByVal dueDate As Date) As String
If dueDate - Date < 0 Then
GetDateStatus = "Overdue"
ElseIf dueDate - Date < 7 Then
GetDateStatus = "Due Soon"
Else
GetDateStatus = "Due Later"
End If
End function
And then in your table the formula would be:
=GetDateStatus(#[Due Date])
No need to be bothered with ranges and the nitty-gritty details of how and where every value is coming from - code gets much, much simpler when you work at the right abstraction level!
Note that a worksheet function is not allowed to change other cells' values: it calculates a value.

Rounding Summarized Saved Search Results

I created a saved search on sales orders to calculate days between order date and ship date, grouped and averaged by class (the formula is cased to distinguish between 'Wholesale' class and all others). The numeric formula is:
CASE WHEN {class} = 'Wholesale' THEN {actualshipdate} - {startdate} ELSE {actualshipdate} - {shipdate} END
The summary type for the formula result is average. The summary-level results have way too many decimal places. Is there a way to round the summarized results to a pre-defined number of digits?
I have tried using the ROUND() function, both inside the CASE statement and as a wrap-around. I've also looked through general preferences for rounding defaults and haven't found any.
In order to round the result, you should implement you own average calculation and rounding.
Add the following result field besides the class grouping field that you already have:
Field : Formula (Numeric)
Summary Type : Maximum
Formula : ROUND(SUM(CASE WHEN {class} = 'Wholesale' THEN {actualshipdate} - {startdate} ELSE {actualshipdate} - {shipdate} END) / COUNT({internalid})),2)
Basically, you are doing here your own analytics.
Since the results are grouped, each result fields contains the whole result set of this field which allows you to add analytical functions on this group.
The summary type is MAXIMUM, just in order to show one result, so it can also be min or avg, no difference.
The function is calculating the sum of your formula and dividing it by the records count to get the average.

Resources