Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Strange error message: Unknown member column1 in grid (Corrupt SCX file ?)

Status
Not open for further replies.

Jay9988

Programmer
Mar 2, 2023
51
ID
Hi Experts,

I have one form with grid name "grd", and in the "init" procedure/method, i have this code

Code:
WITH thisform.grd
      .column1.enabled=.f.
      .column2.enabled=.f.
      .column3.enabled=.f.
      endwith

The form is functioning properly. There was one time, I edited the form, to add one text box only.
After I compiled all the project, and run the application again, the strange error occurred with message: "Unknown member column1", and pointing to the line I show above. I am sure the column1 is still in the grid. Because I couldn't find the real problem, so I restore from the backup of .scx file, redo the modification again, and the form is running properly. Is is possible that the .scx file is corrupt so VFP misinterpret my form.

How do we know is the .scx file is corrupt? Is there a way to fixed them?

I experienced this on the second time (on the same form again) but with different strange behavior, and still couldn't find the real problem.

Thank you all

 
Most likely you accidentally changed the name of column1 slightly.

Maybe you deleted it, or renamed the grid by accident?

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

There is no place like G28 X0 Y0 Z0
 
My experience with forms is if the scx file becomes corrupted, it will not open at all. So, it is unlikely that you have a corrupted scx if it is opening. What causes the corruption in a scx file I don't know; but I have had VFP (current version with all SPs installed) corrupt a scx or vcx file. Sometimes this happens during a build operation with the build set to recompile all files or by VFP after saving/closing during editing. You can use the debugger to see the grid object, then look at the columns collection and step through it to see each column's name property value.
 
What should be added to Griffs observation is that surely the grid column1 has either been renamed or removed, no matter if by accident or intentionally, by you or not, by code or by manually modifying the grid, but far less likely the column3 is missing by a file corruption. It's just that neither manual modifications nor code using removeobject will amend code that still addresses column1 to either skip it or address it by its new name.

If your intention is to disable all columns use Thisform.Grid.Setall("disabled","column"). If you want to disable the first three columns in visual order that's more difficult, as that's neither given by the names nor by the first 3 elemments of the grid.columns() array. You'd do something like
Code:
For each oCol in thisform.grid.columns
   If oCol.ColumnOrder<4
      oCol.enabled = .f.
   Endif
Endfor

If you want to disable three specific columns for specific fields of the table, then the best advice is that you also disable the move of columns by users, neither by accident or intentioanally, by setting the movable property to .F.

Chriss
 
If you need to get the column order in a grid, then this property will give it:

Code:
toGrid.Columns(lnCol).ColumnOrder

Greg
 
In general, if you are worried that a column might have been accidentally deleted or renamed, just click on the grid in the form designer, then look at the property window. In the drop-down list at the top of the window, drill down into the grid to see the names of the columns contained within the grid (and if required drill down into a individual column to see the control(s) which the column contains).

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
On your more general question about how to detect a corrupt SCX: The typical defect SCX won't open in the designer at all, that's how you detect it.

If code refers to objects that are renamed or removed from the form, the SCX is still healthy, the problem is that modifying controls, their count and/or name does not cause code changes. It would be hard to verify code only refers to existing objects, because sometimes objects are created by code at runtime only and then it's okay code refers to something not present in the SCX, that's also a reason the compiler won't report errors about column1 at build time, only later at runtime you get the error.

Adding a textbox to an unchanged grid should cause a problem, so check for yourself what column names are present in the scx you restored from backup. If there already was no column1 the problem was inherent before you changed the form, it's maybe only running on some circumstance, so it did only come up lately, that's not rarely the case. And users knowing an error of an otherwise already approved as stable version will likely report that wheen a new version is rolled out, as that's always easily explained as a new error. I wish users would be more honest about such things and jut report errors whenever they find them, you can blame a new programmer that didn't cause anything about such already existing errors.

I actually often therefore insist they prove with the older version the error didn't exist before, and if they have to admit they lived with an error for that long, that's a lesson learned, too. It's not that I reject fixing it.

