Set TextMerge, Set("TextMerge"), \, \\, _PreText, _Text, Set TextMerge Delimiters, TextMerge()
Textmerge is a combination of several of FoxPro's best features—it creates low-level file output, performs runtime evaluation and eases formatting of different types of data. \ and \\ are the textmerge equivalents of ? and ??, outputting to the destination specified by SET TEXTMERGE TO, rather than SET DEVICE TO. Starting in VFP 7, you have several new options for creating textmerge output, including the ability to send the results to a variable.
Usage |
SET TEXTMERGE [ ON | OFF ] | [ TO FileName | TO MEMVAR VarName [ ADDITIVE ] ] [ WINDOW WindowName ] [ SHOW | NOSHOW ] cOnOrOff = SET( "TEXTMERGE" ) cMergeFile = SET( "TEXTMERGE", 2) cShowOrNot = SET( "TEXTMERGE", 3) nRecursionLevel = SET( "TEXTMERGE", 4) |
? LTRIM(STR(nNumber,4)) + space(6) + ; DTOC(Date()) + SPACE(7) + ; TTOC(DateTime()) + SPACE(4) + ; "Page #" + ltrim(_PAGENO)In a textmerge document, you would just say:
\<<nNumber>> <<Date()>> <<Datetime()>> Page # <<_PAGENO>>Now which would you prefer to have to decode and maintain six months after you wrote it?
SET TEXTMERGE is different from SET ALTERNATE or SET PRINT in that you can both SET TEXTMERGE TO and ON in a single line. For ease of maintenance, we advise you to splurge on the two lines of code to SET TEXTMERGE TO and ON. |
Unlike the command to SET TEXTMERGE ON and SET TEXTMERGE TO, you must write two separate lines of code to SET TEXTMERGE OFF and SET TEXTMERGE TO, so that's an even a better reason to have two matching pairs of commands. |
The original release of VFP 7 sometimes crashes when you mix TEXT TO processing with SET TEXTMERGE processing. It's fixed in SP1. |
The help file claims that SHOW is the default—that's true the first time SET TEXTMERGE is issued. After that, the default appears to be the last setting used—that is, if NOSHOW was issued with the previous command, text will not be echoed unless SHOW is explicitly specified. So this isn't really a "default" behavior, it's more like a global SET behavior. Always specify SHOW or NOSHOW and you won't have a problem. |
Unfortunately, SET("TEXTMERGE",4) uses a ridiculously narrow definition of recursion. It adds a level to the count only if the expanded string contains the same variable from which it was expanded. That is, if you expand the variable ExpandMe and its text contains the string "<<ExpandMe>>", the count goes up (which it should). However, when talking about textmerge, the term "recusion" generally applies to any expanded string that contains the textmerge delimiters, not just expanding the same string over and over. SET("TEXTMERGE",4) doesn't go up if you expand the variable ExpandMe and it contains the string "<<MeToo>>". |
There's no way to find out what variable you've SET TEXTMERGE to. |
Example |
* The *best* examples of textmerge are available in your main * Visual FoxPro directory - check out GENMENU.PRG and others. * But here's something for you to try: LOCAL lcOldPreText * SET TEXTMERGE ON TO textmerg.txt NOSHOW && Don't do this! SET TEXTMERGE TO textmerg.txt SET TEXTMERGE ON NOSHOW \Generated at <<DATE()>> <<TIME()>> \ TEXT This is a block of text with no comments or anything before it ENDTEXT \ \Now we add a pretext \ lcOldPreText = _PRETEXT _PRETEXT = "*"+CHR(09) TEXT Four score and seven years ago, our forefathers (and mothers) brought forth upon this continent a new nation, ENDTEXT _PRETEXT = lcOldPreText \ \ And delimiters are evaluated within TEXT...ENDTEXT \ TEXT Today is <<DATE()>> and the time is <<TIME()>> ENDTEXT SET TEXTMERGE OFF SET TEXTMERGE TO MODI FILE textmerg.txt * Textmerge to a variable SET TEXTMERGE TO MEMVAR cHTML SET TEXTMERGE ON NOSHOW \<HTML> \<HEAD> \<TITLE><<Customer.Company>></TITLE> \</HEAD> \<BODY> \Address: <<Customer.Address>> \</BODY> \</HTML> * and so forth to build an HTML document SET TEXTMERGE OFF SET TEXTMERGE TO StrToFile( cHTML, "MyHTMLDoc.HTM" ) |
Usage |
_PRETEXT = cTextToPrecede cTextToPrecede = _PRETEXT _TEXT = nHandle nHandle = _TEXT |
Example |
_PRETEXT = "*" + CHR(9) && Comment and indent merged text. SET TEXTMERGE TO D:\TEXTMERG.TXT ? _TEXT && Displays the opened file handle. |
Usage |
SET TEXTMERGE DELIMITERS TO [ cLeftExp [, cRightExp ] ] cAllDelimiters = SET( "TEXTMERGE", 1 ) |
This means that you can't really parse the return value of the SET() function and be sure where the first delimiter ends and the second begins—see the second example below. So a "black box" routine cannot mess with these values. A return length for SET("TEXT",1) of 3 means you're doomed, since you don't know which one of the delimiters has two characters. It would be better if this SET() function, like most of them, returned the explicit string that we could use to SET TEXTMERGE DELIMITERS TO &OurString, and leave the parsing to us. Our advice: Don't do this. Leave the delimiters as they are, or if you must change them, change them to something simple like a matched pair of single or double curly braces or something. |
Example |
SET TEXTMERGE DELIMITERS TO "::", "::" SET TEXTMERGE DELIMITERS TO "@~","@" ? SET("TEXTMERGE",1) && returns "@~@" - but which is which? |
Usage |
cMergedOutput = TEXTMERGE( cString [, lRecursive [, cLeftDelim [, cRightDelim ] ] ] ) |
Parameter |
Value |
Meaning |
cString |
Character |
The string to be evaluated. |
lRecursive |
.T. |
If a merged expression contains the textmerge delimiters, keep evaluating the contents of the delimiters again until no more delimiters are found. |
.F. or omitted |
Evaluate strings inside the textmerge delimiters only once. |
|
cLeftDelim |
One or two characters |
The left delimiter for textmerge within the function. |
Omitted |
Use the current left delimiter from the SET TEXTMERGE DELIMITERS setting. |
|
cRightDelim |
One or two characters |
The right delimiter for textmerge within the function. |
Omitted |
Use the current right delimiter from the SET TEXTMERGE DELIMITERS setting. |
Example |
#DEFINE CRLF CHR(13) + CHR(10) cString = "<HTML>" + CRLF cString = cString + "<HEAD>" + CRLF cString = cString + "<TITLE><<Customer.Company>>" + ; "</TITLE>" + CRLF cString = cString + "<BODY>" + CRLF cString = cString + "Address: <<Customer.Address>>" + CRLF cString = cString + "</BODY>" + CRLF cString = cString + "</HEAD>" + CRLF cString = cString + "</HTML>" cHTML = TextMerge( cString ) |
See Also |
FError(), Low-Level File Functions, Set Alternate, Set Printer, Text ... EndText |