Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Detecting when a memo field stretches over into page and beyond on a report

Status
Not open for further replies.

Steve-vfp9user

Programmer
Feb 5, 2013
337
GB
I have a form with a memo field where the user types in text for job proposals.

Is there a way to show when the text being typed extends over on to page 2 and subsequent pages similar to that of Microsft Word when, as you type, if you go beyond page 1 you can clearly see that it's page 2.

VFP9, service pack 2 with Windows 10.

Thank you

Steve
 
Steve,
Depends on your idea of "page" (US Letter, legal size, Rest of the world A4, B4, A3, etc). So you need to do a few things.
1) Determine the target page size
2) Determine the font used and font height.
3) Determine line spacing addition (if more than 1)
4) Determine how many lines of text at that font and size will fit on the page.
5) Determine when you have that number of lines. You could then "restrict" further text from being entered if you want to hold it to 1 page, or give a warning that a new page is being started.

What is your objective. Why are you trying to determine the amount of text in a memo field vs. page consumption?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Hi Scott

Thank you for the comprehensive post.

In answer to your points:

1) Determine the target page size
A4

2) Determine the font used and font height.
Would like to use Times New Roman or Arial

3) Determine line spacing addition (if more than 1)
I'm not aware you can choose line spacing in VFP for a memo field on a report but if there is a way, 1 and a half

4) Determine how many lines of text at that font and size will fit on the page.
We have tried a few reports and 24 lines seems to be enough as we have a header and footer on the report page

