Occassional errors in VFP 9

Posted on 2013-12-16
Medium Priority
Last Modified: 2013-12-26
Hi experts,

I would like just your opinion to this subject... How often do you observe some occassional error in VFP 9? The last example at my side is:
		SELECT tmp58orders
		IF TYPE('stornomark')='U'
			ALTER table tmp58orders ADD stornomark c(1)
		IF TYPE('typemark')='U'
			ALTER table tmp58orders ADD typemark c(1)
		REPLACE stornomark WITH 'S' FOR s__storno
		REPLACE typemark WITH 'M' FOR s__type<2
		REPLACE typemark WITH 'S' FOR s__type=2

Open in new window

tmp58orders is a writable cursor created by SQL SELECT (one output row only) and the error reported was:
1) Variable stornomark does not exist   ...  in the first REPLACE command
2) Variable s__type does not exist  ... in the second and third REPLACE commands
... more missing columns...

This code works in 99.9% of cases but it seems the cursor has totally different structure than I could suppose this time... and the first ALTER TABLE command failed without any error report whereas the second one succeeded...

I have just one explanation: "the fox is drank"...

It is also possible the first ALTER TABLE command crashed resulting in some unexpected data structure, but who knows...

So the only remaining question: How othen does this happen to you?
Question by:pcelba
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
  • 2
LVL 30

Expert Comment

by:Olaf Doschke
ID: 39723106
I never ALTER TABLE with cursors, because of this passage from the help:

ALTER TABLE might not produce consistent results when used with Visual FoxPro cursors created by the CREATE CURSOR command. In particular, you can create a Visual FoxPro cursor with features, such as long field names, that are normally available only with tables that are part of a database container. ALTER TABLE saves a temporary copy of the cursor, so the rules that apply to free tables also apply, and any features requiring database support are lost or changed in an unpredictable manner. Therefore, you should generally avoid using ALTER TABLE with Visual FoxPro cursors unless you have tested and understood the outcome.

This is not about a cursor you created by a query, still ALTER TABLE might better only be applied to tables.

Is s__storno a variable? What about s__type? We know VFP reports a missing variable when a field is missing, as it can't judge from a name expression what it is. Since field names are prioritized over variables, VFP looks for variables last and then reports a missing variable, though a field is meant.

Not sure if ALTER TABLE always has the new table as currently selected alias, your REPLACEs depend on that. I always prefer the syntax with IN alias.

How about using other approaches?
1. Make sure the fields exist:
SELECT ..., ' ' as stornomark, ' ' as typemark ....INTO CURSOR tmp58orders

2. Create the fields separate:
Create Cursor curMarks (recno I, stornomark C(1), typemark C(1))

With the second approach you relate the side cursor to the main cursor tmp58orders without an index by record number.

Sample code:
s__storno =.f.

Create Cursor tmp58orders (orderid I, customerid I)
Insert Into tmp58orders Values (1,10)

Create Cursor curMarks (iRecno I, stornomark C(1), typemark C(1))
Insert into curMarks (iRecno) Select Recno() From tmp58orders
Set Relation To iRecno  Into tmp58orders 

REPLACE stornomark WITH 'S' FOR s__storno IN curMarks
REPLACE typemark WITH 'M' FOR s__type<2 IN curMarks
REPLACE typemark WITH 'S' FOR s__type=2 IN curMarks

Open in new window

That would even work with multiple records in tmp58orders. Of course the relation is not needed for a single record, but if done, you can even populate a grid with records as if there only was a single cursor, you just have to set the grid recordsource to the side cursor curMarks. You can then display tmp58orders fields as well as curMarks fields using the colums controlsources, as the grid scans through curMarks and the relation will move the record pointer in tmp58orders, also a REPLACE IN curMarks could have tmp58orders fields in it's FOR condition, the relation makes sure the right tmp58orders record is checked for the FOR condition.

Bye, Olaf.
LVL 27

Expert Comment

ID: 39723222
Actually since you are creating the table at run time, you can easily have the fields ready from the start. If the table it huge, it will be much faster as well if you create them from the start.
LVL 30

Expert Comment

by:Olaf Doschke
ID: 39723383
I would also prefer generating the fields in the query, much simpler. To make sure you get the right field type and to specify, whether it should be nullable you could also use CAST, of course.

One more thing specifically about the "Variable not found" error: I also experienced this in cases I am sure the field exists, from time to time. And I also had to judge this as "the fox is drunk".

In some cases I found out another alias was active, so the field couldn't be found. Activating a grid does select it's recordsource workarea, for example. But in many cases debugging with the datasession open showed me, that's not always the reason for that error. That seems to be a bug digged too deep to reproduce it.

Bye, Olaf.
TCP/IP Network Protocol Cheat Sheet

TCP/IP is a set of network protocols which is best known for connecting the machines that make up the Internet. The truth is that TCP/IP is one of the oldest network protocols and its survival is mainly based on its simplicity and universality.

LVL 27

Assisted Solution

