ObjectScript: Looping over a multidimensional global value and comparing
Hi,
I have a global that holds users name and date of birth.
I would like to loop through them and check if the date of birth is more than 2 years based on todays date
so I have ^checker("under2", "Eric David", "02-05-2018")
I want to check the birthdate based on todays date to see if it is greater than 2. How do I access the birthdate in the global
Please can you advice
I tried :
set values = $order(^checker("under2"))
set td = $zdate($horolog, 3)
set ol = $p(^checker("under2"), ",", 3) // this does not work
while (values ' = "")
{
set difdays = $system.SQL.DateDiff("d", ol, td)
if difdays > 730
{
set ^value("greater than 2")
}
}
Hello,
You have to navigate through subscript using $order.
Assuming your first node is "under2" and won't change, and assuming your date is "DD-MM-YYYY"
you can do:
I hope this help.
for date conversion I decided to convert the birthdate into Cache Date, instead of converting $horolog into "DD-MM-YYYY" format.
But your method work also.
If you have only one record you can do:
I hope this help.
Cheers,
Jacques
Thank you so much Jacques. That was really helpful. I was able to build my solution
Hi Vladmir, thank you so much. I just saw your answer.
Why would you use GOTOs? There is no good reason to use GOTOs for anything, ever.
You are very welcome :)
The main reason I use GOTOs instead of FOR loops is that,
when I use GOTOs I can come back (or enter) at any point of the loops,
while in the case with FOR loops you can not start from the middle (that is, from any point in the loop).
In addition, how many operators do you count in Method A and Method B?
--------------------------------------------------------------------------------------------------------------------------------------------
{
set under2 = ""
for {
set under2 = $order(^checker(under2))
quit:under2=""
set Name = ""
for {
set Name = $order(^checker(under2, Name))
quit:Name=""
set DateBirth = ""
for {
set DateBirth = $order(^checker(under2,Name,DateBirth))
quit:DateBirth=""
}
}
}
}
ClassMethod TestB() As %String [ ZenMethod ]
{
s (under,name,dob)=""
1 s under=$o(^checker(under)) q:under=""
2 s name=$o(^checker(under,name)) g:name="" 1
3 s dob=$o(^checker(under,name,dob)) g:dob="" 2
g 3
}
--------------------------------------------------------------------------------------------------------------
Agreed. The pitfalls of using GOTO, while not immediately obvious, can be catastrophic:
Source: https://xkcd.com/292/
An old fashioned design:
{
s (under,name,dob)=""
1 s under=$o(^checker(under)) g:under="" end g:under'="under2" 1
2 s name=$o(^checker(under,name)) g:name="" 1
3 s dob=$o(^checker(under,name,dob)) g:dob="" 2
s dob1=$zdateh(dob,15)
if (+$h-dob1)>730 {w name,?30,dob}
g 3
end q
}
But you should take into account leap years.
In the common case:
{
s (under,name,dob)=""
1 s under=$o(^checker(under)) g:under="" end g:under'=underage 1
2 s name=$o(^checker(under,name)) g:name="" 1
3 s dob=$o(^checker(under,name,dob)) g:dob="" 2
s dob1=$zdateh(dob,15)
if (+$h-dob1)>daysofyears {w name,?30,dob}
g 3
end q
}
Your question does not say the format of the dates. I am answering based upon dd-mm-yyyy, but it is easy enough to change for a different date format. The big mistake in all prior answers is that they contain small errors around leap years. To compute the number of years between to dates in $HOROLOG format use $ZDATE(date2,8)-$ZDATE(date1,8)\10000.
So:
UNDER2 ; SRS 2018-12-06
SET today=$ZDATE($HOROLOG,8)
SET name=""
WHILE 1 {
SET name=$ORDER(^checker("under2",name)) QUIT:name="" ; [1]
SET birthday=$ORDER(^checker("under2",name,"")) ; [2]
SET birthday=$ZDATEH($TRANSLATE(birthday,"-","/"),4,,,,,,,"") ; [3]
CONTINUE:birthday="" ; [4]
SET age=today-$ZDATE(birthday,8)\10000 ; [5]
CONTINUE:age'<2 ; [6]
WRITE !,name,?22,age," ",$ZDATE(birthday,4,,4) ; [7]
}
QUIT
[1] Advance to next name.
[2] Get the first birthday. The structure allows multiple birthdays, but the code only looks at the first birthday.
[3] Convert the birthday from dd-mm-yyyy format to $HOROLOG format.
[4] Skip badly formatted birthdays.
[5] Compute the age in whole years.
[6] Skip people whose age is >= 2.
[7] Do something with people whose age is less than 2.