Convert Fixed format Rpg code to free format - rpgle

Hi I need to convert fixed format code to Free format as per my companies coding standard instructions. I dont even understand what the below means except that some date movement and conversions are happening..
C *ISO MOVE BCEXDT MDYDATE
C MOVE MDYDATE PEXPDATT
C *ISO MOVE BCSTDT MDYDATE
C MOVE MDYDATE PSTRDAT
Field definitions below:
BCEXDT 8S 0
BCSTDT 8S 0
D MDYDATE S D DATFMT(*MDY)

The two move operations for which you have shown the definitions can be converted like this:
C *ISO MOVE BCEXDT MDYDATE
C *ISO MOVE BCSTDT MDYDATE
to
MDYDate = %date(bcexdt: *ISO);
MDYDate = %date(bcstdt: *ISO);
Note that MDYDate is a date field, and has the same internal format as every other date field. The DATFMT(*MDY) keyword only defines how the field is represented externally by default when loaded into (or from) a character or numeric field. It also sets limits on allowable values. In the case of *MDY, those limits are 01-01-1940 to 12-31-2039. Notice that the values in BCEXDT and BCSTDT are *ISO format, and the values limits are different for those fields. Specifically 0001-01-01 to 9999-12-31. So you could get errors when attempting to assign the *ISO date to a *MDY date field.
The two moves I haven't converted for you would be done in one of the following ways.
If the targets are date fields:
pexpdatt = MDYDate;
pstrdat = MDYDate;
If the targets are numeric fields:
pexpdatt = %dec(MDYDate);
pstrdat = %dec(MDYDate);
If the targets are character fields:
pexpdatt = %char(MDYDate);
pstrdat = %char(MDYDate);
%dec() and %char() will assign the date fields in *MDY format since it was not explicitly specified in the assignment, and the date fields have DATFMT(*MDY).

Nobody else is going to be able to tell you what is going on either; without the definitions of the source and target fields.
That's why IBM depreciated the MOVE op-code from free-form.

Related

Data extraction from excel with operators is unable to store values

I have a Excel file with two columns. One has a name other has the corresponding mass to it. I have used the corresponding lines to read it and find the position of the name. But when I am trying to find the mass to the corresponding name as shown below it is not able to store it in the memory. In the Excel file, I have the mass values as 1.989*10^30. This seems to affect the code as the same code works fine when the cells in the excel has just numeric values.
majbod = 'Sun';
minbod = 'Earth';
majbodin = readtable("Major_and_Minor_Bodies.xlsx","Sheet",1);
minbodin = readtable("Major_and_Minor_Bodies.xlsx","Sheet",2);
MAJORBODY = table2array(majbodin(:,"Major_Body"));
MINORBODY = table2array(minbodin(:,"Minor_Body"));
mmaj = table2array(majbodin(:,"Mass"));
mmin = table2array(minbodin(:,"Mass"));
selected_majbody = find(strcmp(MAJORBODY,majbod));
selected_minbody = find(strcmp(MINORBODY,minbod));
M = mmaj(selected_majbody);
m = mmin(selected_minbody);
disp([M ;m])
Is there a better way to write the code compared to the way which I wrote?
Thanks.
Excel does it's best to figure out what kind of data is in each cell. Since your data has something besides just numbers, Excel treats it like a string. You have a couple of options for getting around that:
If you put an equals sign in front of it, it will treat it like an equation, and calculate the value of 1.989*10^3 for you. this will be a number.
Since scientific notation is so common, programmers have created a shortcut for representing it. They often use the character 'E' where you use "*10^". This means that if you type "1.989E30", excel will recognize that as a number.
If keeping the current string format is very important, you could probably modify the string during extraction - replace '*10^' with E, and then whatever language you are using will have a string to number parser you can use.
If the real problem is that the real numbers are just too long in Excel, you can always format the cell that they are in. (right click the cell, select format cells, then select scientific.)
Good luck

Pivot_tables' representation of DatetimeIndex is faulty

