HI @annypanny Here is a very simple solution that should be easy to follow for most. I have also written comments where necessary to help you understand the flow of the logic. I hope this is convenient enough.
data have;
input Sc_no $ perf date :ddmmyy10.;
format date ddmmyy10.;
datalines;
A000855A -0.28305 30112018
A000855A 0.49306 30092018
A000855A 2.14955 31032019
A000855A 2.53133 31072018
A000855A 4.19303 31012019
A000856A -0.28305 30112018
A000856A 0.49306 30092018
A000856A 2.14955 31032019
A000856A 2.53133 31072018
A000856A 4.19303 31012019
;
/*Get the current month date and start date backtracking 61 months*/
%let curr_dt=%sysfunc(intnx(mon,%sysfunc(today()),0,e));
%let start_dt=%sysfunc(intnx(mon,&curr_dt,-61,e));
%put &=curr_dt;
%put &=start_dt;
/*Create the backtracked monthend date list*/
data backtracked_dates;
date=&start_dt;
do while(date<=&curr_dt);
output;
date=intnx('mon',date,1,'e');
end;
format date ddmmyy10.;
run;
/*Combine the dates with distinct Sc_no*/
/*This will give you a complete date list associated with each scn_no */
proc sql;
create table combine_scno_dates as
select *
from
(select distinct Sc_no from have), backtracked_dates
order by Sc_no,date;
quit;
/*Now, Join the combine_scno_dates back with have to get the needed result*/
proc sql;
create table want as
select a.*,case when perf=. then 0 else perf end as perf
from combine_scno_dates a left join have b
on a.Sc_no=b.Sc_no and a.date=b.date
order by a.sc_no,a.date;
quit;
/*Print and check the results*/
proc print noobs;run;