BookmarkSubscribeRSS Feed
data_null__
Jade | Level 19
I was not thinking clearly. _N_ should be equal to the number of lines read not one more. The loop reads the "next" line to see of it has a 1 CC but that does not increment _N_.

[pre]if keeperFlag then do _n_ = 1 to _n_;[/pre]
Is working in my test program, it should be good for you too. Sorry to be so dense.

Message was edited by: data _null_; Message was edited by: data _null_;
HoustonGSC
Calcite | Level 5
I reverted the DO WHILE(CC NE 1) back to the DO UNTIL(CC=1) and changed the

IF KEEPERFLAG THEN DO _N_ = 1 TO _N_ - (NOT EOF);

to

IF KEEPERFLAG THEN DO _N_ = 1 TO _N_;

and that worked so they both produced the desired results but your observation explains why it wasn't working the first time.
Thanks.
data_null__
Jade | Level 19
Here is an example that short circuits to the next page when "BOOK A" is not found in the third read of each page.

[pre]
filename FT15F001 temp recfm=F lrecl=161;
data _null_;
infile FT15F001 eof=eof end=eof;
array line[50] $161; *array dim should equal report page size;
keeperFlag = 0;
do _n_ = 1 by 1 until(cc eq '1');
input @1 line[_n_] $char161. @@;
if _n_ eq 3 and not index(line[_n_],'BOOK A') then do;
do until(cc eq '1');
input / @1 cc $1. @@;
end;
delete;
end;
input / @1 cc $1. @@;
end;
eof:
file print noprint ls=161;
do _n_ = 1 to _n_;
put line[_n_] $char161.;
end;
parmcards4;
1$$DJDE JDE=STD15,SIDE=(NUFRONT,NOFFSET),END;
JNM: GSGB020 P R I V A T E L A B E L
PGM: GSGB020 BOOK A G R O U P B U Y O R D E R
0
CA
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
0 0001 PRIVATE LABEL MANDARIN ORANGES
1$$DJDE JDE=STD15,SIDE=(NUFRONT,NOFFSET),END;
JNM: GSGB020 P R I V A T E L A B E L
PGM: GSGB020 BOOK B G R O U P B U Y O R D E R
0
CA
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
0 0002 PRIVATE LABEL MANDARIN ORANGES
1$$DJDE JDE=STD15,SIDE=(NUFRONT,NOFFSET),END;
JNM: GSGB020 P R I V A T E L A B E L
PGM: GSGB020 BOOK A G R O U P B U Y O R D E R
0
CA
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
0 0003 PRIVATE LABEL MANDARIN ORANGES
1$$DJDE JDE=STD15,SIDE=(NUFRONT,NOFFSET),END;
JNM: GSGB020 P R I V A T E L A B E L
PGM: GSGB020 BOOK A G R O U P B U Y O R D E R
0
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
CA
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
0 0004 PRIVATE LABEL MANDARIN ORANGES
0
CA
ITEM PACK SIZE DESCRIPTION O.I. REBATE CO
0 0004 PRIVATE LABEL MANDARIN ORANGES
;;;;
run;
[/pre]
HoustonGSC
Calcite | Level 5
Just out of curiosity, would this be more efficient or just use less resources since it is "throwing away" the undesirables.

I don't think it would make much difference on the current report since it is only a few hundred pages, but if I have to carry this across to a much larger report, it might be of some benefit there.
data_null__
Jade | Level 19
It is more efficient, because once it is determined that a page it is not wanted, the program only reads 1 byte from each line sliding down column 1 to the next page, and more lines are read into the array.

If there are many more discarded pages than good it will make a bigger impact on performance but I may take thousand of pages to see a difference in time.
HoustonGSC
Calcite | Level 5
Excellent, good to know.

Thanks.
Peter_C
Rhodochrosite | Level 12
just another thought - where all pages have the same number of lines :
The infile statement has an option N= (doc copied below)

This tells the data step to make that number of input lines addressible with #-pointers
#-pointers are like @-pointers but point to lines rather than columns.


From "Help and Documentation
N=available-lines

specifies the number of lines that are available to the input pointer at one time.

Default:

The highest value following a # pointer control in any INPUT statement in the DATA step. If you omit a # pointer control, then the default value is 1.
Interaction:

This option affects only the number of lines that the pointer can access at a time; it has no effect on the number of lines an INPUT statement reads.
Tip:

When you use # pointer controls in an INPUT statement that are less than the value of N=, you might get unexpected results. To prevent unexpected results, include a # pointer control that equals the value of the N= option. Here is an example:
infile 'external file' n=5;
input #2 name : $25. #3 job : $25. #5;

The INPUT statement includes a #5 pointer control, even though no data is read from that record. [/pre]
HoustonGSC
Calcite | Level 5
Something similar to this "page level control" was what I was originally after, however, in our case a report page may not have the same number of detail lines which voids the use of the N= option unless you can dynamically redefine the infile or somehow make N= a variable.

As you mentioned, this would probably work if the report was standardized but I cannot count on the application programmers to do this.

I also thought about using FIRSTOBS and OBS but the code that data_null shared is working very nicely and I have enhanced the script to be able to include or exclude pages so I think the user will be pleased with it.

I appreciate the idea though. I might have some use for it in another application.
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
You definitely can control full-page formatting using a combination of N=PS on the FILE statement along with your own coding and (selected) execution of PUT _PAGE_; as required.

However, as I remember this thread, you simply need to detect a YES or NO (print this entire page) condition based on finding a character string in the first "so many" records -- easily controlled with INPUT / PUT statement execution based on input record content, "1" (skip to new page) condition.

Of course, there are software products on the mainframe market that perform this type of function (along with much more).

Scott Barry
SBBWorks, Inc.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 23 replies
  • 1915 views
  • 0 likes
  • 5 in conversation