Home All Groups Group Topic Archive Search About

Fluctuation of printer alignment

Author
20 Sep 2005 8:35 PM
pitters
Greetings, all!

I am printing reports showing a number of amount columns, and I am using the
Printer Object so that I can control the formatting. (Yes, I come from the
DOS era!)

I am using the following code to right-justify the amount fields:

       sWidth = Printer.TextWidth("000,000.00")

       Printer.Print Tab(44); "Batch total"; Tab(65);
       Frmt = Format(tot, "#####,##0.00")
       Printer.CurrentX = Printer.CurrentX + sWidth - Printer.TextWidth(Frmt)
       Printer.Print Frmt

and this was working very well, until . . .

The problem comes in when Windows decides to move the columns to the right
about 5-8 characters - not all the columns, just some of them! This forces
the printer to print the rest of columns on the next line (one of my reports
prints out the info over four lines instead of one, which does make a mess of
my linecount!)

If one prints the report again without even exiting the procedure, let alone
the programme, then the report prints the same report but beautifully aligned.

I cannot work out why, or what's causing this.  I can't keep on telling my
clients "That's Microsoft, or Windows" - I have to find a solution.

Please help - I'm tearing out my hair over this, and I have very little left!

Thanks
pitters
--

Author
20 Sep 2005 8:58 PM
Douglas Marquardt
Hi pitters:

You are using a fixed-width font, right?

Doug.

Show quoteHide quote
"pitters" <pitt***@discussions.microsoft.com> wrote in message news:A0C8BE42-014B-4DE4-910E-27EF77868683@microsoft.com...
> Greetings, all!
>
> I am printing reports showing a number of amount columns, and I am using the
> Printer Object so that I can control the formatting. (Yes, I come from the
> DOS era!)
>
> I am using the following code to right-justify the amount fields:
>
>        sWidth = Printer.TextWidth("000,000.00")
>
>        Printer.Print Tab(44); "Batch total"; Tab(65);
>        Frmt = Format(tot, "#####,##0.00")
>        Printer.CurrentX = Printer.CurrentX + sWidth - Printer.TextWidth(Frmt)
>        Printer.Print Frmt
>
> and this was working very well, until . . .
>
> The problem comes in when Windows decides to move the columns to the right
> about 5-8 characters - not all the columns, just some of them! This forces
> the printer to print the rest of columns on the next line (one of my reports
> prints out the info over four lines instead of one, which does make a mess of
> my linecount!)
>
> If one prints the report again without even exiting the procedure, let alone
> the programme, then the report prints the same report but beautifully aligned.
>
> I cannot work out why, or what's causing this.  I can't keep on telling my
> clients "That's Microsoft, or Windows" - I have to find a solution.
>
> Please help - I'm tearing out my hair over this, and I have very little left!
>
> Thanks
> pitters
> --
>
Author
20 Sep 2005 9:12 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:A0C8BE42-014B-4DE4-910E-27EF77868683@microsoft.com...

> The problem comes in when Windows decides to move the
> columns to the right about 5-8 characters - not all the columns,
> just some of them!

Which columns? Your current code only prints two columns, and yet you say
that sometimes it prints out the info over four lines instead of one. You
must be printing more than you have shown. Please post some of your actual
code, something perhaps that prints a fairly large part of a complete page.
Show as much as possible of the code you are using, including the part where
you set the font name and the font size and stuff like that. Also tell us
what size paper you are using. By the way, I would personally avoid the use
of Tab. Instead, you should position everything to a specified position
using CurrentX.

Mike
Author
20 Sep 2005 9:35 PM
pitters
Thanks, guys, for your oh-so-swift responses!  :o}

Doug, I'm using Tahoma - someone suggested I use Courier New, but it looks
so old-fashioned!  (And for me to say that . . . !!)  Font size = 8 (A4 paper)

