When I print out notes from VistA, I would always get a blank page
printed after each note, which caused reams of paper to be wasted
(These pages jam the printer if put back in).
First, a description of my printing system:
The DEVICE in my VistA is a HFS, with subtype P-OTHER80.
The pre-execute code creates a unique filename and sets IO to this, the
note is then printed to the HFS, and then the post-execute code
executes a ZSYSTEM command to launch lpr (the linux CUPS system) to
print the file and then delete it. The lpr command uses the
linux-defined printer to send out the print job. In my case, this
arrives at a HP JetDirect print server device connected to eternet,
that then connects directly to the printer.
Obviously in such a long chain, there are numerous ways for the system
to NOT work, and I had despaired of ever finding where that extra
LINE-FEED was coming from at the end of the print job. Then, our HP
Laser jet died, and we replaced it with a Dell Laser, and amazingly the
extra page of paper stopped! It was too good to be true. (And I am
still not sure how that happened.)
Then, I upgraded my server from RedHat 9 to CentOS, and the extra page
started appearing again. So I decided to try to fix it.
So I told lpr (the Linux printer) NOT to delete the HFS file when done
and looked at it. Sure enough, there was a /n /f /n (newline,
formfeed,newline) at the end of the file. So I knew the problem was
not in the printer, HP JetDirect, or lpr system. It was coming from
VistA.
So I traced through the code with my debugger for several hours and
finally found that in the function FOOTER^TIUPRPN2 the following line
was called after every footer was printed:
W @IOF
Now, IOF is defined for the device and is set up by ^%ZIS, and in the
case of my HFS, IOF="#"
Now, I know that if I perform a 'write #' at the GTM> command line, the
screen will clear. So I assumed that # was a formfeed command. But
when I used a hexdump on the HFS file before and after this command, I
find that # turns into "/f /n". I think this is significant because a
simple /f would probably spit out the current page, but having a /n
after the /f appears to eject a blank page. So if anyone can explain #
better to me, I'd appreciate it.
The solution is as follows:
Change:
W @IOF
to:
if +$get(TIUCONT1)=0 write @IOF
or for you compactors out there,
I '+$G(TIUCONT1) W @IOF
TIUCONT1 is a signal used by the VistA printing system to determine
whether to print a "continued on next page" message. So if we are not
continuing on the next page, then we don't need to put a form feed at
the end of the job. Apparently the linux lpr system or modern laser
printers knows that at the end of a print job to eject the current
page. I don't think older dot matrix printers did that.
So I have to fully test this, but I am fairly sure this will fix the
problem.
So how are others printing notes etc? Does anyone else have an issue
with this extra @IOF being printed after eacy note? Is everyone just
printing from the windows printer in CPRS, which avoids this whole
problem?
Kevin
--
Steve
"Not only is the universe stranger than we imagine, it is stranger than we can imagine." -- Sir Arthur Eddington
So I wrote some logic to check whether or not we are at the LAST note
in the print list and stop of @IOF only then. OK, so now the notes are
separated, but I am getting all kinds of blank pages again.
It is so frustrating, because I am sure that the laser printer kicks
out the page after a certain point is reached, and it looks like that
happens, and then @IOF adds another page or something. But still, when
I get look at my printed progress note the bottom margin is a full 1
inch or so.
I have worked on the about 2 hrs today, tracing through the code, doing
a XDialog --tailbox on the print job file so that I can watch as text
is added, and I seem to be going in circles....
See also below:
Steven McPhelan wrote:
> First, TIU is following the VA's programming standard which states that all
> print jobs are required to leave the printer at a top of form position. W
> @IOF will do that. The VistA program is suppose to check for $Y>0 before
> issuing the final W @IOF.
At least where I see the W @IOF, I don't see a check for $Y. It does
check this to get down to the bottom of the page, but that is the only
check I see in my version of the code.
> The value of IOF is device dependent. It should be set to the appropriate
> codes for the device.
>
> # is part of the M ANSI standards. For a terminal, if a M implementation is
> fully compliant, then W # should clear screen and place the cursor in the
> upper left hand corner. I do not see how any M implementation can do this
> generically for all terminals. Clearly, a M implementation can do this for
> those terminal types that it supports. Of course, introducing PCs instead
> of terminals, you now have the added layer of some kind of terminal
> emulation software. It also depends on how good a job the terminal emulator
> does at emulating a specific terminal type.
>
> For printers, this is another issue. Usually, your VistA terminal type must
> have a properly defined TERMINAL TYPE for this to work.
Well, my TERMINAL TYPE is P-OTHER80. Does that somehow define what a #
does, or does it change IOF to something else in some cases?
But again, you have
> an added issue of the OS and how the printer is actually accessed from M.
> You also have the issue of what the printer logic does with codes sent to
> it. For example, if the print buffer is empty, some printers will interpret
> a W # as a hard page feed. Others will interpret the W # and decide not to
> print a blank page if the print buffer is empty. But many times the print
> buffer is not empty. Sometimes one may send the escape sequences to put the
> printer back to default mode if you had printed in a different pitch than
> the default settings. So when the printer gets the final W # it may print a
> blank page because the buffer was not empty even though all it had was the
> resetting escape sequences (i.e., non-printing characters).
I agree, it is all very complicated. Why am I the only one having this
problem? What is the better solution that everyone else is using?
>
> You have to look at all areas to determine exactly where the trailing page
> feed is coming from. If the VistA program is following VA SAC standards and
> all configurations are set up properly, you will not get a trailing blank
> page.
Well, I must be doing something wrong :-(
Thanks for your feedback.
At least where I see the W @IOF, I don't see a check for $Y. It does
check this to get down to the bottom of the page, but that is the only
check I see in my version of the code.
They may not be checking for $Y. If I write a report and I know that the last line on a page is NOT the last line of a report, then I do not need to check for $Y since I know there is data in the print buffer and I need to issue a page feed. That may be what is happening in this routine. I have not actually looked at the routine at this point to determine things.
----------------
Well, my TERMINAL TYPE is P-OTHER80. Does that somehow define what a #
does, or does it change IOF to something else in some cases?
IOF is a field in the TERMINAL TYPE file. It does not change dynamically.
----------------
I agree, it is all very complicated. Why am I the only one having this
problem? What is the better solution that everyone else is using?
Everyone has this problem. In the VA, IRM staff spend considerable amount of time setting up each and every printer type used to avoid this problem.
At least where I see the W @IOF, I don't see a check for $Y. It does
check this to get down to the bottom of the page, but that is the only
check I see in my version of the code.They may not be checking for $Y. If I write a report and I know that the last line on a page is NOT the last line of a report, then I do not need to check for $Y since I know there is data in the print buffer and I need to issue a page feed. That may be what is happening in this routine. I have not actually looked at the routine at this point to determine things.
As Steve pointed out, the last character of a VistA report should be /f. I think the solution in this case is to change the definition of # for this device so that it is /f only.
If you did not change anything in Linux when you changed printers, then I think this is a likely explanation. But, if you did change printer drivers, then it's also possible that when VistA closes the device, the HP driver sends an extra /f but the Dell does not. It is common with printer drivers to "flush" partial pages by sending a /f when the device is closed by the application.
Steve,
Thanks for your feedback. You are correct about the #. I was confused
about that, I was debugging with a terminal, which probably caused IOF
to be reset to # or something. In the TERMINAL TYPE file, the Page
Feed (put into IOF) was defined as $C(12,13). And I think this
following 13 (LF) was the problem. I removed it with improvement.
But your first post really got me thinking. Why and I using P-OTHER80
for a laser printer? You got me thinking about getting my Terminal
Type configuration correct rather than trying to fiddle with the
printing code. So I changed to P-HPLASER.. and that seemed more
correct. But I was getting very wrong output. So I looked as the
Open-Execute codes and it was sending sequences that just seemed wrong.
Some research on the internet showed proper PCL escape codes. I put
these in and have gotten much closer to a fix. I can now adjust the
font, pitch, lines/inch etc.
I am having problems with page length, which I made another post about,
that has to do with $Y wrapping at 65 for some reason!
Thanks
I think when I upgraded my Linux that I did change drivers. That was
likely the problem. But now I am using the "raw printer" mode that
just sends the text on to the printer. That way the escape sequences
used by VistA won't get put inside some driver's escape sequences. I
am getting closer to a solution.
Thanks again
Kevin