Well, and then I just go back to my advice, amend the code by the intention, you have all the form code as context, I can only guess. But one thing is true about VFP more than C++, Java, C# projects: The compiler of VFP is less strict and sometimes such errors can pass through quality inspections, you should always test for runtime errors, a build with no error isn't a quality insurance.

Chriss
 
Hi All,

Thank you all for your explanation and suggestion.

I've double/triple checked the name of grid and column is still the same actually, and I have no code to alter grid in run-time
But, I will have to check again then.

Since we put aside the possible corrupt of .scx file, probably as @ggreen61 said, the error is happened during building the project and yes, I use recompile all files...
 
Jay9988 said:
I have no code to alter grid in run-time
Well, the easiest way to reconstruct the grid is to make a query that recreates the grid cursor. Are you doing that?

Watch what happens:
Code:
PUBLIC oform1

oform1=NEWOBJECT("form1")
oform1.Show
RETURN

DEFINE CLASS form1 AS form
	Top = 0
	Left = 0
	Height = 278
	Width = 375
	DoCreate = .T.
	Caption = "Form1"
	Name = "Form1"


	ADD OBJECT grid1 AS grid WITH ;
		Height = 200, ;
		Left = 12, ;
		Top = 12, ;
		Width = 320, ;
		Name = "Grid1"


	ADD OBJECT command1 AS commandbutton WITH ;
		Top = 228, ;
		Left = 12, ;
		Height = 27, ;
		Width = 84, ;
		Caption = "click me", ;
		Name = "Command1"


	PROCEDURE Load
		Open Database (_samples+"Northwind\Northwind.dbc")
		Select Top 10 * from Customers where Contacttitle = "Owner" order by customerid into cursor grdCursor
	ENDPROC


	PROCEDURE command1.Click
		Activate Screen
		? 'the grid has',Thisform.grid1.columncount,' columns now, before the query.'
		Select Top 10 * from Customers where Contacttitle <> "Owner" order by customerid into cursor grdCursor
		? 'the grid has',Thisform.grid1.columncount,' columns now, after the query'
	ENDPROC

ENDDEFINE

There's no code that explicitly changes the grid, but querying into a cursor with the same name as the grid is already bound to means that the grid will lose its recordsource as that alias will shortly not exist during the query and it's too late, afterward. The grid lost all its column objects because it lost its recordsource at the moment the query closed the previous cursor to build the new result.

This demo causes grid blanking, that's just the worst form of grid reconstruction without the construction of new columns. In this demo, it only happens when clicking the button, but blanking the grid can also happen at the form start if you think the grid initialization has not yet bound to an alias name, but do your grid data population is too late. You have to be cautious when exactly you query the data for the grid of the form. The demo does at form load, that's before the grid exists. And the demo is programmed very lazy, it relies on the fact that a grid automatically populates with the current workarea, when it has no recordsource already set at form design time.

The usual form should have data ready from the data environment, that will open up tables and do view queries before the form controls are created. If you query grid data at the form init event, for example, to make use of parameters passed in, then this is too late and causes this effect.

So, the question to you is: How does this form populate the grid with data?

Chriss
 
Hi Chriss,

Thank you for your sample coding. In other cases, I've also experienced the behavior the 'blanking' grid when we make (requery) the cursor, and the cursor is already used on the property of controlsource of the grid when the form was designed. To prevent this I put the statement thisform.grid1.controlsource="" to emptying the controlsource before the statement of requering the gridcursor.

Do you think the error I've got ("The unknown column1") is related to this 'blanking' grid ?
Because I think it's quite different, because in the case of 'blanking' grid, at least the form is still running and no error message was generated. But, in my case this time, the form was quitting because error 'The unknown column1")

Many thanks,





 
at least the form is still running and no error message was generated

Well, then do Thisform.grid1.column1.enabled=.f. and you get the error.

Blanking alone doesn't cause an error, but you know the error comes from that code, and that runs, or you also wouldn't encounter that error.

You could now do as Tore, Mike and I suggested in another recent thread and add a breakpoint to your code. Not at a line in some method, but watching over an expression and break when it changes. And that expression could be the grid's columncount.

And then you'd see where the column is lost at runtime.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top