Mike, I'm using VB6 SP 6 and yes, running as a compiled exe.
Though this afternoon, (it's 23h28 here now!) I had the same problem running
source.  Printed the report and the amounts were 6-7 positions to the left -
clicked to print again and it was perfect.

A bigger sample of my code (I didn't want to overload the WWW) follows:

                Printer.Print Tab(5); "Parking"; Tab(50);
                Frmt = Format(SummarySundryExempt, "#####,##0.00")
                Printer.CurrentX = Printer.CurrentX + sWidth -
Printer.TextWidth(Frmt)
                Printer.Print Frmt; Tab(70);
                Frmt = Format(SummarySundryNett, "#####,##0.00")
                Printer.CurrentX = Printer.CurrentX + sWidth -
Printer.TextWidth(Frmt)
                Printer.Print Frmt; Tab(90);
                Frmt = Format(SummarySundryVat, "#####,##0.00")
                Printer.CurrentX = Printer.CurrentX + sWidth -
Printer.TextWidth(Frmt)
                Printer.Print Frmt; Tab(110);
                Frmt = Format(SummarySundryGross, "#####,##0.00")
                Printer.CurrentX = Printer.CurrentX + sWidth -
Printer.TextWidth(Frmt)
                Printer.Print Frmt

I suppose I could replace the Tabs with CurrentXs but would that stop the
fluctuation?

Regards
Tony



--
Tony Pitwood


Show quoteHide quote
"Mike Williams" wrote:

> "pitters" <pitt***@discussions.microsoft.com> wrote in message
> news:A0C8BE42-014B-4DE4-910E-27EF77868683@microsoft.com...
>
> > The problem comes in when Windows decides to move the
> > columns to the right about 5-8 characters - not all the columns,
> > just some of them!
>
> Which columns? Your current code only prints two columns, and yet you say
> that sometimes it prints out the info over four lines instead of one. You
> must be printing more than you have shown. Please post some of your actual
> code, something perhaps that prints a fairly large part of a complete page.
> Show as much as possible of the code you are using, including the part where
> you set the font name and the font size and stuff like that. Also tell us
> what size paper you are using. By the way, I would personally avoid the use
> of Tab. Instead, you should position everything to a specified position
> using CurrentX.
>
> Mike
>
>
>
>
>
Author
20 Sep 2005 10:15 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:C97CBE59-57A2-4CF4-B2DA-4262A05ED6AD@microsoft.com...

> I suppose I could replace the Tabs with CurrentXs
> but would that stop the fluctuation?

Yes. I'm fairly certain that it would. A Tab unit is a distance equal to the
average width of all characters in the specific font you are using, and I've
known it to cause lots of trouble before. Use CurrentX to set your print
positions and you should be okay. Just set the desired "left" position for
the columns containing text and the desired "right" position (minus the
textwidth of the number to be printed) for columns containing numbers that
you want to be right justified. By the way, check the printed font face and
size in the pages that print correctly and the pages that do not. Are they
*exactly* the same. If not, post again and I'll tell you how to fix that
problem.

Mike
Author
20 Sep 2005 11:16 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:C97CBE59-57A2-4CF4-B2DA-4262A05ED6AD@microsoft.com...

> I'm using Tahoma [font]

That's fine. If you position your right aligned column of numbers using
CurrentX minus the TextWidth of the number then everything will work out
fine for both fixed width fonts and for proportionally spaced fonts. There
are some exceptions though. The alignment works well only because even in
proportionally spaced fonts the TextWidth of each of the numerals (0 to 9)
is identical (usually, but not always, exactly twice the width of the Space
character or the decimal point). A few fonts, however, do not hold to this
rule and with those fonts the TextWidth of the numerals 0 to 9 are
different. These are very rare though, and most of the standard fonts you
might wish to use conform to the "equal textwidth of numerals" rule. It is
always wise to check though, just in case:

Private Sub Command1_Click()
Printer.Font.Name = "Comic Sans MS"
Printer.Font.Size = 24
If Printer.TextWidth("0") <> Printer.TextWidth("1") Then
  MsgBox "Don't use this font for right aligned numbers"
Else
  MsgBox "This font's Okay"
End If
End Sub

Mike
Author
20 Sep 2005 9:19 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:A0C8BE42-014B-4DE4-910E-27EF77868683@microsoft.com...

.. . . by the way, some versions of Visual Basic did at one time have a bug
that caused the Printer.Textwidth function to return inconsistent values
under some circumstances, but as far as I know that was fixed with Service
Pack 2 or above in VB5, and also in VB6. Which version of VB are you
running, and what service pack have you installed? Also, is this code
running as a compiled exe?

Mike
Author
20 Sep 2005 9:59 PM
Saga
My suggestion is to eliminate all use of the Tab(). Rely wholy
on setting CurrentX.

If done properly, you can use any font you like.

I have a few reports that print using a similar approach.

Here is a small snippet:

    'The truck name.
    strTxt = "" & rs!TruckId
    sngXPos = 1800 + XOff - Printer.TextWidth("" & rs!TruckId)
    prnGenText sngXPos, sngYPos + YOff, strTxt, "Arial", 8, False

First off, I define exactly how far I want to print the right justified
column
from the left margen (ie the CurrentX). Once I have a number, I subtract
the width of the resultant string that I am going to print. In your
case, it
would be the Frmt variable.

The prnGenText sub is below. Excuse the $!%$!%, this routine came
VB3.

Public Sub prnGenText(x!, y!, t$, sFont$, iSize%, iType%)

  'This routine places the text in t$ at coordinates x!, y!
  'using the font specified in sFont$ and the size in iSize%. If
  'iType is True, then the text is bolded, otherwise it is
  'left as normal.
  Printer.FontName = sFont$
  Printer.FontSize = iSize%
  Printer.FontBold = iType%
  Printer.CurrentX = x!
  Printer.CurrentY = y!
  Printer.Print t$

End Sub

Good luck!
Saga


Show quoteHide quote
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:A0C8BE42-014B-4DE4-910E-27EF77868683@microsoft.com...
> Greetings, all!
>
> I am printing reports showing a number of amount columns, and I am
> using the
> Printer Object so that I can control the formatting. (Yes, I come from
> the
> DOS era!)
>
> I am using the following code to right-justify the amount fields:
>
>       sWidth = Printer.TextWidth("000,000.00")
>
>       Printer.Print Tab(44); "Batch total"; Tab(65);
>       Frmt = Format(tot, "#####,##0.00")
>       Printer.CurrentX = Printer.CurrentX + sWidth -
> Printer.TextWidth(Frmt)
>       Printer.Print Frmt
>
> and this was working very well, until . . .
>
> The problem comes in when Windows decides to move the columns to the
> right
> about 5-8 characters - not all the columns, just some of them! This
> forces
> the printer to print the rest of columns on the next line (one of my
> reports
> prints out the info over four lines instead of one, which does make a
> mess of
> my linecount!)
>
> If one prints the report again without even exiting the procedure, let
> alone
> the programme, then the report prints the same report but beautifully
> aligned.
>
> I cannot work out why, or what's causing this.  I can't keep on
> telling my
> clients "That's Microsoft, or Windows" - I have to find a solution.
>
> Please help - I'm tearing out my hair over this, and I have very
> little left!
>
> Thanks
> pitters
> --
>
Author
20 Sep 2005 10:17 PM
pitters
Thanks, Saga - indeed food for thought!

I'll have to work through it and see if it solves the problem -

speak to you guys later - good night!

Regards
Tony
--
Tony Pitwood


Show quoteHide quote
"Saga" wrote:

>
> My suggestion is to eliminate all use of the Tab(). Rely wholy
> on setting CurrentX.
>
> If done properly, you can use any font you like.
>
> I have a few reports that print using a similar approach.
>
> Here is a small snippet:
>
>     'The truck name.
>     strTxt = "" & rs!TruckId
>     sngXPos = 1800 + XOff - Printer.TextWidth("" & rs!TruckId)
>     prnGenText sngXPos, sngYPos + YOff, strTxt, "Arial", 8, False
>
> First off, I define exactly how far I want to print the right justified
> column
> from the left margen (ie the CurrentX). Once I have a number, I subtract
> the width of the resultant string that I am going to print. In your
> case, it
> would be the Frmt variable.
>
> The prnGenText sub is below. Excuse the $!%$!%, this routine came
> VB3.
>
> Public Sub prnGenText(x!, y!, t$, sFont$, iSize%, iType%)
>
>   'This routine places the text in t$ at coordinates x!, y!
>   'using the font specified in sFont$ and the size in iSize%. If
>   'iType is True, then the text is bolded, otherwise it is
>   'left as normal.
>   Printer.FontName = sFont$
>   Printer.FontSize = iSize%
>   Printer.FontBold = iType%
>   Printer.CurrentX = x!
>   Printer.CurrentY = y!
>   Printer.Print t$
>
> End Sub
>
> Good luck!
> Saga
>
>
> "pitters" <pitt***@discussions.microsoft.com> wrote in message
> news:A0C8BE42-014B-4DE4-910E-27EF77868683@microsoft.com...
> > Greetings, all!
> >
> > I am printing reports showing a number of amount columns, and I am
> > using the
> > Printer Object so that I can control the formatting. (Yes, I come from
> > the
> > DOS era!)
> >
> > I am using the following code to right-justify the amount fields:
> >
> >       sWidth = Printer.TextWidth("000,000.00")
> >
> >       Printer.Print Tab(44); "Batch total"; Tab(65);
> >       Frmt = Format(tot, "#####,##0.00")
> >       Printer.CurrentX = Printer.CurrentX + sWidth -
> > Printer.TextWidth(Frmt)
> >       Printer.Print Frmt
> >
> > and this was working very well, until . . .
> >
> > The problem comes in when Windows decides to move the columns to the
> > right
> > about 5-8 characters - not all the columns, just some of them! This
> > forces
> > the printer to print the rest of columns on the next line (one of my
> > reports
> > prints out the info over four lines instead of one, which does make a
> > mess of
> > my linecount!)
> >
> > If one prints the report again without even exiting the procedure, let
> > alone
> > the programme, then the report prints the same report but beautifully
> > aligned.
> >
> > I cannot work out why, or what's causing this.  I can't keep on
> > telling my
> > clients "That's Microsoft, or Windows" - I have to find a solution.
> >
> > Please help - I'm tearing out my hair over this, and I have very
> > little left!
> >
> > Thanks
> > pitters
> > --
> >
>
>
>
Author
20 Sep 2005 10:28 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:A0C8BE42-014B-4DE4-910E-27EF77868683@microsoft.com...

> I am printing reports showing a number of amount columns,
> and I am using the Printer Object so that I can control the
> formatting. (Yes, I come from the DOS era!)

Hey, don't worry about using the much maligned VB Printer Object. Despite
its many little shortcomings it is an amazingly versatile beast. You can do
virtually anything you want with it, as far as your printed output is
concerned. It is capable of giving you truly professional looking output,
printing and accurately sizing and positioning text and pictures and drawn
graphics and metafiles and all sorts of things with ease, and it leaves you
in total and absolute control over every aspect of your output. There are
some limitations it has that might cause you to dip into the API functions
now and again, but that's not a real problem.

Mike
Author
24 Sep 2005 7:34 PM
pitters
Thanks guys, for all your input -

Especially interesting your comment about Tab being average-width, Mike.

Problem is that it's not some reports that are printing correctly and others
not - (that I could live with!)

It's that I print the same report twice - first time, it's out of alignment,
the second time it's perfect - same report, same code, same Tabs and
CurrentX's!!!   ???

I can't change the code - then the second time will be wrong!
Is it Windows or VB or what?

Regards
Tony
--
Tony Pitwood


Show quoteHide quote
"Mike Williams" wrote:

> "pitters" <pitt***@discussions.microsoft.com> wrote in message
> news:A0C8BE42-014B-4DE4-910E-27EF77868683@microsoft.com...
>
> > I am printing reports showing a number of amount columns,
> > and I am using the Printer Object so that I can control the
> > formatting. (Yes, I come from the DOS era!)
>
> Hey, don't worry about using the much maligned VB Printer Object. Despite
> its many little shortcomings it is an amazingly versatile beast. You can do
> virtually anything you want with it, as far as your printed output is
> concerned. It is capable of giving you truly professional looking output,
> printing and accurately sizing and positioning text and pictures and drawn
> graphics and metafiles and all sorts of things with ease, and it leaves you
> in total and absolute control over every aspect of your output. There are
> some limitations it has that might cause you to dip into the API functions
> now and again, but that's not a real problem.
>
> Mike
>
>
>
Author
24 Sep 2005 8:31 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:CE7A3F5A-412E-4202-A3CC-7100E6E82EC9@microsoft.com...

> . . . It's that I print the same report twice - first time, it's out of
> alignment, the second time it's perfect - same report, same code,
> same Tabs and CurrentX's!!!   ???

First off, *don't use Tabs*! Don't use even a single Tab! Not anywhere! They
may (or may not) be the cause of your problem, but they definitely have
shown themselves to be unreliable in the past. Ditch all your Tabs and use
only CurrentX (and possibly CurrentY) to position all your text. If you
still have problems after you have done that then post again. If you do have
to post again then you'll need to post *full* details of your code (if
necessary, create a brand new VB project (preferably containing just a
single Form) and place as much of your current code into it so that it runs
and actually prints one of your reports (if necessary using dummy or perhaps
randomly generated data). Then *make sure that it exhibits the problem you
are having* and post it to the group (preferably posting the entire .frm
code rather than just the code so that we will have *exactly* the Form that
you are working with. Also post full details of the system you are using,
together with details of then printer and also any information about any
other application running on the same machine that may also use that same
printer in between the printing of your individual reports.

As I recall you said in one of your earlier posts that sometimes (on a
report that prints out faulty) a line of text that should take only a single
lines actually takes up two or three or more lines. That behavious is
typical of a Tab to an X position that is "behind" the current value of
CurrentX (in othjer woprds behind the end of the last piece of text that was
printed on that linbe). In such a case VB will print at the required Tab
position *but on the next line down*. It's difficult to say for sure without
seeing more of your code, but that "Tab makes it go to the next line down"
behaviour is quite likely at the root of your problem. GET RID OF THOSE
TABS! Then post again.

By the way, are you *sure* that the font is the same every time you print
the page. Certain combinations of printer driver, operating system and VB
service pack number did at one time have a problem with the printer object
"forgetting the font it is supposed to beusing" under certain conditions,
particular after a Printer.Newline. Also, certain combinations had a habit
of failing to comply with your request for a certain font (basically because
VB "thought" that it was already using the selected font when actually it
was not. I really did think that all of those problems had been solved by
now, but just in case they still exist on your particular setup you should
make sure that you set up the font and the font size (and also possibly the
font bold) at the start of every Print Job and *also at the start of every
new page*. Also, just in case your machine has the second problem, you
should ensure that you reinforce your selections by "toggling". What I mean
by toggl;ing is that you should set a specific property to something you *do
not* want and then follow that by a printer.Print statement (that bit is
important) and then set the same property to something that you *do* want.
You should do all thnis at the start of every print job and also at the
start of every new page in that print job (by the way, every print job
should start off with a simple Printer.Print statement). Suppose for example
that you actually want to use Times New Roman size 12, then at the start of
the print job and also at the start of every new page (after each
printer.NewPage) you should use something like:

Printer.Font.Name = "Arial"
Printer.Print
Printer.Font.Name = "Times New Roman"
Printer.Font.Size = 99
Printer.Print
Printer.Font.Size = 12
Printer.CurrentX = 0
Printer.CurrentY = 0

The above cose is a way of solving the "forgot my font" and also the "fail
to set font" problems on systems which had those problems. It is a bit of a
"belt and braces" thing now of course, because as far as I know those
problems no longer exist. However, it is worth doing them just in case they
do for some reason exist on your own system.

Anyway, Ill repeat, DITCH THOSE TABS!

If you do all these things and you are still having problems then post again
with *full details of your system and printer and everything* and also with
the full text of a VB .frm file that contains its own dummy opr randoml;y
generated data and that exhibits the problem you are having. Please postr
back anyway, even if the above stuff does happen to fix your problem, so
that we'll know what did it.

Mike
Author
24 Sep 2005 8:36 PM
Mike Williams
"Mike Williams" <M***@WhiskyandCoke.com> wrote in message
news:dh4d38$pke$1@news6.svr.pol.co.uk...

.. . . bloody hell! I've just read the stuff I last posted and I think I'm
gonna have to start checkin' for "typos" before I post these things! The
problem is I am a simple "two finger typist" but I can go like a bat out of
hell, and if I get carried away (with my speed) I can end up making a few
mistakes :-(
Author
25 Sep 2005 7:01 AM
pitters
Thanks, Mike, for all your help -

I think you have hit on the answer - certainly CurrentX would keep the
details on the same line - even if the figures are obscured by the later
information!!  o:|

I will try what you have suggested about a separate form - maybe with two
routines (one as is with Tabs, the other with CurrentX's)

My son-in-law is busy looking into using VSView instead, so we will be
tackling this from different angles.

Will let you know the results (don't be impatient - it will take time!)

Regards
Tony

--
Tony Pitwood


Show quoteHide quote
"Mike Williams" wrote:

> "Mike Williams" <M***@WhiskyandCoke.com> wrote in message
> news:dh4d38$pke$1@news6.svr.pol.co.uk...
>
> .. . . bloody hell! I've just read the stuff I last posted and I think I'm
> gonna have to start checkin' for "typos" before I post these things! The
> problem is I am a simple "two finger typist" but I can go like a bat out of
> hell, and if I get carried away (with my speed) I can end up making a few
> mistakes :-(
>
>
>
>
Author
25 Sep 2005 10:35 AM
J French
On Sun, 25 Sep 2005 00:01:02 -0700, "=?Utf-8?B?cGl0dGVycw==?="
<pitt***@discussions.microsoft.com> wrote:

>Thanks, Mike, for all your help -
>
>I think you have hit on the answer - certainly CurrentX would keep the
>details on the same line - even if the figures are obscured by the later
>information!!  o:|
>
>I will try what you have suggested about a separate form - maybe with two
>routines (one as is with Tabs, the other with CurrentX's)
>
>My son-in-law is busy looking into using VSView instead, so we will be
>tackling this from different angles.
>
>Will let you know the results (don't be impatient - it will take time!)

I fully  agree with Mike about not using Tabs
- they are 'relative' and very dodgy
- the reason your reports come out differently is probably because the
first ones CurrentX was not zero

If you set up an Array containing each CurrentX for each column, then
it is very easy to adjust things

If you set up the array programatically from an array of field lengths
then it is even easier

I certainly would not resort to a 3rd party utility for printing
- not unless you have the source - and understand it

Some time ago I wrote a utility Class for fancy Screen or Printer
printing with deadly accurate alignment

Search Google Groups for:  "J French" "GPrint.cls"
It should be the second hit
Author
25 Sep 2005 1:52 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:07F38BE8-12E0-4FB1-9225-B065C9A37F5D@microsoft.com...

> Thanks, Mike, for all your help - I think you have hit on the answer
> - certainly CurrentX would keep the details on the same line - even
> if the figures are obscured by the later information!!  o:|

Okay. Let me know how it goes. By the way, if that happens when you get rid
of Tabs and use CurrentX instead(figures being obscured by later
information) and it is consistent then you'll need to look at your
positioning and adjust it accordingly. However, if it happens and it is
inconsistent (some reports with identical information being aligned
correctly and other not) then your setup might have a problem with the
TextWidth function (I know it was a problem in the past, but I think it has
been fixed now). Anyway, if that is a problem then you can fix it by using
the API instead of the VB TextWidth function to get the printed length of
the pieces of text. Let us know how it goes.

Mike
Author
27 Sep 2005 5:45 PM
pitters
One of my operators said that it's usually the first report that's out of
alignment, and all the rest are fine - she then reprints the first report
again.
But it's a waste of paper and time, apart from making me look like a real
'nana!!

That made me think it's to do with initializing as you suggested. I do
address the printer by way of printer.fontsize, printer.orientation, etc.,
but it sees to need to print the first report to get its bearings?!!  o:}

I used CurrentY to set my top line on another (customised) statement
procedure, and there was half a line difference between printing on an HP
Laserjet 5 and a Konica printer.   That's a difficult one to allow for
programmatically!

Regards
Tony
--
Tony Pitwood


Show quoteHide quote
"Mike Williams" wrote:

> "pitters" <pitt***@discussions.microsoft.com> wrote in message
> news:07F38BE8-12E0-4FB1-9225-B065C9A37F5D@microsoft.com...
>
> > Thanks, Mike, for all your help - I think you have hit on the answer
> > - certainly CurrentX would keep the details on the same line - even
> > if the figures are obscured by the later information!!  o:|
>
> Okay. Let me know how it goes. By the way, if that happens when you get rid
> of Tabs and use CurrentX instead(figures being obscured by later
> information) and it is consistent then you'll need to look at your
> positioning and adjust it accordingly. However, if it happens and it is
> inconsistent (some reports with identical information being aligned
> correctly and other not) then your setup might have a problem with the
> TextWidth function (I know it was a problem in the past, but I think it has
> been fixed now). Anyway, if that is a problem then you can fix it by using
> the API instead of the VB TextWidth function to get the printed length of
> the pieces of text. Let us know how it goes.
>
> Mike
>
>
>
>
>
Author
27 Sep 2005 6:42 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:8DA4E414-33AF-4B8B-BCBF-A82AA47E0A2A@microsoft.com...

> One of my operators said that it's usually the first report that's
> out of alignment, and all the rest are fine - she then reprints the
> first report again. That made me think it's to do with initializing
> as you suggested. I do address the printer by way of
> printer.fontsize, printer.orientation, etc., but it sees to need to
> print the first report to get its bearings?!!  o:}

You should start *every* print job with a simple Printer.Print statement. It
should be the very first statement of your print code (apart from setting
orientation, which you will have to do first if you need to change it).
Printer.Print causes VB to set up the printer object, and you should not try
to set any other things until you have done that. Also, try my "toggle"
suggestion in my reply dated 24 Sep. Set the font names and size and bold
etc at the very start of the print job (immediately after the Printer.Print
statement) and try using the "toggle" method when you do so.

> I used CurrentY to set my top line on another (customised) statement
> procedure, and there was half a line difference between printing on
> an HP  Laserjet 5 and a Konica printer.   That's a difficult one to allow
> for programmatically!

Not really. It's very easy. Every printer has an "unprintable margin" at the
top of the page, and also at both sides and sometimes also the bottom. The
sizes of these margins can be different on different printers, and even on
the same printer at different settings. Even printers that actually can
produce "full bleed" output still have these unprintable margins at certain
settings. The printer is totally incapable of depositing ink in those
unprintable margins. VB cannot make it do so, and neither can Microsoft Word
or anything else. That effectively leaves a "printable rectangle" which is
slightly smaller than the physical page, the size and position of which is
different on different printer.  In fact, if you have Microsoft Word start a
new document and then use the File / Page Setup menu and set all four
margins to zero. Click OK and MS Word will tell you that some margins are
set outside the printable area of the page. When it does so click the "Fix"
button and MS Word will set the margins for you, which will show you exactly
where the unprintable margins are.

As far as the VB printer object is concerned, location (0, 0) is the top
left corner of the "printable rectangle" (*not* the top left corner of the
physical page). However, it is very easy to correct for this. The following
code will do it for you, and it will set location (0, 0) to "point to" the
exact top left corner of the physical page on all printers. This, of course,
means you can use CurrentX and CurrentY with great accuracy on all printers,
and your problem will be solved. Here's the code. Run it at the start of the
print job:

Option Explicit
Private Declare Function GetDeviceCaps Lib "gdi32" _
(ByVal hdc As Long, ByVal nindex As Long) As Long
Private Const PHYSICALOFFSETX As Long = 112
Private Const PHYSICALOFFSETY As Long = 113

Private Sub SetPrinterOrigin(x As Single, y As Single)
With Printer
  .ScaleLeft = .ScaleX(GetDeviceCaps(.hdc, PHYSICALOFFSETX), _
    vbPixels, .ScaleMode) - x
  .ScaleTop = .ScaleY(GetDeviceCaps(.hdc, PHYSICALOFFSETY), _
    vbPixels, .ScaleMode) - y
  .CurrentX = 0
  .CurrentY = 0
End With
End Sub

Private Sub Command1_Click()
Printer.ScaleMode = vbInches
' The following line will set location (0, 0) so that
' it points to the top left corner of the physical
' page for the rest of the print job.
SetPrinterOrigin 0, 0
' the rest of your printing code
End Sub

Mike
Author
27 Sep 2005 7:09 PM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:8DA4E414-33AF-4B8B-BCBF-A82AA47E0A2A@microsoft.com...

> One of my operators said that it's usually the first report
> that's out of  alignment, and all the rest are fine

.. . . by the way, I've noticed you are doing things like sWidth =
Printer.TextWidth("000,000.00"). Are you doing that, and perhaps other
things, *after* you have set up the font name and the font size and
font.bold or whatever, or before? You must remember that the VB printer
object does *not* completely reset itself after finishing a print job (after
using Printer.EndDoc). Many of its settings are carried over from one print
job to the next. This means that if the first time the printer is used in
your application you get some details (width of a specific piece of text for
example) *before* you have actually set the font to its correct name and
size then the returned length will be wrong (because the initial default
font name and size will usually be something quite different from what you
are setting it to). This will cause the first print job to come out wrong.
However, on the second print run many of the settings you made during the
first print run will be "remembered", and so the "default" conditions for
the second run will be different to the default conditions for the first
run. Because of this you need to ensure that you set up *everything* at the
very start of your print job (font name, size, bold, italic, just about
everything) and definitely before you use any function that itself uses
those values (TextWidth, for example). If you initialise the VB printer
object fully and correctly (and if you also use the code I posted to set its
origin to the top left corner of the physical page) it will work correctly
for you, and you won't have any problems. Why don't you post the *exact*
full code you are using (or email the complete VB project to me at
taximic***@yahoo.co.uk if you don't want to put it on the newsgroup) and
I'll have a look at it. Email the complete project to me (add code to
generate random data if it otherwise uses a database) and I'll give you a
complete answer.

Mike
Author
29 Sep 2005 8:06 AM
Mike Williams
"pitters" <pitt***@discussions.microsoft.com> wrote in message
news:8DA4E414-33AF-4B8B-BCBF-A82AA47E0A2A@microsoft.com...

> I used CurrentY to set my top line on another (customised)
> statement procedure, and there was half a line difference
> between printing on an HP Laserjet 5 and a Konica printer.

By the way, in addition to using the SetPrinterOrigin code that I posted
(which will fix the above problem) you should also make sure that you are
setting your print coordinates correctly, especially if you are printing so
as to align text correctly onto pre-printed forms. You need to remember that
when you are printing a string of text the coordinates refer to the *top
left* corner of the first character of that text (actually the top left
corner of the rectangular "cell" in which that character sits and which is
the same height but not the same width for all characters in that font and
size. For example, suppose you take a pre printed document and measure the
distance from the top of the page to a specific the pre printed line on
which you want some text to sit, and supposing that the measured distance is
(say) 1.65 inches. You should set up CurrentY as follows (after first using
my SetPrinterOrigin code and after setting up your font name and size at the
start of the print job and, of course, after setting the printer scalemode
to vbInches):

Printer.CurrentY = 1.65 - Printer.TextHeight("x")

Mike
Author
29 Sep 2005 8:53 AM
J French
On Thu, 29 Sep 2005 09:06:45 +0100, "Mike Williams"
<M***@WhiskyandCoke.com> wrote:

Show quoteHide quote
>"pitters" <pitt***@discussions.microsoft.com> wrote in message
>news:8DA4E414-33AF-4B8B-BCBF-A82AA47E0A2A@microsoft.com...

>> I used CurrentY to set my top line on another (customised)
>> statement procedure, and there was half a line difference
>> between printing on an HP Laserjet 5 and a Konica printer.

>By the way, in addition to using the SetPrinterOrigin code that I posted
>(which will fix the above problem) you should also make sure that you are
>setting your print coordinates correctly, especially if you are printing so
>as to align text correctly onto pre-printed forms. You need to remember that
>when you are printing a string of text the coordinates refer to the *top
>left* corner of the first character of that text (actually the top left
>corner of the rectangular "cell" in which that character sits and which is
>the same height but not the same width for all characters in that font and
>size. For example, suppose you take a pre printed document and measure the
>distance from the top of the page to a specific the pre printed line on
>which you want some text to sit, and supposing that the measured distance is
>(say) 1.65 inches. You should set up CurrentY as follows (after first using
>my SetPrinterOrigin code and after setting up your font name and size at the
>start of the print job and, of course, after setting the printer scalemode
>to vbInches):

>Printer.CurrentY = 1.65 - Printer.TextHeight("x")

Interestingly, the descender on all fonts I've tested is 25% of the
total height of the font

' --- adjust vertical position for height of other font
' descender is 0.25 - below CurrentY - get Base of Char at CurrentY

    HoldV = P.CurrentY
    P.CurrentY = P.CurrentY - (P.TextHeight("M") * 0.75)
    '  print
    P.CurrentY = HoldV

This allows different font sizes to be printed on the same 'base line'
Author
29 Sep 2005 10:12 AM
Mike Williams
"J French" <erew***@nowhere.uk> wrote in message
news:433ba90d.7139868@news.btopenworld.com...
> On Thu, 29 Sep 2005 09:06:45 +0100, "Mike Williams"

> Interestingly, the descender on all fonts I've tested is 25%
> of the total height of the font [snip]
> P.CurrentY = P.CurrentY - (P.TextHeight("M") * 0.75)

Actually I find it to be nearer 20% on most fonts (so that he would use
height * 0.8), but you're quite right Jerry about often needing to take it
into account. My own suggested method is what I normally use simply because
in the stuff that I write I usually want the text to fit neatly inside a
"cell" (or a drawn rectangle) of a pre printed form, so that the descenders
are also within the rectangle. However if the user wants his text to sit
neatly on the line so that the main characters touch the line and the
descenders fall below it then he needs to do as you suggest. Nice catch.

He could, of course, use the GetTextMetrics and the GetOutLineTextMetrics
APIs to get more detailed information about a specific font, and the
GetGlyphOutline API to get extremely detailed information about a specific
character in a specific font, but that of course would be overkill for most
purposes.

Thanks for pointing out the descender stuff. By the way, just check it out
on your own machine Jerry, to see if agrees with what I find here (the .8
instead of the .75 I mean). Try the following code and let me know the
result.

Mike

Option Explicit
Private Declare Function GetDeviceCaps Lib "gdi32" _
(ByVal hdc As Long, ByVal nindex As Long) As Long
Private Const PHYSICALOFFSETX As Long = 112
Private Const PHYSICALOFFSETY As Long = 113

Private Sub SetPrinterOrigin(x As Single, y As Single)
With Printer
  .ScaleLeft = .ScaleX(GetDeviceCaps(.hdc, PHYSICALOFFSETX), _
    vbPixels, .ScaleMode) - x
  .ScaleTop = .ScaleY(GetDeviceCaps(.hdc, PHYSICALOFFSETY), _
    vbPixels, .ScaleMode) - y
  .CurrentX = 0
  .CurrentY = 0
End With
End Sub

Private Sub Command1_Click()
Printer.ScaleMode = vbInches
SetPrinterOrigin 0, 0 ' top left corner of physical page
Printer.Print
Printer.Font.Name = "Times New Roman"
Printer.Font.Size = 100
Printer.Line (1, 4)-(8, 4)
Printer.CurrentX = 1
Printer.CurrentY = 4 - (Printer.TextHeight("M") * 0.8)
Printer.Print "MgjpqZ"
Printer.EndDoc
End Sub
Author
30 Sep 2005 9:06 AM
J French
On Thu, 29 Sep 2005 11:12:47 +0100, "Mike Williams"
<M***@WhiskyAndCoke.com> wrote:

Show quoteHide quote
>"J French" <erew***@nowhere.uk> wrote in message
>news:433ba90d.7139868@news.btopenworld.com...
>> On Thu, 29 Sep 2005 09:06:45 +0100, "Mike Williams"
>
>> Interestingly, the descender on all fonts I've tested is 25%
>> of the total height of the font [snip]
>> P.CurrentY = P.CurrentY - (P.TextHeight("M") * 0.75)

>Actually I find it to be nearer 20% on most fonts (so that he would use
>height * 0.8), but you're quite right Jerry about often needing to take it
>into account. My own suggested method is what I normally use simply because
>in the stuff that I write I usually want the text to fit neatly inside a
>"cell" (or a drawn rectangle) of a pre printed form, so that the descenders
>are also within the rectangle. However if the user wants his text to sit
>neatly on the line so that the main characters touch the line and the
>descenders fall below it then he needs to do as you suggest. Nice catch.

>He could, of course, use the GetTextMetrics and the GetOutLineTextMetrics
>APIs to get more detailed information about a specific font, and the
>GetGlyphOutline API to get extremely detailed information about a specific
>character in a specific font, but that of course would be overkill for most
>purposes.

>Thanks for pointing out the descender stuff. By the way, just check it out
>on your own machine Jerry, to see if agrees with what I find here (the .8
>instead of the .75 I mean). Try the following code and let me know the
>result.

Your test proves it perfectly - Many Thanks   0.8 it definitely is !

Like a prat I did not think to verify my assumption using extra large
characters.
Author
30 Sep 2005 12:05 PM
Lee Peedin
Guys,
Just wanted to let all of you know that this thread has been a joy to
follow.  I especially appreciate the info on "descender", something I
had been struggling with for quite a while.

I'm sure all of you have already figured it out, but I'll offer the
following in case there's someone reading that hasn't considered it
yet.

The following deals mainly with printing on pre-printed forms or even
mailing labels.

Since all InkJet & Laser printers have a physical offset
(non-printable region), quite often the programmer ends up with an
application that will work great with a particuliar model of printer,
but the alignment will be off if the user installs another printer
whose offset is not the same (and trust me, .25" is NOT a standard).

To overcome this, I use a little bit of math up front.
(I'm talking INCHES here)
Let's say I want something to print exact 1.25" from the far left of
the sheet of paper, which, of course is a position < CurrentX = 0.

First I retrieve (using GetCaps) the LOGPIXELX (value1).
Next I retrieve the PHYSICALOFFSETX (value2).

PrintPosition = 1.25
MarginLeft = value2 / value1
FarLeft = 0 - MarginLeft
CurrentX = PrintPosition + FarLeft 

Now, no matter what printer is used, the text will be exactly 1.25"
from the left side of the sheet of paper.

Anyone got any thoughts on this (or a better way of accomplishing the
same thing)?

Lee

On Fri, 30 Sep 2005 09:06:10 +0000 (UTC), erew***@nowhere.uk (J
French) wrote:

Show quoteHide quote
>On Thu, 29 Sep 2005 11:12:47 +0100, "Mike Williams"
><M***@WhiskyAndCoke.com> wrote:
>
>>"J French" <erew***@nowhere.uk> wrote in message
>>news:433ba90d.7139868@news.btopenworld.com...
>>> On Thu, 29 Sep 2005 09:06:45 +0100, "Mike Williams"
>>
>>> Interestingly, the descender on all fonts I've tested is 25%
>>> of the total height of the font [snip]
>>> P.CurrentY = P.CurrentY - (P.TextHeight("M") * 0.75)
>
>>Actually I find it to be nearer 20% on most fonts (so that he would use
>>height * 0.8), but you're quite right Jerry about often needing to take it
>>into account. My own suggested method is what I normally use simply because
>>in the stuff that I write I usually want the text to fit neatly inside a
>>"cell" (or a drawn rectangle) of a pre printed form, so that the descenders
>>are also within the rectangle. However if the user wants his text to sit
>>neatly on the line so that the main characters touch the line and the
>>descenders fall below it then he needs to do as you suggest. Nice catch.
>
>>He could, of course, use the GetTextMetrics and the GetOutLineTextMetrics
>>APIs to get more detailed information about a specific font, and the
>>GetGlyphOutline API to get extremely detailed information about a specific
>>character in a specific font, but that of course would be overkill for most
>>purposes.
>
>>Thanks for pointing out the descender stuff. By the way, just check it out
>>on your own machine Jerry, to see if agrees with what I find here (the .8
>>instead of the .75 I mean). Try the following code and let me know the
>>result.
>
>Your test proves it perfectly - Many Thanks   0.8 it definitely is !
>
>Like a prat I did not think to verify my assumption using extra large
>characters.
Author
30 Sep 2005 1:59 PM
Mike Williams
"Lee Peedin" <lpeedinREM***@UPPERCASEnc.rr.com> wrote in message
news:an9qj1p88g1es0naru916f088eg4jbje0q@4ax.com...

> Anyone got any thoughts on this (or a better way of
> accomplishing the same thing)?

Yes. Have a look at my posting in this very same thread of 27th September.
Here is an extract in case you missed it:

Option Explicit
Private Declare Function GetDeviceCaps Lib "gdi32" _
(ByVal hdc As Long, ByVal nindex As Long) As Long
Private Const PHYSICALOFFSETX As Long = 112
Private Const PHYSICALOFFSETY As Long = 113

Private Sub SetPrinterOrigin(x As Single, y As Single)
With Printer
  .ScaleLeft = .ScaleX(GetDeviceCaps(.hdc, PHYSICALOFFSETX), _
    vbPixels, .ScaleMode) - x
  .ScaleTop = .ScaleY(GetDeviceCaps(.hdc, PHYSICALOFFSETY), _
    vbPixels, .ScaleMode) - y
  .CurrentX = 0
  .CurrentY = 0
End With
End Sub

Private Sub Command1_Click()
Printer.ScaleMode = vbInches
' The following line will set location (0, 0) so that
' it points to the top left corner of the physical
' page for the rest of the print job.
SetPrinterOrigin 0, 0
' the rest of your printing code
End Sub

By the way, when you try the above you'll almost certainly quicjkly realise
that you are not limited to SetPrinterOrigin (0, 0), If you wish you can
instead do SetPrinterOrigin (1, 1), which will set the origin to exactly 1
inch from the top and one inch from the left. Or you can set it to the exact
middle of the page, which will allow you to very easily draw graphs and
things using four quadrants.

Mike
Author
30 Sep 2005 3:00 PM
Lee Peedin
On Fri, 30 Sep 2005 14:59:18 +0100, "Mike Williams"
<M***@WhiskyandCoke.com> wrote:

>"Lee Peedin" <lpeedinREM***@UPPERCASEnc.rr.com> wrote in message
>news:an9qj1p88g1es0naru916f088eg4jbje0q@4ax.com...
>
>> Anyone got any thoughts on this (or a better way of
>> accomplishing the same thing)?
>
>Yes. Have a look at my posting in this very same thread of 27th September.
>Here is an extract in case you missed it:

Thanks - somehow I gazed right over what you were doing (couldn't see
the forest for the trees).

Thanks
Lee
Author
30 Sep 2005 3:36 PM
J French
On Fri, 30 Sep 2005 15:00:25 GMT, Lee Peedin
<lpeedinREM***@UPPERCASEnc.rr.com> wrote:

<snip>

>Thanks - somehow I gazed right over what you were doing (couldn't see
>the forest for the trees).

Lee, you are the guy that creates 200 PDFs per day ?
- some form of printed (or laptop) publishing I guess

Mike is the local guru on 'fancy printing'
- I've got a directory full of his demos

It will be interesting watching ...
Author
30 Sep 2005 4:10 PM
Lee Peedin
That's correct J, but when creating PDF files, you have no concern
with non-printable areas, since there are none on a PDF.

As far as the number of PDF files we create each day: we run a data
collection service via telephony & web based.  Some of the data we
collect is sent to the customer in "flat files" for importing into
their mainframe applications and some is sent in Excel files. (If you
eat pork, there's an 85% chance that something about that animal went
through our system before it became pork chops. :-) )

However, one of our largest clients is a Home Care & Hospice provider
that we collect employee's patient visit start/stop times along with
mileage.  They have 38 offices and need/want the data presented in 4
different formats on a daily basis.  So for that client alone we
create 152 PDF files on a daily basis - plus all the weekly and
bi-weekly employee signoff sheets that are also in PDF format.  There
are numerous other clients that we do similar work for, just on a
smaller scale.

BTW: I'm also the guy that "wrapped" the VB PrinterObject into an
ActiveX dll (along with the GetCapabilities API) so that printing can
be accomplished in any scripting language (ooRexx, VBScript, etc.)
that supports ActiveX/OLE.

I just got a letter this week from a major insurance company
indicating that they will be installing ooRexx and my RxVB.dll on over
1000 of their WinXP desktop systems. 

Lee

On Fri, 30 Sep 2005 15:36:32 +0000 (UTC), erew***@nowhere.uk (J
French) wrote:

Show quoteHide quote
>On Fri, 30 Sep 2005 15:00:25 GMT, Lee Peedin
><lpeedinREM***@UPPERCASEnc.rr.com> wrote:
>
><snip>
>
>>Thanks - somehow I gazed right over what you were doing (couldn't see
>>the forest for the trees).
>
>Lee, you are the guy that creates 200 PDFs per day ?
>- some form of printed (or laptop) publishing I guess
>
>Mike is the local guru on 'fancy printing'
>- I've got a directory full of his demos
>
>It will be interesting watching ...
Author
30 Sep 2005 4:32 PM
Mike Williams
"Lee Peedin" <lpeedinREM***@UPPERCASEnc.rr.com> wrote in message
news:e3oqj11vosdtq9h4ort5r4gd52gijmg45p@4ax.com...

> That's correct J, but when creating PDF files, you have no
> concern with non-printable areas, since there are none on a PDF.

I hope you don't mind Lee if I point out that even though the PDF file
itself might at design time have no knowledge of "non printable" areas
(because it of course doesn't know at that time what device it will
eventually be printed on) its actual output will certainly be limited by
such things. A printer that has non printable margins is physically
incapable of depositing ink into them, and even your PDF file cannot make it
do so. I don't actually know anything about the format of PDF files, and it
may well be that file itself or whatever driver it uses will examine the
current output device at "print time" and position everything correctly on
the page, but it definitely won't be able to put ink in areas where the
current output device won't let it. For example, one of my printers is a
Citizen Printiva, and it is impossible for you to write a pdf file that will
print stuff into the top 0.5 inch border or the bottom 0.6 inch border or
the two side borders.

Mike
Author
30 Sep 2005 4:53 PM
Lee Peedin
Oh - you are quite correct Mike.  Just because something looks exactly
like you want it in a PDF, by no means is an indication that will it
will produce the desired format when the PDF is printed.  Internally,
I use PDF as a "print preview", but only for alignment of the various
parts of the text - not for the final "paper" alignment. 

Yep, gone are the days when you could load 8.5x11 paper in a dot
matrix and print 132 characters wide (even if you deposited ink on the
roller). :-)

Gone also are the days when you could simply write everything to a
text file using a non-proportional font and then simply "type text.txt
>lpt1".

Lee

On Fri, 30 Sep 2005 17:32:52 +0100, "Mike Williams"
<M***@WhiskyandCoke.com> wrote:

Show quoteHide quote
>"Lee Peedin" <lpeedinREM***@UPPERCASEnc.rr.com> wrote in message
>news:e3oqj11vosdtq9h4ort5r4gd52gijmg45p@4ax.com...
>
>> That's correct J, but when creating PDF files, you have no
>> concern with non-printable areas, since there are none on a PDF.
>
>I hope you don't mind Lee if I point out that even though the PDF file
>itself might at design time have no knowledge of "non printable" areas
>(because it of course doesn't know at that time what device it will
>eventually be printed on) its actual output will certainly be limited by
>such things. A printer that has non printable margins is physically
>incapable of depositing ink into them, and even your PDF file cannot make it
>do so. I don't actually know anything about the format of PDF files, and it
>may well be that file itself or whatever driver it uses will examine the
>current output device at "print time" and position everything correctly on
>the page, but it definitely won't be able to put ink in areas where the
>current output device won't let it. For example, one of my printers is a
>Citizen Printiva, and it is impossible for you to write a pdf file that will
>print stuff into the top 0.5 inch border or the bottom 0.6 inch border or
>the two side borders.
>
>Mike
>
>
>
Author
30 Sep 2005 3:38 PM
Mike Williams
"Lee Peedin" <lpeedinREM***@UPPERCASEnc.rr.com> wrote in message
news:lmkqj1t4j3nbq563000a875trqlkv5mkfr@4ax.com...

> Thanks - somehow I gazed right over what you were
> doing (couldn't see the forest for the trees).

That's okay. Sometimes my postings are a bit "longish" (I've been told off
about it before). It's easy to miss stuff in them.

Mike