I am encountering this weird 'visual' effect that takes place on my pivot table.
This code outputs the representation of the pivot_table's index as shown in Annex 1:
pt = df_sorted.pivot_table(index = [date_col],values=[measure],columns=[apporteur_col],aggfunc=[len],fill_value=0)
pt=pt.loc[:,'len'].loc[:,measure][['A','B','C']]
While this code outputs the representation of the pivot_table's index as shown in Annex 2:
pt = df_sorted.pivot_table(index = [date_col],values=[measure],columns=[apporteur_col],aggfunc=[len],fill_value=0,margins=True)
pt=pt.loc[:,'len'].loc[:,measure][['A','B','C',"All"]]
As you can see, the only difference is the use of margins=True and the column All.
My goal
To have the representation of the index as date only. (Like Annex 1)
My questions
Why does this happen?
How do I fix it?
EDIT
Even though Annex 1 shows the index as dd/mm/yyyy only, once I plot the pivot_table on a 7 days period, the x axis is shown as dd/mm/yyyy HH:MM:SS. (View Annex 3)
P.S : I removed the keys so the sensitive info doesn't show.
Annex

PowerQuery (M): How can I extract a date from a large text field?

My table has a text column called Remarks which usually contains a large amount of text.
Here's an example:
3/24/2017 11:14:41 AM - EMD FOR STATUS NFU 3/30/17
3/30/2017 10:58:03 AM - CLD PER RECEPTIONIST GM UNAVAILABLE NFU 04-13-2017
4/13/2017 11:10:15 AM - CLD PER RECEPTIONIST WILL GIVE INFO NFU4/27
4/27/2017 9:02:20 AM - MLD INV WITH 90 DAY STAMP
4/27/2017 9:15:03 AM - PER REP WILL CALL CUSTOMER FOR PAYMENT
4/27/2017 11:03:46 AM - NFU 05/5PER REP CUSTOMER CONFUSION
5/5/2017 8:55:17 AM - NFU 5/9/2017 CRP PER REP CHECK WAS MLD 5/2/17
All of that text would be crammed into a single field, and I need to extract the last NFU date from the field for use in calculations and filtering.
In the above example, I would want to extract the date 5/9/2017 from the last row.
But as you can see, the date could be in any format, anywhere in the field.
I presume Excel can parse the text into a date value in any of the above formats (if not, I'll deal with that some other way - employee training, etc.)
The main things I need to figure out how to do using PowerQuery are:
Find the last instance of "NFU" in this field
Extract all text immediately following that last instance of "NFU", including the space between "NFU" and the date, if present.
At this point, the result should be:
" 5/9/2017 CRP PER REP CHECK WAS MLD 5/2/17"
Remove any whitepsace at the beginning of the string.
At this point, the result should be:
"5/9/2017 CRP PER REP CHECK WAS MLD 5/2/17"
Find the first character that is not 0-9, /, or - (or the end of the string, whichever comes first)
Truncate the string at the first non-date character, if appropriate.
At this point, the result should be:
"5/9/2017"
Finally, attempt to format the resulting text into Date type/format, and return as the result for a PowerQuery custom column.
Looking at the PowerQuery string functions available, I'm not sure whether this is even possible.
I guess you mean the Power Query Text functions. These are somewhat limited indeed, but there are plenty other options in Power Query's function library: in this case the List functions can come to the rescue.
By the way: I checked for " NFU" in order to avoid "CONFUSION" (last but one line in your examples).
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Typed = Table.TransformColumnTypes(Source,{{"example", type text}}),
LastNFU = Table.AddColumn(Typed, "LastNFU", each Text.PositionOf([example]," NFU",Occurrence.Last), Int64.Type),
AfterNFU = Table.AddColumn(LastNFU, "AfterNFU", each if [LastNFU] = -1 then null else Text.Range([example],[LastNFU]+4)),
Trimmed = Table.TransformColumns(AfterNFU,{{"AfterNFU", Text.Trim}}),
TextToList = Table.TransformColumns(Trimmed,{{"AfterNFU", each if _ = null then {} else Text.ToList(_)}}),
ListFirstN = Table.TransformColumns(TextToList,{{"AfterNFU", each List.FirstN(_, each Text.Contains("01234567890-/",_))}}),
TextCombine = Table.TransformColumns(ListFirstN, {"AfterNFU", Text.Combine, type text}),
Date = Table.TransformColumnTypes(TextCombine,{{"AfterNFU", type date}}, "en-US"),
Renamed = Table.RenameColumns(Date,{{"AfterNFU", "Date"}}),
Removed = Table.RemoveColumns(Renamed,{"LastNFU"})
in
Removed
A simple formula like =RIGHT(A1,LEN(A1)-(FIND("NFU",A1,1)-1)) would work to extract the string next to NFU. Assuming the text is at cell A1.
But needs to further drill down to get your other requirements.

Need an Expression to Split a DateRange column into 3 bins

I want to represent count of ID's wrt to Daterange column. I tried to split it into bins but there was option to split into no of parts and not as 3 differnt date values.I want to split the Date Range column into 3 parts so that i  can represent the data in a bar chart as Current,Pat and Future data. Each of the 3 bins are represented as:
1.Current - Count of ID for Current month[Dec 2016]. The data for current month should be dunamically calculated since if the next month comes the data should point to that by the dynalic calculation
2.Past - Count of ID for Data less than current month[Data < Dec 2016]. I need to be able to dynamically change the no of months using custom expression so that user can chnage th e no of months it goes back to. Need the expression in such a way that it can be set by a custom expression ,if not the nos can be changed at the expression
3.Future - Count of ID for Data greater than current month[Data  Dec 2016]. I need to be able to dynamically change the no of months using custom expression so that user can chnage th e no of months in the future. There will be future dates available since it is a data for manintenance done in the future time.
This 3 data needs to be as a custom/binned column so that the data is represented as shown in the attached picture.
You just need to create a calculated column...
case
when DatePart('month',[DateColumn]) = DatePart('month',DateTimeNow()) and DatePart('year',[DateColumn]) = DatePart('year',DateTimeNow()) then "Current"
when [DateColumn] < DateTimeNow() and [DateColumn] >= DateAdd('month',${NumOfMonthsBack} * (-1),[DateColumn]) then "Past"
when [DateColumn] > DateTimeNow() and [DateColumn] <= DateAdd('month',${NumOfMonthsAhead},[DateColumn]) then "Future"
end as [MonthRange]

Changing a numeric to a string variable in Stata

I have a variable ShiftStart that is a numeric variable in the format 01jan2014 06:59:59 (and so on). I want to change this to a string variable so that I can then substring it and create variables based on just date and just time separately.
When I try
generate str20 string_shiftstart=string(ShiftStart)
I create a string but all of the cells have been converted to strange values ("1.70e+12" and so on).
How can I keep the original contents of ShiftStart when it is converted to a string?
It seems you have a variable formatted as datetime. If so, no need to convert to string. There are appropriate functions that allow you to manipulate the original variable. This is clearly explained in help datetime:
clear
set more off
*----- example data -----
set obs 5
gen double datet = _n * 100000000
format datet %tc
list
*----- what you want -----
gen double date = dofc(datet)
format %td date
gen double hour = hh(datet) + mm(datet)/60 + ss(datet)/3600
list
The reason you find your original result surprising is because you are not aware of the fact that underlying the datetime display format, is a numerical value.
A good read (aside from help datetime) is
Stata tip 113: Changing a variable's format: What it does and does not mean, The Stata Journal, by Nicholas J. Cox.
Edit
To answer your last question:
If you want to create an indicator variable marking pre/post periods, one way is using td() (see the help file). Following the example given above:
// before 04jan1960
gen pre = date < td(04jan1960)
Creating this indicator variable is not always necessary. Most commands allow the use of the if qualifier, and you can insert the condition directly. See help if.
If you mean something else, you should be more explicit.

Resources