Your second code block would provide greater insight if it was

data final;
set a b(in=inb);
if inb and z=. then y=111*_n_;
run;

it would then be more obvious that the unexpected y value is retained from the previous observation and not the result of the IF condition.