THE FoxPRO FAQ


PART 4a: TIPS etc. (OR THINGS MOTHER NEVER TOLD YOU)

February 2nd, 1996 foxfaq@iinet.net.au
Comment and suggestions are invited. DISCLAIMER: Most of the information in this FAQ is unsupported by Microsoft. No guarantees of any sort are made about the information contained in this FAQ. If you use something you find here and wind up clobbering all your data, it's your problem solely. INDEX
INCOMPATIBLE HARDWARE FOR FOXPROW According to the FoxPro Resource Kit for 2.5, the following cards have problems with FoxPro: ATI Ultra Graphics Pro (local bus) AST Power Premium 486 with VGA motherboard Genoa 7900 MM card Dell 486/20 with VGA on motherboard COMPAQ QVision Speed Star 24x Trident 8900C TIGA 1024x768x256 small fonts NEC 2A MACH32 MATROX MGA video driver using 1024x768 resolution Orchid Fahrenheit 1280 card using Windows 3.1
Return to Index

SYSTEM SETTINGS (To try for better performance or in case of conflicts) MEMLIMIT Try these MEMLIMIT settings: MEMLIMIT = 50, 2432, 4096 SWAP FILES Have a PERMANENT SWAP FILE set up in your Windows Control.exe 386 Enhanced Virtual Memory settings (6 TO 9 Meg) 32 BIT DISK ACCESS Don't turn on 32 bit disk access in Windows Ver 3.1 but OK to do so in Ver. 3.11 ENVIRONMENT SPACE Have about 1K of environment space available: config.sys: shell=c:\command.com /e:1024 /p BREAKPOINTS (Windows for Workgroups - GPFs) system.ini: [386Enh] MaxBPs=768 (Specifies the maximum number of breakpoints (a method for transferring control to WFW in 386 enhanced mode), default=358 (4k) optional: 768 (8k), 1177 (10k), 1586 (12k)) UPPER MEMORY CONFLICTS Try: system.ini: [386Enh] EMMExclude=A000-FFFF ABNORMAL PROGRAM TERMINATION FIX IN EXTENDED FOXPROX Try: autoexec.bat: SET FOXPROX=-saveregs (This command tells FoxPro to preserve any registers in use and not to overwrite them while running).
Return to Index

GENERATING COMPLEX INDEXES ON NUMERIC FIELDS There's an interesting "feature" that the FoxPro manuals don't tell you about in the information on indexes. Let's say you have a database: ACCOUNT N(6,0) SSN N(9,0) On first glance, if you wanted to sort the database by social security number, and then account, you can just: INDEX ON SSN+ACCOUNT TAG myorder SET ORDER TO myorder This, of course, doesn't work. What happens is that FoxPro just adds the values together, causing: SSN = 076541111 ACCOUNT = 999999 (Key value = 77541110) To appear AFTER SSN = 076541122 ACCOUNT = 000333 (Key value = 76541455) Note: Microsoft says that this problem doesn't occur if you are working with N(x,y > 1) fields, date fields, or logical fields. What can you do to sort properly? There are several schools of thought: (1)You can add a digit after the decimal point. Microsoft assures me that this will solve the problem. (2)If you're working with fixed length fields, you can shift one set of digits over so that your math is correct. In the above example, you would want to: INDEX ON ssn*1000000+account TAG myorder (3)Convert the numerics into strings, and concatenate them: INDEX ON STR(ssn)+STR(account) TAG myorder or: INDEX ON TRANSFORM(ssn,"#########")+TRANSFORM(account,"######") ; TAG myorder
Return to Index

GETTING RID OF THE MICROSOFT FOXPRO SCREEN AND TITLE The first thing to do if you're tired of seeing "Microsoft FoxPro" every time you start your application is to use the -T command line option to prevent it from showing up. This looks like this: FOX -T If you're using FoxPro/Windows or FoxPro/MAC, and want to get rid of the "Microsoft FoxPro" title in the bar of the main screen, you can do a couple of things. : After your application starts, you can MODIFY WINDOW screen TITLE "My Title" and the window name will change to whatever your title is. You can put the following line in config.fpw/config.fpm: TITLE=My Title Note the lack of quotes. This will cause the main window to be listed as "My Title" as soon as FoxPro starts up. For some reason, there are differences in the way this works depending on whether you are running your application from the development kit or the distribution kit.
Return to Index