CaptainCyril earned 200 total points
ID: 39723396
The way I usually do it is: IF TYPE('table.field') <> 'C' and I always do it on Tables and not Cursors.
LVL 30

Expert Comment

by:Olaf Doschke
ID: 39723530
I was rather talking about Select ... CAST(' ' as C(1) NULL) as typemark... to generate the field as wanted, not about detecting the missing field.

Indeed TYPE('table.field') is better to test for the field.

Independent of that, the error also occurred to me in cases the field preexisted in a table for sure and was neither generated by the query or by ALTER TABLE, and even in case of a SQL-Select query with the table in it's FROM clause, not only in REPLACEs.

Bye, Olaf.
LVL 42

Author Comment

ID: 39723660
Thanks for your answers...

... the question was not about the ALTER TABLE on cursors... but about occassional errors in VFP.  :-)

Above ALTER TABLE is just one example (the most recent one) but it can be almost anything. These errors do not happen every time but every week, maybe every day. And the question rather was how often do you observe an error which is not easy to explain?

OK, you've focussed on ALTER TABLE so I'll explain why it is used this way:

The original cursor was produced in VFP COM application on the server then it was stored to a file, zipped and delivered to the client workstation.  Workstation unzips the file creates the cursor and offers it to the client part of the application.

Above topology means the COM app update requires to disconnect all working users... If we need some quick change at the client side then we may decide to update the cursor at the client side which is this case. (The change then stays in the app for ever...)

I know when it should be possible to use ALTER TABLE on the cursor but it seems
SELECT *, newCol1, newCol2 FROM cCursor INTO cCursor would do the job better way probably.

ALTER TABLE in my example works fine all the time and this was the first time it failed. There were no work area change during the command, it even works in Private datasession (just two cursors are open).

I don't follow the "rule" to use IN clause in every possible command. I know it is recommended by several authorities BUT
SELECT workarea  command never failed to me. And the unattended workarea change means program error which is easier to trace without all these IN clauses.

The TYPE("workarea.field") is better than TYPE("field") probably because it avoids possible conflicting memory variables. Our application does not use memory so heavily so the conflict would be visible at the first run.

Also all names used in my example were table fields.
LVL 30

Accepted Solution

Olaf Doschke earned 1800 total points
ID: 39728892
>the unattended workarea change means program error

Well, it's a known bug you shouldn't REPORT FORM while a grid has focus, if you want to report from the current workarea, and that should differ from the grid recordsource. That has less to do with occasional, it's reproducable.

Aside of that, of course a SELECT workarea followed by a REPLACE or a LOCATE works reliable, still the IN clause also documents, what your intention is.

Aside of that, more generally on the topic of occasional errors, I have one error specifically in only app, but that's some flaw in my code for sure. An error handler often reports a broken index in the error log dbf, the real error then is not reported. The interersting part is not that, but the index isn't corrupt. It's seldom enough I didn't changed this, the error reporting also is part of a framework. I will perhaps replace it with my own error handling anyway, soon.

Other things causing regular trouble are: Starting a report preview, maximising it and later closing it after or instead of printing, reactivates the form having started the report, which then also is maximised. And that looks odd for small report starting forms, even if I anchor them. This may also not be a native VFP problem, but a problem of the form handler.

There are some flaws of the debugger, eg non reliable breakpoints and missing the command window while in debug mode. he last problem can be solved by entering _vfp.docmd([SHOW WINDOW 'command']) in the watch window. But this also causes the command window to be unclosable, while the debugger window is active.

I'm sure I could come up with further flaws, but I can't think of other occasionally working and occasionally non working stuff aside of the "variable not found" problem. I think I described the reasoning behind it quite well, and why VFP reports a missing variable, where a field is meant. The VFP internal Name Table contains both variables and fields, so that's another reason besides the naming syntax for an overlap of these two things. Also see http://www.foxpert.com/docs/howfoxproworks.en.htm 

Bye, Olaf.
LVL 42

Author Comment

ID: 39739799
Yeah, we could write another Hacker's Guide to VFP... Debugger seems to be VFP independent product sometimes...  It also reports non-existing events.

I know the Christof's GREAT paper.

BTW, Christof placed Guineu to open source: https://bitbucket.org/cwollenhaupt/guineu 

Thanks for all your contributions!

Featured Post

More Than Just A Video Library

Train for your certification. Learn the latest DevOps tools. Grow your skillset to do better work.

At Linux Academy, we release new training modules every week so you'll always be up to date on the latest tech.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Microsoft Visual FoxPro (short VFP) is a programming language with it’s own IDE and database, ranking somewhat between Access and VB.NET + SQL Server (Express). Product Description: http://msdn.microsoft.com/en-us/vfoxpro/default.aspx (http://msd…
We are witnesses that everyone is saying that our children shouldn't "play" with a technology because it is dangerous. This article is going to prove that they are wrong.
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
Suggested Courses
Course of the Month8 days, 12 hours left to enroll

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question