THE FoxPRO FAQ
PART 4a: TIPS etc. (OR THINGS MOTHER NEVER TOLD YOU)
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