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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Not An Array Error

Status
Not open for further replies.

CDavis

Programmer
May 5, 2000
155
US
This relates to VFP 6.0

I have been experiencing an intermittent error: 'ATBL' is not an array.


The error occurs in a code snippet that in the init event of a listbox object. The purpose of the code is to determine the number of files in the current or default directory with a .dbf extension and then to populate an array (aTbl), which is the RowSource of the listbox, with the name of the file. I've included the code and indicate the line that produces the error. Thanks in advance for your comments and suggestions.

Public Array aFls(1)

ADIR(aFls,"*.dbf") && Populate array with file data

nCounter = 0

For I = 1 to Alen(aFls) Step 5 && Use info only from column 1 of the array
****Next Line Produces Error******
Use aFls(I) In 0 && Open each table
nCounter = nCounter + 1 && determine no. of files.
Next I

Public Array aTbl(1)

Dimension aTbl(nCounter) && dimension aTbl to match number of files.

For I = 1 to nCounter
aTbl(I) = Alias(I) && populate array rows with alias from each work area.
Next I

If ThisForm.Tables.ListCount > 0 && If there is a list --
ThisForm.Tables.ListIndex = 1 && Select the first item in the list
ThisForm.Refresh()
Endif

Select (ThisForm.Tables.Value)



CDavis
 
An objects LOAD event occurs before the INIT. I suspect the array is not defined at this time.

When working with arrays in a form, I usually create a property on the form as an array. To do this, it is simply add a new property (I'll call mine arDbfs), but give it a dimension of 1.

arDbfs[1]

The 2nd thing I normally do is load the array in the Form's LOAD event. This usually takes care an any array conflicts.



Jim Osieczonek
Delta Business Group, LLC
 
What happens if the ADIR that populates aFls doesn't find any DBF files? Your counter will be 0 and your DIMENSION command for aTbl will fail. I don't think this is what's causing the problem you're running now, though.

I'm confused about what the problem is. You say that the error you're getting is that the array aTbl doesn't exist, but the line of code you say is where the error occurs is only using the array aFls. Did you reference the wrong line?

Also, I agree with Jim that it's better to use form properties for the arrays rather than declaring public variables.

One other thing that could get you into trouble is that you're assuming that ADIR will always return a 5 column array. If they change this in a future version of VFP, this code will break. Instead, it's better to do this:
Code:
For I = 1 to Alen(aFls,1)
    Use aFls(I,1) In 0
    nCounter = nCounter + 1  && determine no. of files.
Next I
Note the 1 as the second parameter in the call to the ALEN function. That returns the number of rows in the array, rather than the number of elements. I can then look at the first column for the current row when I reference the array in the USE statement. If they every add more columns to the ADIR command, this code will still work.



-BP
 
Barbara brings up a good point concerning 0 entries in the array as a result of no dbfs matching your specific criteria. I didn't think about that. That supports our belief that the array is best suited for a property on the form. That way, you can initialize the array in advance and avoid an error occurring, even if there are no tables in the directory.





Jim Osieczonek
Delta Business Group, LLC
 
Hi


Public Array aFls(1)
** Add path while populating if not in default directory
ADIR(aFls,"*.dbf") && Populate array with file data

IF VARTYPE(aFls) = "C"
nCounter = ALEN(aFls,1) && total files
Public Array aTbl(nCounter)
aliasCount = 0
FOR I = 1 to nCounter
IF UPPER(aFls(I,1))="FOXUSER"
LOOP
ENDIF
aliasCount = aliasCount+1
SELECT 0
USE aFls(I,1) && Open each table
aTbl(aliascount) = Alias() && populate alias opened
ENDFOR
DIMENSION aTbl(aliasCount) && redimension
ELSE
** No tables
** suitably take action to avoid errors..
ENDIF

** proceed with your other code..(not tested)
If ThisForm.Tables.ListCount > 0 && If there is a list --
ThisForm.Tables.ListIndex = 1 && Select the first item in the list
ThisForm.Refresh()
Endif

Select (ThisForm.Tables.Value)

:)

____________________________________________
ramani - (Subramanian.G) :)
When you ask VFP questions, please add VFP version.
 
Jim, Barbara, & Ramani

Thanks for the suggestions. I'll work on the modifications you suggest. I was aware of the potential for not finding any .dbf files creating an error and planned to deal with that. What confuses me is that the code works sometimes and other times it doesn't. Also Barbara goes to the heart of my confusion when she points out that the error occurs prior to my referencing aTbl. I verified the location by inserting (Wait 'myReference Number' Window) commands prior to each command. I suppose that if the Load event of object is occuring prior to the init event that the reference to aTbl in the RowSource property might be causing the problem. However, that doesn't explain why the error is intermittent.