OUTER JOINS IN FOXPRO SELECT-SQL (David Churcher) I give up, I RTFM (and I got FAQ'd) and did not find the syntax. Using the foxpro Select command, I wish to join two or more tables inclusively. By this I mean : To join Table A and B, if there is no join then include the records from table A and place blanks in the fields from table B. In previous versions of foxpro I would have used "Set relation to" and it would have just happened. Oh no, it's the dreaded Left Outer Join! This is an SQL construct which FoxPro doesn't currently support, so you have to simulate it using a UNION of two selects: one for all the records with matches in table B, and one for all the records without. Here's an example: SELECT a.keyfield, ; a.datafield1, ; b.datafield2, ; b.datafield3 ; FROM a,b ; WHERE a.keyfield = b.keyfield ; UNION ; SELECT a.keyfield, ; a.datafield1, ; 000.00, ; 000.00 ; FROM a ; WHERE a.keyfield NOT IN ; (SELECT b.keyfield ; FROM b) Couple of points: 1. The numeric and string constants in the second SELECT (000.00 in this example) have to exactly match the length of the fields in the second database, because FoxPro requires both sides of a UNION to exactly the same structure. 2. SET RELATION TO and SET SKIP TO may be faster and easier if it's only a simple query.
Return to Index

THE DIFFERENCE BETWEEN '=' AND '==' (Pete Kruckenberg) The rules for determining how string comparisons are done seem to be very complicated (confusing), depending on whether you use the '=' or '==' operator, the setting of various SET parameters (ANSI, EXACT), the positioning of the two strings on either side of the comparison operator (a=b or b=a), and whether the comparisons are being done in FoxPro directly or in an SQL SELECT. The exact same comparison expresion, or what appears to be a logically equivalent expression, will give different results in different setting environments, causing no end of trouble in debugging. Here are the rules (at least, as I understand them): = : SET EXACT OFF only compares as many characters as are in the right-hand-side: "abc" = "ab", but "ab" != "abc" SET EXACT ON pads the shorter of the two with spaces on the right, then compares the strings. Spaces after the strings are ignored. So, "abcd" = "abc" returns false, but "abc " = "abc" returns true. SET ANSI does the same thing for SQL commands that SET EXACT does for non-SQL commands. ==: compares the strings both character-for-character, and their length. So, "abc" != "ab", "ab " != "ab", but "abc" = "abc" SET EXACT doesn't change the operation of == So, the rule is: =, SET EXACT OFF Look at all the characters of a string, ignore extra spaces: =, SET EXACT ON Look at all the characters, plus the length of the strings: == Look at all characters Also, remember that SET EXACT also affects searching via SEEK(), in the same way it affects =. One thing to be careful of is using x = "" with SET EXACT OFF. It is true that x = "" for any string x, because no characters are compared. To test for an empty string, it's usually best to use EMPTY(x) instead. Pete.
Return to Index

MAKING BROWSES WORK WITH OTHER WINDOWS The simplified basics of this are: 1.Define a browse window 2.Define and activate another window that contains your Buttons and other objects and that is sized and located so that it DOES NOT OVERLAP your browse window. 3.Call the browse using BROWSE IN WINDOW NOWAIT SAVE etc etc 4.Finally, do a READ CYCLE MODAL WITH brtitle where brtitle is: a. The first word of the title of the browse or IF NO TITLE then b. The database alias. This gives you a control screen that coexists with a browse. From then on you can: add extra browses, add extra windows, add a container window to make it look as if it is all the one screen, add keyboard stuffers to enable you to start in the BROWSE, (See Drew Speedie's article in September '94 Foxpro Advisor) e.g. DEFINE WINDOW bgrnd FROM 0,0 TO SROWS(),SCOLS() ; COLOR RGB(,,,192,192,192) DEFINE WINDOW control FROM 0,0 TO 5,SCOLS()-5 COLOR N/RG* MOVE WINDOW control CENTER DEFINE WINDOW br1 FROM 0,0 TO (SROWS()/2)-5, SCOLS()/2.1 DEFINE WINDOW br2 FROM 0,SCOLS()/1.9 TO (SROWS()/2)-5, SCOLS() DEFINE WINDOW br3 FROM (SROWS()/2)+5, 0 TO SROWS(), SCOLS()/2.1 DEFINE WINDOW br4 FROM (SROWS()/2)+5,SCOLS()/1.9 TO SROWS(), SCOLS() ACTIVATE WINDOW bgrnd ACTIVATE WINDOW control @ 1,WCOLS()-15 GET quitit PICTURE '@*T QUIT' DEFAULT 1 SIZE 2,10 ACTIVATE WINDOW br1 ACTIVATE WINDOW br2 ACTIVATE WINDOW br3 ACTIVATE WINDOW br4 USE table1 in 0 USE table2 in 0 USE table3 in 0 USE table4 in 0 SELECT table1 BROWSE IN WINDOW br1 NOWAIT SAVE SELECT table2 BROWSE IN WINDOW br2 NOWAIT SAVE TITLE "Title for Table 2" SELECT table3 BROWSE IN WINDOW br3 NOWAIT SAVE SELECT table4 BROWSE IN WINDOW br4 NOWAIT SAVE READ CYCLE MODAL WITH table1, "Title for Table 2", table3, table4 CLOSE DATABASES RELEASE WINDOWS control, br1, br2, br3, br4, bgrnd
Return to Index

COPYING A BROWSE FIELD TO THE CLIPBOARD lcdbf=ALIAS() lcfield=VARREAD() lcvar=lcdbf+'.'+lcfield _CLIPTEXT = &lcvar
Return to Index

SELECTING DUPLICATE RECORDS FROM A TABLE SELECT * ; FROM mydbf d1 ; WHERE EXISTS ; ( SELECT * ; FROM mydbf d2 ; WHERE d2.keyfield = d1.keyfield ; GROUP BY keyfield ; HAVING COUNT(*) > 1 ) ; ORDER BY keyfieldlist or SELECT * ; FROM mydbf ; WHERE keyfield IN ; ( SELECT keyfield ; FROM dbf ; GROUP BY keyfield ; HAVING count(*) > 1) ; ORDER BY keyfieldlist
Return to Index

MACRO EXPANSIONS - TERMINATING CHARACTER The FoxPro Macro Expander evaluates the first dot (period) after a macro'd variable as a directive to remove trailing spaces. Therefore &m.filter doesn't work because "." is the terminating character for the macro expansion SELECT &XXXX.field FROM &XXXX doesn't work either but can be rectified by using SELECT &XXXX..subsystem FROM &XXXX (note the two .'s).
Return to Index

