I am using the following measure (and a calendar table) to determine equipment uptime for a given hour of the day based on user input from a datetime slicer:
Selected Hour =
CALCULATE (
'UptimeView'[Uptime %],
FILTER (
'UptimeView',
'UptimeView'[LocalShiftDateHour] = SELECTEDVALUE ( 'CalendarTable'[DateTime] )
)
)
This is working just fine. The problem is that I also need this same calculation performed for each of the 12 hours prior to the selected hour. When I try to use the same formula but with one hour subtracted from the SELECTEDVALUE, like so...
S-1 =
CALCULATE (
'UptimeView'[Uptime %],
FILTER (
'UptimeView',
'UptimeView'[LocalShiftDateHour]
= SELECTEDVALUE ( 'CalendarTable'[DateTime] ) - ( 1 / 24 )
)
)
... I get blank cells in my table visualization, even though I know there is data for that hour:
Why does this happen? Any time I try to perform mathematical operations on the SELECTEDVALUE datetime value, it gives me blanks. But without using operations to manipulate it and just using the selected datetime itself, it works no problem. Is it not possible to subtract an hour from a SELECTEDVALUE datetime? If not, what workaround(s) should I try? (I have also attempted using -TIME(1,0,0) instead of -1/24 but that gave me blanks as well.)
Thanks in advance!!
I think the reason is that the subtraction you are operating isn't convenient to go row by row. Would you please try rather to put it as follows, and put the MAXX() function around the calculus you did, while adding another argument, which is the name of the table in which you want the subtraction to be performed:
S-1 =
CALCULATE (
'UptimeView'[Uptime %],
FILTER (
'UptimeView',
'UptimeView'[LocalShiftDateHour]
= MAXX('Replace_with_Tablename',SELECTEDVALUE(
'CalendarTable'[DateTime] ) - ( 1 / 24 ))
)
)
This is the trick I use. In fact, MAXX(tablename, expression) Evaluates an expression for each row of a table and returns the largest value.
Don't worry about the max, it doesn't have any effect on the result, since the max(one precise value in a precise row)= that same value
Related
I want to find the minimum date value in a list of transactions that are associated with an investment. There are many transactions for one investment, clearly. How do I write this so that Progress will only give me the minimum transaction date? I get the minimum at the end of my list, but I do not want the list, just the minimum value.
FOR EACH ilinvest WHERE ilinvest.inv-num EQ 406885:
FOR EACH iltrans WHERE iltrans.reg-pin EQ ilinvest.reg-pin:
DISPLAY iltrans.tran-dt(MINIMUM).
END.
END.
If you have an index on the tran-dt field, you could do something like
FOR EACH ilinvest WHERE ilinvest.inv-num EQ 406885:
FOR EACH iltrans WHERE iltrans.reg-pin EQ ilinvest.reg-pin
BY iltrans.tran-dt ASCENDING:
// The iltrans.tran-dt value here is the lowest. Note that
// you may see the unknown value .
// Leave after getting the first record
LEAVE.
END.
END.
Thank you both for your help. Removing the ascending worked like a charm:
FOR EACH ilinvest:
FOR EACH iltrans WHERE iltrans.reg-pin EQ ilinvest.reg-pin
AND iltrans.acct-num EQ ilinvest.inv-num
BY iltrans.tran-dt:
iMin = iltrans.tran-dt.
LEAVE.
END.
END.
Beware if your date field has no value, ie the unknown value (?). If the unknown value sorts before or after other values depends on all sorts of black magic
Additionally, since I do not like leave, I prefer a while:
def var dt min as date no-undo.
for each ilinvest no-lock,
each iltrans
where iltrans.reg-pin = ilinvest.reg-pin
and iltrans.acct-num = ilinvest.inv-num
no-lock
by iltrans.tran-dt
while dtmin = ?:
if iltrans.trans-dt <> ? then
dtmin = iltrans.tran-dt.
end.
I have a SQLite-Select statement like this to get the next available number:
SELECT IFNULL(MAX(current_nr)+1, 1) FROM rm_evaluation;
I already have a corresponding model in python peewee:
class RmRiskEvaluation(BaseModel):
...
current_nr = IntegerField(unique=True)
class Meta:
table_name = 'rm_evaluation'
But how can I express the SQL-statement from above.
=> Get the last number, add 1 to it and return the whole thang; if there is no last number at all, calculate with 1 beforehand.
If you weren't so lazy and had spent even a couple minutes reading the docs or searching, you would have found your answer.
fn.IFNULL(fn.MAX(RmRiskEvaluation.current_nr) + 1, 1)
this might look simple.. but dk how to do it
this is the information:
So.. i got the Cumulative Total using this function:
CumulativeTotal = CALCULATE(
SUM(vnxcritical[Used Space GB]),
FILTER(ALL(Datesonly[Date]),
Datesonly[Date] <= MAX(Datesonly[Date])))
But what i need is to get the differences between the dates, in the first date and the second the difference will be of 210. I need to get another column with that information. know the formula to do that?
ok..
So.. i used this:
IncrmentalValueTEST =
VAR CurrDate = MAX(vnxcritical[Date])
VAR PrevDate = CALCULATE(LASTDATE(vnxcritical[Date]), vnxcritical[Date] < CurrDate)
RETURN SUM(vnxcritical[Used Space GB]) -
CALCULATE(SUM(vnxcritical[Used Space GB]), vnxcritical[Date] = PrevDate)
and this is the result:
Ok, so this is is my data table:
You can see all the dates that i have for now, this is a capacity report for diferents EMC Storage Arrays, for diferentes Pools. The idea would be to have the knolwdge to review the incremental space used in a determinated portion of time.
allready tried another idea to get this, but the result was the same.. i used this:
Diferencia =
Var Day = MAX(Datesonly[Month])
Var Month = MAX(Datesonly[Year])
RETURN
SUM('Used Space'[used_mb])
- CALCULATE(
SUM('Used Space'[used_mb])
,FILTER(ALL(Datesonly[Date]),Datesonly[Date] <= Max(Datesonly[Date])))
But the return is the same.. "47753152401"
i'm using graphical filters, and other things to get a minimal view, because there are only 5 weekly reports and the sql database got more than 150.000 rows.
and this is the relation that i made with a only a table full of "dates" in order to invoke the function in a better way, but the result is the same..
Try something along these lines:
IncrmentalValue =
VAR CurrDate = MAX(Datesonly[Date])
VAR PrevDate = CALCULATE(LASTDATE(Datesonly[Date]), Datesonly[Date] < CurrDate)
RETURN SUM(vnxcritical[Used Space GB]) -
CALCULATE(SUM(vnxcritical[Used Space GB]), Datesonly[Date] = PrevDate)
First, calculate the current date and then find the previous date by taking the last date that occurred before it. Then take the difference between the current value and the previous value.
I would like to define a datetime type variable that is a result of a simple arithmetic operation between datetime type variables.
I've defined:
datetime duration = ( TimeCurrent() - OrderOpenTime() );
datetime TmStop = StringToTime( "1970.01.01 16:00" );
but when I call it in some other arithmetic operation or generally in code like this
ExitBuy_H1 = ( duration > TmClose && ...
or this
text[3]= "Duration: " + TimeToStr( duration, TIME_MINUTES );
it doesn't work.
TmStop instead works fine.
Does anyone know why?
datetime is a simple integer, number of seconds passed since 1970.01.01 00:00. duration in your example is also in seconds, even though it is datetime formated, when you need it in minutes, divide by 60. TmClose from your example means 16*60*60 seconds and you can compare that integer with any other int of course, but what might be the reason for that?
if you hold you position more then 16 hours, then duration > TmClose is true. if you want to convert difference in seconds (duration) into time, then you will have time converted from 1970.01.01 00:00 + duration seconds.
Anyway it is not clear what is your goal in doing this calculations? if you want to make sure that you hold that particular position more then x hours, then simple bool holdMoreThanXHours = TimeCurrent()-OrderOpenTime()>x*PeriodSeconds(PERIOD_H1), and do not forget to reselect each ticket if you have several ones in open
Fact A) the code, as-is, absolutely out of any question works.
//+------------------------------------------------------------------+
//| Test_StackOverflow.mq4 |
//+------------------------------------------------------------------+
#property strict
void OnStart() {
datetime duration = ( TimeCurrent() - OrderOpenTime() );
string txt = "Duration: " + TimeToStr( duration, TIME_MINUTES );
}
//+------------------------------------------------------------------+
0 error(s), 0 warning(s), compile time: 2000 msec 1 1
Fact B) the full MCVE-context of the code, as-is, is missing.
StackOverflow requires users to post a complete MCVE-representation of the problem. This requirement was not met in the original post.
While the datetime and int data-types are mutually interchangeable, the problem does not seem to be hidden in this intrinsic "duality" of a value representation, but must be somewhere else.
The main suspects for Why? are:
variable definition was masked by another variable having the same name
variable scope-of-definition was exceeded ( asking a variable outside of it's scope )
db.Pool-operations were not preceded by OrderSelect()
I'm using List() to retrieve a numeric field which I subsequently display on a report view via a merge variable inside a text field. The data being displayed is a list of employees who worked on a particular job on a particular day, and the number of hours they worked under various classifications (normal, overtime, non-billable, non-billable overtime, et al). The hours are all calculated fields pulled from another table, but they need to be stored numerically.
Each column has its own text field:
| <<$$Name>> | <<$$normalHours>> | <<$$otHours>> | ...
Giving output such as:
Jim Jones 8 2
Ralph Ryder 4.25 0
Foo McBar 10 2.5
The field height needs to be dynamic because there could be anywhere from 1 to 10 or so employees displayed.
The issue is that I would like to always display the hours field with two decimal places:
Jim Jones 8.00 2.00
Ralph Ryder 4.25 0.00
Foo McBar 10.00 2.50
This is normally trivial via Inspector -> Data for a single-value field, and perhaps it still is trivial -- but I'm just not seeing it.
I've tried using SetPrecision(hours ; 2) when populating the field, and also (though I didn't think it would actually work) when creating my list variable:
$$normalHours = SetPrecision( List( laborTable::normalHours ) ; 2 )
In both cases I still see plain integer output for whole numbers and no trailing zeroes in any case.
Please let me know if I can provide any further information that might help.
A few things you can try:
Auto-enter calculation replacing existing value
You could change your normalHours field to be an auto-enter calculation, uncheck 'do not replace existing value', and set the calculation to the following:
Let ( [
whole = Int ( Self ) ;
remainder = Abs ( Self ) - Abs ( whole )
] ;
Case ( remainder = 0 ;
whole & ".00" ;
Self )
)
This will append a ".00" to any whole numbers in your field. This should then come through your List() function later.
New calculation field
Alternately, if you don't want to automatically modify the existing number, you could make a new calculation field with a very similar calculation:
Let ( [
whole = Int ( normalHours ) ;
remainder = Abs ( normalHours ) - Abs ( whole )
] ;
Case ( remainder = 0 ;
whole & ".00" ;
normalHours )
)
And then you would use that calculation field in the List function, instead of your normalHours field.
For more complicated field formatting, you could also use a custom function like this: http://www.briandunning.com/cf/945
Can you replace this with a portal, perhaps?
If not, then try to set formatting on the merge text field itself. It can have formatting too; only one variant for each data type, but in your case it should be enough.