I'll post my ultimate solution. But if any of you would like to comment further -- I'll appreciate your input.

CDavis
 
I verified the location by inserting (Wait 'myReference Number' Window) commands prior to each command.

For debugging things like this I really prefer to stick a SET STEP ON command in there to get the trace window open. At each line of code you can check the contents of variables and evaluate expressions, as well as see what code is actually running.



-BP
 
What confuses me is that the code works sometimes and other times it doesn't.

Maybe the array is losing it's scope, i.e. public do to another event occuring. I strongly suggest taking it out of a public variabe, which I am not a fan of anyway, to a propery on the form as Barbara and I mentioned. If it this doesn't solve the problem, we can trace why.

For example, does it fail the first time only.

Does it fail after a series of events.

Or as Barbara suggested, can SET STEP ON assist?

Jim Osieczonek
Delta Business Group, LLC
 
Thanks for all the help on this issue. I've not had much time to spend on it today, but I have taken bits and pieces from each of your suggestions. I've created two new form properties: DirList(1) and TableList(1) and modified the code to:

ADIR(ThisForm.DirList,"*.dbf") && Populate array with file data
IF VARTYPE(ThisForm.DirList) = "C"
nCounter = ALEN(ThisForm.DirList,1) && total files
aliasCount = 0
FOR I = 1 to nCounter
IF UPPER(ThisForm.DirList(I,1))="FOXUSER"
LOOP
ENDIF
aliasCount = aliasCount+1
USE ThisForm.DirList(I,1) In 0 && Open each table
DIMENSION ThisForm.TableList(aliasCount)
ThisForm.TableList(aliascount) = Alias()
ENDFOR

ELSE
** No tables
** suitably take action to avoid errors..
ENDIF

If ThisForm.Tables.ListCount > 0 && If there is a list --
ThisForm.Tables.ListIndex = 1 && Select the first item in the list
ThisForm.Refresh()
Endif

Select (ThisForm.Tables.Value)
This.Requery()
ThisForm.Refresh()

*************************************

The code is working well except that when presented with a test directory that has 3 .dbf files the listbox only displays the first one even though each of the files has been opened in a work area. I think that I saw something from a previous post that may touch on the issue but haven't done much research due to other commitments today.

If any of you would like to comment further, I continue to welcome input.

As I say each of you have provided valuable suggestions:

Jim & Barbara for suggesting form properties and Set Step
Ramani for pointing out that I should trap for "Foxuser" and cleaning up the loop structure.

Thanks again -- CDavis
 
I don't see a ThisForm.Tables.Requery() anywhere in the code. You need to call the Requery() method for combos and lists after you make changes to the RowSource to get those changes reflected in the control.



-BP
 
Barbara,
Actually, all of my posted code is in the init event of the .Tables object. I've issued This.Requery() and ThisForm.Refresh() as the last two lines.

Should I issue the requery() in some other location; perhaps the GotFocus? Let me know what you think.

Thanks -- cd.
 
Sorry. I didn't realize that Thisform.Tables was the listbox having the problem.

Hmmm, not really sure. I would make sure that there are three tables listed in Thisform.Dirlist after the ADIR command. Also check This.Listcount right after the Requery().



-BP
 
As promised, I said I would post my ultimate solution. From my last post, I was unable to determine why only 1 item was showing up in the list -- I tested to make sure I was redimensioning the array and tested to make sure that a value was available for populating the array. Consequently, I've taken another approach with the listbox. I changed the RowSource to None and the RowSourceType to 0 (none). It is now a simple matter to use the AddItem Method of the listbox as demonstrated in the following code:

ADIR(ThisForm.DirList,"*.dbf") && Populate array with file data
IF VARTYPE(ThisForm.DirList) = "C"
nCounter = ALEN(ThisForm.DirList,1) && total files
aliasCount = 0
FOR I = 1 to nCounter
IF UPPER(ThisForm.DirList(I,1))="FOXUSER"
LOOP
ENDIF
aliasCount = aliasCount+1
Select 0
USE ThisForm.DirList(I,1) && Open each table
This.AddItem(Alias()) && populate listbox
ENDFOR

If ThisForm.Tables.ListCount > 0 && If there is a list --
This.ListIndex = 1 && Select the first item in the list
ThisForm.Refresh()
Endif

Select (This.Value)

ELSE
This.AddItem("None Found") && or use messagebox etc.
ENDIF


ThisForm.Refresh()



I have a little tweaking to do. Ultimately, I will use this form to show open tables, indexes and fields and be able to index on fields, change index order to ascending/descending; Browse, Reindex, Pack, Open & Close tables etc. Basically this is an update to an old project that was based on the event model.

Anyway, thanks to each of you who took time to offer suggestions. They were a big help as you can see from the latest version of the code.

CDavis
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top