MACRO EXPANSIONS - EXECUTING CODE You can use & to interpret and execute memvar instructions. e.g. lc='? DATE()' &lc (try writing self-modifying code) TYPE() is also useful to test for illegal functions etc, as it returns "U" if your command contained a syntax error etc.
Return to Index

HELP - MY .EXE WILL NOT RUN (David Nason) >I am using FPW2.6. I have created an .exe file using the >distribution kit. The file executes ok in FP (using DO >filename.exe). BUT, when I try to run it in Windows, it bombs >(it executes - showing the menu for a quick second and then >exits back to Windows. Does anyone have any ideas about what >the problem may be ? The famous Foundation Read strikes again!!! You must have a Foundation Read in your code. This is basically a READ VALID for which the condition is never true while the program is running. You will find details and examples in the Help and Developers' Manual. Just a quick review here...I always start my program from a START.PRG which is more or less along these lines: ***start.prg DO opener && Opens all .DBFs and sets up relations DO vars && Declares all public variables PUBLIC m.quit && m.quit is .f. by default DO main.mpr READ VALID m.quit && The QUIT menu button changes m.quit to be .t. before returning here. QUIT **** end of start.prg
Return to Index

RUN COMMAND - MODIFIERS (Dave Teske) In windows the command RUN /N can be used to start another windows program in several different modes. Here is a list of the /N options for windows: N Application Mode ********** ************************* 1 Active and normal size 2 Active and minimized 3 Active and maximized 4 Inactivate and normal size 7 Inactivate and minimized e.g. when starting WinFax for DDE operations: RUN /7 c:\winfax\faxmng.exe.
Return to Index