Wiki Home

Open Questions


Namespace: VFP
A place for questions to the FoxWiki community. If you have an answer/opinion, please weigh in below. In time, each question finds a home in an existing topic, or its own topic. (N.B. If you move a question, please leave a link to the new location. Alternatively, if you know of some existing content in the wiki which addresses the question, leave a link.) You may find other questions by searching the Category Open Questions.
New questions at the top please.

Weird external key "anomaly" 11-05-2012 (VFP9; W7P-64bit)

I discovered a particular cdx file shows 0 bytes when opened. Every now and then when closing it stays 0 bytes and the index is "corrupted". The 0-byte is caused by a foreign-key tag, when you call a reindex in the code. So I moved the index to a separate idx, to be created with AfterOpenTable. After doing this I got the error "record out of range" after the execution of the code. No amount of manipulation of dbf's would correct this. The only way it would work is with a "retry" so the resulting code looks like this (the ext1 table is opened with BeforeOpenTable):

PROCEDURE dbc_AfterOpenTable(cTableName)
IF Lower(ctablename)="sample"
SELECT sample
SET RELATION TO key1 INTO ext1 IN sample
INDEX ON LEFT(LOWER(ext1.desc),30) TO desc
GO TOP IN ext1
SET ORDER TO main
ON ERROR RETRY
GO TOP
ON ERROR
ENDIF
ENDPROC

Not very elegant all together, so perhaps someone has a better suggestion. Needless to say the desc.idx file shows 0 bytes when open.

victor50

(PS It would be nice to have some RSS feed on this Wiki.) Resolved: found the feed at the bottom.
We're having a weird problem with an index corruption. We run a largish VFP 9 system at a bank (a registry system) with about 700+ users (not all in the same database) and about once or twice a week, the following occurs:
A user keys a new investor and enters the postal address. The address is stored in a table called ADDRESS.
After hitting the Save button, the address is not visible. Even if they close the screen and open it again. No one can view it via the interface.

Now, behind the scene, we start a session of Fox:
Open the ADDRESS table and GO BOTTOM
BROWSE and the record is visible.
Set the order to the primary key (in this case ADDRESSID) and seek for the ID value. You end up with "No Find".

So it appears to exist, but it's not in the index?

The current work around is:
Open the ADDRESS table (leave it in natural order) and GO BOTTOM.
Highlight the ADDRESSID value and cut it to the clip board.
To refresh the index, move up to the next record, then back down.
Highlight the ADDRESSID column and paste back the value. Move the record pointer and the index is fixed.

The ADDRESS table is fairly simple. The ADDRESSID column does not have a default value, this comes from the investor record (it generates an addressid value) and is 6 characters in size. There is only one index tag and this is on ADDRESSID.

This also happened under VFP 7. Any ideas?