5) Determine when you have that number of lines. You could then "restrict" further text from being entered if you want to hold it to 1 page, or give a warning that a new page is being started.
Give a warning (perhaps wait "message" window nowait warning for the user

What is your objective. Why are you trying to determine the amount of text in a memo field vs. page consumption?
The objective is for the user to be made aware when they are about to start or have started the next page as they are typing into the memo field


Thank you

Steve
 
Hi Steve,
I don't understand the last part. If you "warn" them and then they go ahead anyway, how is this any different if you're going to continue the memo text on a new report page?

There are a few ways to approach this as well, some of which may be more accurate than others. Memo has a line length that can be set, so you can then use ALEN() to determine the number of lines in the Memo. When the number of lines exceeds the number of lines you have available for the other items you've determined, then you know when it has to stop.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Oh, sorry I mislead you there. It should be ALINES() function, not ALEN function. Was just thinking off the top of my head and mentioned the wrong function.
MEMLINES might be even better, I haven't tried it, just trying to point you in the right direction...

I assume you mean the user to "know where the page is" in the Memo field.
I'm not aware of a way to "signal" it in the memo field, but what you could do is keep a running check on the editbox, and update an external visual. Something like "Lines Remaining". If can be a lable that starts at 24, and then reduces each time a line is completed. (Because it's not specifically about length, it's about length and CR/LF (or soft paragraph). So a line of text may be 80 characters long, but if at 20 characters into the line, there Enter key is pressed, then that will mark a fully used line as well.

You'll have to tinker with it.
Create a label above your edit box, name it lblEditLength

Then in the edit boxes keypress event, check to see how many lines are used. Then update with something like:

ThisForm.lblEditLength.Value = "Lines Remaining " +STR(MEMLINES(edtMemoField))+ " of 24"
ThisForm.lblEditLength.Refresh()

This one may be best becuase SET MEMOWIDTH will determine the width of a line.
So if you want a line to be 100 characters, in the Form INIT or Load:

SET MEMOWIDTH 100

Where edtMemoField is the name of whatever edit object (text box, edit box, etc) you're using for the text entry.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Sorry, but I don't think Scott's solution will work.

ALINES() will not help you calculate the number of lines that will appear in the report. ALINES() will only count the number of lines that are terminated by a carriage-return and/or line-feed (or any other designated character). It doesn't do word wrap, so won't give you the number of lines that will actually appear

MEMLINES() will give you the number of lines, but only based on a given number of characters per line (as specified by SET MEMOWIDTH). In a report, the number of characters per line is variable (unless you use a fixed-pitch font), so again you can't use it to get the actual number of lines.

A better approach is to use FONTMETRICS(). Provided you know the font, font size and font style (e.g. bold) of the text, it is possible to calculate the height and width of a given piece of text. See Find the height and width of a text string in pixels for a function that does that. If you call that function from the InteractiveChange of the control where the user edits the text, you can issue a warning as soon as the number of lines goes beyond the number available on the page.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I did this with MEMLINES and MEMOWIDTH earlier today actually. I just use left text justification... it was pretty good. FONTMETRIC will work for certain, but it's going to be a lot of work for novice...

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
FONTMETRIC will work for certain, but it's going to be a lot of work for novice...

Well, if he uses the TextWidth() function in the page that I linked to, he can just copy and paste it into his app, then call it from the control's InteractiveChange.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
But isn't there a gotcha with that as mentioned:

Unfortunately, TXTWIDTH() doesn't work with multi-line text. Any CRs or LFs in the string are treated as if they were printable characters, with a specific width of their own. The total width of the string will be that of all the characters, regardless of how many lines they occupy.

In which case he still needs the MEMLINES function...

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
The form.TextWidht/TextHeight functiosn will far superior over both TXTWIDTH and MEMLINES, which both only work with counting characters and not at all taking into account W is far wider than i in propoertional fonts. TXTWIDTH only works with an average character width and MEMLINES only counts characters.

You have Label.Widht and Height to better measuer. If you set a label to autosize and textwrap=.t. It displays quite like the editbox, but instead of scrollbars appearing, the abel stretches and you can read width and height in pixels from its width and height properties. But what width will correspond to paper width - and what about respecting margins/printable area?This is a subject with no ends.

And there's another major problem in that all such widths and heights on screen don't easily translate to reports and their points unit. Most fonts (TTF) render with bitmaps on screen and via vector graphics on print, and that doesn't translate.

In the end a editbox or label or whatever control also don't compare to a Word page canvas, which is nearer to the printing representation during genereating/writing texts. Foxpr is not a text processor. If you want text processing capabilities, why not automate Word?

In VFP, your main report tools in regard of the single report controls are "Stretch with overflow" in the general tabe and all the print when options. And in regard of band with the property "start detail set on new page when less than ... cm/inch/mm are available on the current page. What really happens in conjunction with the printer, printer driver and windows spooler is not really foreseeable with any screen related measurement functions.

Bye, Olaf.
 
Completely agree with you Olaf. I think what Steve (OP) user is after is a really more a guideline than absolute, since he's going to allow the user to proceed to 2nd (or more page) anyway, but with some indicator as to where the page will break, MEMLINES seems to be a close approximation with not horrendous amounts of effort. The Memo will auto continue to the next page in a detail band in the report anyway. I don't really see why the OP is really that keen on knowing since it doesn't stop the user continuing in text.

Back in the day, I wrote some very complex reports in FPD2.6 using HPGL to control text on a page. If you're willing to forgo the VFP report writer, and get down and ugly with your own routine, you can actually produce some very sophisticated manipulation of spacing and lines, when to determine to continue and when to make a new line. I had line spacing being added so that the one page report (which was a formatted CV) would all use the same amount of space on the page. This make people with "light weight" CV not seem as bad because the white space was dispersed evenly vertically in the page. BUT... it requires writing specifically to a printer type (or at least print engine type). If you're just printing to HP Lasers, then this works fine...

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Olaf has made a very good point. Even if you could calculate the number of lines that will be rendered on the screen (as in a report preview, for example), there's no guarantee that the same number would apply in the printed page. Different printer drivers have subtle differences in the way they print (caused by very slightly different font metrics or by small unprintable areas at the sides of the page). So to do the job properly, you would need to also know the printer driver, as well as the font sizes, styles, etc.

Maybe you need to look for a different method of meeting your goal. Would the user be happy with relying on the report preview as a way of knowing if the text will overflow the page? That would be less elegant, but it would guarantee the correct result. Or would it be worth looking for a different reporting tool? Could you do the job using Word Automation, for example?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I would also say, as Mike, that the FRX print preview is your only chance to know what will come out, I have very rarely seen preview not matching the final print, and the one time that was the case, I think it had to do with printer loaded fonts VFP could not access and had no equivalent in Windows for the preview. At least with FRX reports, obviously, if you print in a direct fashion your output even more depends on the printers fonts.

Bye, Olaf.

 
Olaf, I wasn't suggesting that the preview wouldn't match the final print. My point was that the preview has to know which printer driver will be used for the final print. And that any algorithm that calculates the number of lines of text would also have to be aware of the printer driver.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
My point was not contradicting yours. I think the preview is a very good measurement. I doubt you can do as the preview can, but maybe a listener could, which means you would actually also run a report with a listener in preview mode without displaying a preview but measuring how many pages are rendered. Since a listener can do what you like, it can also show no preview and not print.

Did you have that in mind, Mike?

Bye, Olaf.

 
Hello guys

Apologies for not posting back, but I will go through the read and get back soon.

I appreciate your comments.

Thank you

Steve
 
If I develop a report where the detail section contains a memo, which could
cause issues if not controlled I do a couple of things;

Firstly, I try to control the size on the input data by validating the
number of lines the user can input into the memo field - if that is
practicable, which it is if the memo is an address or something like that.

Secondly, I turn each line of the memo into a detail line itself - so the cursor
that generates the report has a record for each line in the memo that might cause
the problem - thus I can control the size of the memo, even changing to a different
font if needs be where I'm trying to avoid widows and orphans - so if just one or two
lines were headed for a second page I could invoke a different (smaller) font perhaps
using the 'print when'. This approach has other 'advantages' in that you can also put
text effects in place on a line by line basis (bold/italic/colour).


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
so the cursor that generates the report has a record for each line in the memo that might cause the problem

Griff, just out of curiosity, how do you handle word wrap in that situation? Or, put another way, if each record corresponds to one line of text, how do you know where the line will break? With a name and address, you would have each elemement of the address on a line by itself, but that wouldn't be the case with free-flowing text.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi

I just set the memowidth to what I want - often 80 or 100 chars - then use memlines() to get the count and mline() to extract the actual line.
You are stuck with left hand justification and often with this approach I choose a fixed width font. Your printing space has to be generous to
make sure it's never too wide and if you use the decreasing font technique to avoid widows and orphans you need to move the text to the right
as it get smaller or it looks a tiny bit odd.

Normally I only use this approach where the desired result is a one or two page report (like an inspection report, not an invoice).

Doesn't work with everything, but it's another tool in the box...

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Yes, I agree with Mike free-flowing text is a big problem of that. The original problem is even worse as the goal is to mark page breaks within the UI when entering text. Posts now rather concentrate on how to control report behaviour. It may actually be fine to let the report engine do its line and page break of the memo text, Steve only wants to indicate where text breaks are and that's quite impossible to tell but with a report preview. The problem is you can't have an interactive preview changing as you type and change the source data.

The requirements ask to be solved automating Word and also using it for printing instead of a VFP report overall, so this will be a major rewrite. Splitting memos in lines, even if you get it going including word wrap, will need a detail band only having the memo field, or how do you handle repeted print of other report fields in the band printed with a memo line? I also see some advantages, eg you can introduce a line spacing by simply setting the band height up. But it's a longwinded way to get to lines with proportional fonts and freeflow text wrapping. MEMLINES does only split on number of characters (keeping whole words), ALINES only on given line separator (CRLF by default, but you can apply whatever separators - won't help with freeflow tet, though).

You can work with Memlines, if imperfect line breaks are ok with you. Forget WYSIWYG anyway. If you're concerned with WYSIWYG, you'd also need to go the route of Word automation instead.

Bye, Olaf.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top