Tech Frequently Asked Questions
What
files do I need to distribute with my application?
You'll
need to include APP files, DBFs, and possibly other files. For a
complete listing, see "Foxfire! Application Integration and Distribution"
in the Foxfire! online documentation
I've
set up my own Preference Set and I'm ready to distribute it. Is
there any easy way to get rid of all the Foxfire! sample
stuff?
If
you use the Preference Set Editor to delete the 'Demo Use of Views'
record and then the 'Sample Data Set' record, you will be prompted
with a dialog asking whether you'd like to delete the sample tables
as well. These steps will quickly remove all traces of the samples
from your system.
Running
in VFP3, I'm getting a "versions do not match" error. Why?
Microsoft
changed FOXTOOLS.FLL between v3.0 and v3.0b. The files shipped with
Foxfire! (in \3XLIBS) are the v3.0b ones. When FOXTOOLS
is loaded, it seeks out two 'companion' files, DDEREG.EXE and FLL32_16.DLL.
If the v3.0b version of FOXTOOLS finds the v3.0 version of one or
more of the other files, you'll see the version mismatch error.
The solution is to copy the two 'companion' files to each directory
where you have a copy of FOXTOOLS.FLL (including the VFP home directory
if you're running v3.0 and not v3.0b).
I
changed access privileges in the Preference Set, but my users still
have access to the features. What's wrong?
Foxfire!
v6.0 now uses User Accounts to establish security level. See the
section "User Security and Permissions" in the Foxfire! online documentation
Foxfire! looks fine on my machine, but on my client's machine
some of the dialogs have fonts all scrunched up. What's wrong?
This
usually indicates that either the Andale Mono and/or FoxFont font
have not been installed on the client machine. Use the Windows Control
Panel->Fonts applet to ensure that these fonts are available
at runtime. If not, install these fonts (they are located in the
Foxfire! FONTS subdirectory). You may need to exit and restart FoxPro
and/or Windows to ensure that the font is visible.
I
created a Preference Set with the Setup Wizard. Now I've added a
new table to my system. How can I tell Foxfire! about the
new table and get it into the existing Preference Set?
Start
Foxfire! and switch to the appropriate Preference Set, then
pull down the Tools menu and choose "System Administrator".
The "Import Data Items from File" tool will create new Data Items
in the current Preference Set for all the fields (or just some selected
fields) in your new table. If you add new fields to a table that
Foxfire! already knows about, you can use the same utility
program to create new Data Items for just those fields which have
been added
Is
there a way to specify that a report should be landscape regardless
of the printer being used?
In
VFP, yes. I'm assuming you're dealing with a custom layout (FRX)
here. Set it up the way you want it via MODI REPO, then save it.
Now USE from the command window. The first record is the header
record (for the Windows platform records).1) MODI MEMO EXPR and
look for a line reading "ORIENTATION=" (1=Landscape, 0=Portrait).
Erase all the other lines in the memo and save it. This will force
landscape on whatever printer is in use at the other end.2) MODI
MEMO COMMENT and add this string without the quotes:"#DO NOT REPLACE
PRINTER ATTRIBUTES INFORMATION"Note: the text in this string is
correct. The help file and "explain directives" dialog had an *incorrect*
version of this text. The correct text for the other directive is:"#DO
NOT REPLACE PRINTER DESTINATION INFORMATION"When FF sees the #DO
NOT..., it bypasses the usual behavior of forcing the printer attributes
based on what the client has installed. Essentially, this means
that you're assuming some of the responsibility for printer/output
management. Testtut on some sample systems, and take a look at allthe
other stuff that VFP puts into the EXPR memo.
I
want to report on two different sets of data which are stored in
different locations but contain the same exact tables and table
structures. When I switch from set A to set B and run a Request,
I'm still getting results from the tables in set A. How can I get
the results from set B instead?
By
default, Foxfire! leaves tables open after you have
queried them (for performance reasons). This means that if you have
a table ABC in one directory and you query it, then it will be left
open. Any subsequent queries mentioning table ABC will simply use
the already-open table, even if you've changed Preference Sets and/or
paths. So when you switch to another Preference Set and run a Request,
you'll still see the ABC data from the original table. If the original
table has been closed before the second query is run, then FoxPro
will search for and open the correct copy of the table.There are
two ways to make sure the tables get closed. One is to write code
in the "GLOBAL SETUP" phase of FFCONFIG.PRG (which is called immediately
following a Preference Set change) to explicitly close any of your
application's tables which might be open. This has the least impact
on performance (happens only on first loading a Preference Set),
but can involve "hard-coding" table names.The other is to UNcheck
the "Don't Close User DBFs before Execg Requests" checkbox in the
Preference Set Editor "Misc" window. This means that after EACH
Request is run, Foxfire! closes all the non-Foxfire!
tables. This works well, but it can be slow, especially if you have
many large tables to open for each Request.Specifically, in your
case, you'll need to go to the Preference Set Editor and make sure
the "Replace user's search path" radiobutton is selected, *NOT*
the "Add to user's search path" one. This way, when you switch Preference
Sets, the path is properly reset so that the old data directory
is no longer first on the path. Then go to the Preference Set Editor
"Misc" window and look for the "Don't Close User DBFs before Executing
Requests" checkbox -it should be unchecked. Repeat these steps for
each affected Preference Set.
When
I go to add a new filter to a Request, the list of available data
items has a bunch of "garbage" entries at the top, and some of my
Data Items that should be there are missing. Is this a bug?
Yes,
it's a bug - in FoxPro. This problem results from an intermittent
bug in FoxPro's COPY TO ARRAY command which we have not been able
to reproduce consistently. If you're using Foxfire!
v3.0, you may want to apply the fix or the workaround documented
below. If you're using Foxfire! v3.0+, the fix has
already been made, so you shouldn't see this problem.As a performance
enhancer, after Foxfire! loops through the Data Items
table to build the various arrays of available Data Items, we cache
those arrays in the Preference Set record (field PF_CACHE). Because
of the FoxPro bug, in some cases these arrays become corrupted.FIX:
1. From the command window, open the Preference Set table (FFPREFER.DBF
by default), then issue the command REPLACE ALL PF_CACHE WITH ""
My
Data Item's expression includes a UDF. The UDF works fine from the
command window, but when it runs inside a query, it breaks or returns
bad values? Are there special considerations for running inside
a query?
In
writing a UDF that's going to be called as part of the columns clause
in a SQL SELECT, there are a few points to take care about. One
is that any changes to work areas, indexes, or record pointers made
during the execution of the UDF must be reversed prior to returning
control to the select. Another is that you must pass any key values
as explicit parameters into the UDF -- the expression is MYUDF(Customer.Cust_ID)
-- if you don't pass it in and try to reference the cust_id field
inside the UDF, you may not get the record you're expecting.When
the query is executed, the UDF gets fired TWICE on the first row,
once to figure out the type/size of the return value, then once
to get a real value. This may affect the logic of your UDF (i.e.,
if you were logging/counting each call, it'd be one off). It also
means that your UDF should always return the same data type at a
fixed length -- use PADR() to ensure this. Otherwise, the column
gets dimensioned to whatever length the first return value has,
which may not de enough for other rows.If you put a UDF in a SQL
SELECT, there's an initial "scouting" call to it as the query processor
tries to determine the type/size of the result column. This means
that if your UDF is keeping a count, for instance, it'll be one
higher than the actual number of rows processed. UDFs designed to
run inside SQL queries need to accomodate this. The code below (posted
by Pavel Celba on a CompuServe forum) is the slickest way we've
seen to do this.It exploits the fact that all of the "trimming"
functions are lobotomized in "scouting" mode (as during index tag
expression evaluation), so they don't actually trim anything.SELECT
myudf() FROM ....procedure myudfIF LEN(SPACE(2)) = LEN(TRIM(SPACE(2)))*
trim was ignored, must be in scouting callRETURN 0000000.00 &&
or whatever column should look likeELSE* trim worked, so not in
scouting* .....real work goes here....RETURN whateverENDIFRETURN
|