You need to delete and recreate the index (reindexing doesn't always work)
That's been tried and we still get the problem.
If you can find code that accomplishes the same as your manual copy-skip-and-paste then you can incorporate that into the save routine until the source of index corruption is found or fixed (bad disk sector, broken network connection etc). If you SCATTER the offending row, skip -1, skip + 1 and GATHER it does that fix the index?
Thanks for the idea Stuart. Due to its quirky nature, its difficult to set up a test case to prove that it works (sometimes we might not see the problem for a week or two, then wham, we get 2 cases in one day!). With legislation changes such as SOX, its sometimes difficult to provide the users with a quick fix.
Sounds like there is some write caching happening on the server. -- Craig Berntson
We thought that as well Craig. But it only happens to one table out of 270+. And as we have multiple databases (one database per client), it can happen to any of those databases.
Are you using local views? It probably can happen either way but just curious. We had similar occurrences that only seemed to affect certain largish tables from time to time. What we found was that a user would get a message of some type like "Error writing to file" but because our errorlog was on the network it was not always written out. (and you know how users are about reporting messages, it ain't gonna happen) So, I would not rule out caching and/or intermittent network issues causing the problem. The longer a VFP table stays open across the network the more likely an interruption, even brief, but just at the right time can cause index corruption. You gotta have a clean, persistent connection at all times.
See CDXCorruption Checklist -- Randy Jean

We have a large DOS FP 2.5 app in which the index process "hangs" (sometimes indefinitely) until the user presses a key (spacebar or Enter). Then it proceeds until the next endless pause. The index process deletes all of the indexes for each table and recreates them in code. This seems to happen only on tables with large numbers of index tags. Is the answer in the memory settings in config.fp? Is it something in config.nt? Could Tame be an issue? Any help would be much appreciated! Thanks--HenryMurphy

Just a guess, but is it possible that some earlier programmer added a WAIT command to the code, perhaps for debugging purposes? The behaviour you described would be consistent with that. Mike Lewis

All of a sudden I am getting errors that a constant defined in an include file cannot be found (error 12). This is occuring on my computer, only. Other computers on the network run the program without error. I am set up as a developer and run a different configuration file than the others. However, I tried running with the standard user config.fpw file and still got the errors.
I am stumped. - HowardShachter
Suddenly REQUERY() in my VFP v8.0 does not work on my single table remote views when I modify data. The view does not refresh and the return value is -1 (which is not documented). Yet, updates to the SQL Server table do occur. Closing and then opening the view results in the new data showing up. If I make changes to the SQL data elsewhere, the view will REQUERY() and the function returns the expected 1.

The other and probable contributing factor is that, in view designer, there is a cross join entry for the one remote table to nothing. I can delete the join and save but when I open the view designer again, it still shows the phantom join. This is happening globally on all single table remote views. Around the time this behavior began, I had written a routine that scans a database opened as a table for the remote views with DBGETPROP() and assigns view properties programmatically with DBSETPROP() to force consistent settings. What went wrong? - Steven Blake

Spent several days of searching for an answer before I resorted to writing the above request. About an hour after posting, I finally found the unintended consequence from setting Fetch As Needed via DBSETPROP(). - Steven Blake
Does anyone know why IntelliSense will prompt for table fields while in the Command window but will NOT work while in a .prg?
Also if I define a local class, IntelliSense will NOT work in the Command Window but will work in a .prg? The two actions are opposite of eachother.

Thanks,
Mike Mohr

The command window and debugger works with existing objects. Using the m dot (m.) brings up a list of variables currently defined. An existing object displays it's properties and methods. An open table, displays it's fields.
The edit windows (programs and methods) work on what is defined in that window and in its PROCEDURE/FUNCTION definition. This helps limit the lists. ZLOC can be used to bring up variables defined with PUBLIC and LOCAL commands. PRIVATE declarations can be added to this. ZDEF pulls in the #DEFINEs in the procedure and those defined in the #INCLUDE file.

I have code that will add an IntelliSense script, to a workstation to handle the Table and Field listings. IntelliSenseCustomScripts_TableFieldList - Tracy Pearson

Does anyone know how to add a thermometer or motion to a screen to start when a query is sent to a DCOM and stop when the results are returned.

Thanks from a newby.
Is anyone aware of a way to produce curved text with VFP? I'm going to be printing labels (on a Datamax thermal transfer printer) with information out of my database, and it would be ideal if I could find a control or somesuch that would do this from within VFP7.

I'm fearing that I may have to use automation with an outside labeling app. I would assume that those sort of apps are written in VC++ or VB or something like that while I know nothing but VFP.

Any ideas?

-- ScottMinar

Um, you want to PRINT the curved text, or display it? Displaying it you can do with the Windows API, I believe. As for PRINTing curved text... -- Peter Crabtree

Anything you can do with Windows API to display text, you can do through the same GDI to the printer... but then your whole report has to go through that GDI. If someone figures out the proper API's to do curved text, I'd add it into Win Print... - ?wgcs
Way back when, I did some OLE stuff which worked with WordArt and some Employee Images, the results pulled into General Field Types. It was a little clunky, but it worked.

I took one pass through the database, generating the WordArt objects with the employee names. The photos were already avail. Constructed the label and printed.

John Cappelletti
Has anyone had a problem with an updateable view not updating the base table and not raising an error? I have an updateable view inside a transaction and the TABLEUPDATE() for both the view and the table return no errors. Other tables in the transaction are updated.

Donald Mann

TABLEUPDATE() doesn't return an error. It returns .T. or .F. Also you can update a table, but if that's nested in a transaction, and the transaction's not COMMITted, then you'll see no changes-- Steven Black


**--** Steve

I know that TABLEUPDATE only returns a logical value. The problem seems to be that when adding a new record, the updateable view is NOT updating the base table and that the TABLEUPDATE for both the view and the base table are returning true. So after an END TRANSACTION is issued, various other tables have been updated, but there is no new record in the base table

Are you sure Send SQL Updates is .T. in the view? -- Bob Archer

If you update a view to a buffered table, TABLEUPDATE returns .T., but the table may be dumped. Make sure the table isn't buffered that the view is trying to update. Todd Haehn
I have several different 8.5" x 3.5" reports(vouchers), and I have the name of the reports stored in a table. I would like to append them under each other on an 8.5" x 11" papersize (which eventually will be perforatted and ripped at the 3.5" mark). However, since each report form has a different name, I must call the "report form X next 1", which seems to insert a pagebreak. Is it possible to have multiple small reports print on one larger paper size? Any suggestions will be greatly appreciated.

NOPAGEEJECT - Specifies that Visual FoxPro does not force a page eject at the end of a report. In other words, printing does not continue on a new page at the end of printing a report. - VFP8 help.

So get vfp8. or mess around with printing to a file and hacking the resulting file...

Can XML be used to post content to the WIKI? I've been looking around - it's either not available or buried pretty deep and I don't know how to find it. I want to update our code documentor to post the documentation to our Wiki as it is regenerated.

If it can be done can you post a code snippet to save on the brain-strain (or point me to an existing Wiki document)?

--->The Kid<---
No. The simple reason for this is I want to avoid high-volume low-content error-prone posting into this human-readable area.-- Steven Black
I am wondering if anyone has figured out an easy way to grab the Info in the document view window. I wanted to grab it and paste it to the beginning of a prg class definition as further documentation, but can't figure out how to do so. cs See the new entry AProc Info for an IntelliSense script to do this -- Ted Roche
I am looking for information concerning VFP's behavior when table/cursor sizes approach/exceed the 2GB limit. The VFP help doesn't appear to contain anything about this; I haven't been able to discover anything in the MS Knowledge Base labyrinth either. I've likewise had no success searching here or on UT (but perhaps I'm not asking the right question...;-)

I would appreciate any information or pointers to information that anyone might be able to provide on this subject. Our testing is in progress; our sole results thus far: VFP hangs when attempting an APPEND that would break the size limit. Other test results pending. FWIW: VFP7 is the platform.

Thanks in advance for any help you may provide! - Fred Noltie

Have had a similar experience of VFP6 hanging when writing to a text file with FPUT / FWRITE and reaching the 2GB limit.
The only way I can think of to stop VFP hanging is to check the physical file size of the table and when it gets close to the 2GB limit, create a new table and add the records in there.
I have used a set of classes in one of my contracts that managed this, as there were a number of tables of just under 2GB that made up one logical table. I think they were created in-house by one of the other developers - so don't know if they are available for download anywhere - Jason Phillips
Report Form MyReport TO Printer Prompt Interesting event combining this command with a Browse Window: If you move the pointer (row marker) down through the displayed rows, then issue the above command, the report only contains row from the current position onwards, even if you issue the GO TOP beforehand.

Fixed by re-using the cursor in another work area and "Report Forming" on that, after completion returning to the original cursor and browse window.

Has anyione else encountered this featurette. Chris Johnson
the REPORT command includes a scope clause that the help says defaults to "ALL", but seems to default to "REST" for you. You could issue: REPORT FORM myReport ALL TO PRINTER PROMPT to be sure it starts at the top. Or REPORT FORM myReport FOR recordId=5 TO PRINTER PROMPT to only have records with "recordID=5" included in the report. More about Scope Clauses - wgcs
-- Within a legacy system coders have used flag files to either stop or start processes. Not the best method to use but "Legacy Code" means there are such things.

The problem stems from a process that checks for this file, if found attempts to erase it, then processes further code. Frequently, the file is not erased, ERASE does not return anything, neither does DELETE FILE.

Is there a function in VFP that returns a file state i.e. In Use, Locked by whoever or will I need to call a WINAPI function to determine this.

Chris Johnson

Chris, check out the FOPEN() function which will return a negative number if the file is not found, or if the file is being used exclusively by another, or if it is used by another, all depending on what arguments you use and the state of the target file. Don't forget to FCLOSE()-- Steven Black

That's one way to do it, but I think FCREATE() is a much better choice. If the file's there, and not open by another user, then it'll return a positive value (and basically delete and recreate the file for you. You can do the same with FOPEN(), but it requires more work. FCREATE() Example:
*There should be some way of exiting that DO WHILE, otherwise you may end up with a Dead Lock / DeadlyEmbrace
LOCAL nFileHandle
nFileHandle = FCREATE("lockfile.lck")
IF nFileHandle == -1
  IF llKeepTrying
    DO WHILE nFileHandle == 1
      nFileHandle = FCREATE("lockfile.lck")
    ENDDO
  ELSE
    RETURN .F.
  ENDIF
ENDIF
DoProcedure()
FCLOSE(nFileHandle)


-- Peter Crabtree
I have a grid which allows the user to dblclick on the header and change the sort order. When the order changes, I keep the 'selected' row highlighted. Anyone know how to show multiple rows after the change. They keep disappearing at the top end of the grid. I'd like the selected to be in the center if the rowcount allows. Ideas?

[2000.12.08] you can use the grid's RelativeRow before and after setting the order of the table and use the DoScroll() method to get the row back where you want it. You need to goto recno() to get the table "move" to the same record in the new order. -- df
What is a good way to pass cursors between datasessions?
( Clipped )
You've read me exactly right: I am arguing (internally) whether a BO should or shouldn't have a private DS. Let's continue this topic in Business Object Architectures ...
I'm having a problem understanding how to use updateable views with a grid. I have an items table (~15000 records), with a field for a foreign key to a drawings table (~9000 records) (each item is tied to one drawing). The grid is bound to a view composed of the items table and several others; I need one column of the grid to hold a Text Box for the drawing number (a field in the drawings table). A Combo Box would work great if it would be efficient for that many items, though the drop-down really wouldn't be used. Is there a way to effectively assign a RowSource and type to a textbox?
I've tried to subclass a textbox and write methods for what I need; I should be able to use the ValidEvent to update the cursor, but I can't figure out how to update the display when the grid gets requery'd.
My problem might lie in how I'm updating the grid, but everything I've tried seems to make the view want to change the drawings.drawingnumber, rather than the items.drawingskey.
-- ScottMinar
I have been trying to do this for about 2 years. I have come up with 4-5 solutions (2 from other people), and not been satified. Ill post a spec, and perhaps a concerted effort will do some good. -- ?CFK
We use (local) views that can be based on several other (local) views, mainly to pick up descriptions from 'lookup tables'. Due to problems with the View Designer we have to build our 'final' view in several steps. All tables (and views therefore) have surrogate primary keys. When we save an (editable) view with TABLEUPDATE and then REQUERY view, the information does seem to get saved to the table, but the descriptions of the changed lookup items does not seem to get refreshed. When doing separate REQUERY's on the underlying views, we seem to get what we want, but that's not what I would like to do!?!

Any ideas??

RobWillemsen

Rob - What you discovered is normal behavior for views of views. The best solution would be to build a single view. The view designer is very limited, as you discovered. But you may create your views in code, or use a free utility, like e View, or buy a product that will do the job for you (www.xCase.com). José Constant

Hmm... or you can download the VFP 8 beta ( PublicBeta8 ) and use it to edit your views, until VFP 8 is finalized :) -- Peter Crabtree
Recently, we started to experience random file corruption on some sites.
Specifically, "record out of range", but also "Index does not match table" in some instances. Resolved by adding and deleting a record,then PACK (since PACK does nothing if there are no deleted records).
Now, my understanding is that VFP now automatically corrects the header when it is beyond the end of the file, but I have reason to believe the problem arises from a short record being added to the file, and that if VFP does attempt to correct the problem, the correction does not work for all cases. My guess is that it reduces the header record count but fails to check the actual length of the file and adjust it as necessary.
- GeoffPhillips
Geoff, those two errors are not telling about the dbf file. They are telling you that something is wrong with one of the index files (whichever one is currently in control>. The errors are saying that there is a reference in the index that does not exist in the dbf file (probably as a result of an append that failed to update the dbf). Your PACK fixes it because PACK also recreates the indexes. Reindexing the table will probably fix the problem for you as well and with less effort and time.
-- Jim BoothOffsite link to http://www.jamesbooth.com

For two days, I went through an endless cycle of reindexing, or recreating the indexes from scratch, and crashing. At that point I picked up on a current thread on the UT, which reported a somewhat similar problem. And then the problem was resolved in a few seconds flat. I accept and understand what you have said, but I believe the problem originated and persisted from the .dbf. Hence my comments.
I have had a few other instances where simply reindexing solved a problem.
-- Geoff Phillips
And the resolution was... ?
Resolved as above by adding and deleting a record, then PACK (there were no deleted records). Question really is, I guess, whether VFP actually does attempt to fix the header pointer, and could it be refined a little to check and correct the actual length of the .dbf. Next chance, I will save a corrupt file and test my theory as to what happens. -- GeoffPhillips
I need to have variables available in the LOAD of a form. I know that when parameters are passed they are picked up in the INIT. I have come up with a work around but feel its a bit messy. My particular application opens a parameterized view in the LOAD (I'm not using the dataenvironment) and I would like to have the variable passed into the form. Any help or explanation for why the LOAD was not chosen as the place for the parameters would be appreciated. - John Burke

John, the only reason that seems plausible is that the INIT exists on all objects, but LOAD is only on Forms. Therefore, for consistency, the INIT of any object is used to capture parameters. Just my opinion... -- Chuck Urwiler

If you don't actually need the data before the INIT event, you can USE the view with the NODATA keyword (so any controls CONTROLSOURCEd to the view fields won't fail) and then requery at INIT time. Otherwise, I think your only recourse is to use PUBLIC variables (or properties of an PUBLIC object). -- Zahid Ali
Recent Data Environment question and answer moved to Data Environment Classes
Has anyone found a grid that works with record-level validation? I'm in the middle of coding something with very basic functionality to replace grid as grid doesn't have a proper beforerowcolchange. By proper, I mean one that has a row parm. After all, if the row is going to change, I'd like to know.

If all you need to know is if a column has changed in the AfterRowColChange() event, simply capture the nColIndex parm in the BeforeRowColChange() event and compare it to the nColIndex in the AfterRowColChange() event. If you also need to check for row changes capture Active Row in the pre-hook and compare it in the post-hook.

-- Michael GEmmons

The above solution tells you if the row HAS changed ... in order to use it, you have to defer your validation code until the AfterRowColChange() event has fired. For validation purposes, it would be nice if there were a way to know if the row IS ABOUT TO change. I think that's what Gene is asking. -- Zahid Ali

Ah, I see. Validation is needed only when the row changes, not when the column changes. VFP grids can be a pain for this sort of thing. They are the most problematical of all VFP controls. My approach to VFP grids when dealing with data validation is to use table buffered data only. There are several cases when using grids in which the record pointer will move unexpectedly and invisibly. So, unless you have your data table buffered you'll be commiting changes without knowing it.

Grids in all development platforms are a complete pain in the arse. -- Alan Bourke

I've always thought the BeforeRowColChange() event was poorly implemented since the event fires before the row or the column changes, but the developer can only determine if the column has changed. Even the help file is misleading in this respect. Under the BeforeRowColChange Event help topic it says the the nColIndex parameter, "Returns the index of the newly selected row or column." In fact, it only returns the index of the column, not the row. -- Michael GEmmons

See Visual Foxpro 7 Features. The VFP grid now has a RowColChange property that you can check from inside BeforeRowColChange. From VFP9 help:

"The value of RowColChange is 0 at opening and after refresh of a grid. You can query this property in AfterRowColChange and BeforeRowColChange events to determine the type of change that triggered the event..." -- Randy Jean


Has anyone any experience with the Visual Studio Analyizer tool? It does not seem to support VFP (probably due to issues in COM event raising). If someone has mananged to use it with VFP (or VB for that matter), I'd be interested in hearing about it. -- ?lc

I asked Robert Green about this shortly after VS 6.0 shipped. He said it shouldn't be too hard to do, but didn't elaborate. I don't know how to do it, but apparently it can be done. I'd be interested in finding out what you learn about it. - Craig Berntson

I don't know what your issue is, but I believe VSA required Windows NT Service pack 4 or higher. I don't know if there is an issue with Win 95 or if it even works with it. -- Bob Archer
If someone in the know would explain how VFP does transactions with local tables? Does it lock records in the tables, or does it lock records in the .DBC? Or is there some other semaphore-type thing going on here?

Since data is not kept in the DBC, the locking occurs in the DBF. - Craig Berntson Guess again! Opening a view locks the DBC. I suspect a transaction might too.-- Steven Black

I would add to this that locking occurs in the DBF, the CDX, and the FPT, if they exist. Further, that locking can be modified by the SYS(3052) function (see the KB for an article regarding this). Something about transactions must happen in the DBC as well, since VFP can only transact tables which are part of a DBC - no free tables. Interestingly, if you have a large number of views open and issue BEGIN TRANSACTION, it can take a really long time to complete that command. --ChuckUrwiler

Transactions lock any records that get changed, until a commit, or a rollback. Also, if you add a record, that means you locked record 0 (table header), which means that no one else can add a record until you COMMIT (END TRANSACTION) or ROLLBACK. Keep in mind, FoxPro locking is ... - it doesn't acutally lock the record, it locks a file area of nOffset+2^31 (roughly), so that the data can still be read, but foxpro will try to lock the nOffset+2^31 first. It's not actually *locking* the record, as it can still be read.
General Questions on VFP v Other, Mind and Mind Sets.

Just to kick things off:

Minor Rant with current contract:

I have a need to establish if my development experience (FOCUS 4GL, Fox 2.X VFP 5/6) has been for any purpose.

For example:

New Normalised Database developed using Sybase (Good BIG product). One of the main static tables is Reports?.Master.Table containing a list of accounts, report type and formats. I.e. 12345678 M01 XLS. There are in excess of 300 accounts and 16 report definitions also 17 potential formats. (81600 Records). Is this an acceptable state?

I would have structured this table to have either a string fields containing report types and report formats separated by commas or columns for each report type / format in so doing reducing the table size considerably also making it more maintainable for adding columns or rows.

I fully comprehend and agree with database normalization and with client/server architecture but abuse of both seems to negate the use of either. Is there a way to coerce/lead/drag non-VFP Database ‘Designers’ into thinking the project through before doing their job?

ChrisJohnson

Chris,

I look at these situations as excellent opportunities to shine since you, the Visual FoxPro developer of all people [g], can now clean up what someone before you evidently didn't know how to properly implement in the first place.

So shine on!

Art Bergquist
Can anyone help me as to why I'm getting an error "Record Out Of Range." while saving the record in an application. This error normally occures when no. of records in the table increases. Also its difficult to debugg the program, because the pointer shows the error at "THISFORM.REFRESH" in the VF Debugger Window.

Suns.

This could be happening because the Active cursor, is not the expected cursor in a Control Source of an object. The Active cursor has an EOF() condition. OR The cursor used in a Control Source has an EOF() condition. Do you ZAP a cursor during the refresh of an object? - Tracy Pearson
No, I do not ZAP any cursor during the refresh of an object. The error occurs when user presses the command button "SAVE". This event supposed to generates one record in the "FEEDBACK.DBF" and updates some fields in the "MAIN.DBF". Waiting for your precious help.
Suns.
( Topic last updated: 2012.05.11 04:14:48 AM )