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

ADIR Not Seeing All Files in Windows 7 Folder 2

Status
Not open for further replies.

Auguy

Programmer
May 1, 2004
1,206
US
VFP9 SP1. I have an application that has been running on a client’s Windows 7 computer for a year with no problems. I am still using XP for development. Now when the app runs on the client's machine and tries to read a directory using ADIR() it doesn’t see all of the files. Supposedly, nothing has changed on the client’s computer. I build a cursor and insert the file names into the cursor from the array created with ADIR(). I use this cursor as the Row Source for a combo box and it does not have all of the file names from the folder. We're only talking about 30-40 files here and the gTemplateFilePath folder is on the local computer. The code below has worked well for the past year. Has anybody had any problems similar to this? I don't think it is an Admin/Other user issue with who created the files because there is only one user?
Code:
* Find Word template files
Local TemplateCount, FileArray, MaxFileLength, Counter1
TemplateCount = Adir(FileArray, gTemplateFilePath + '*.doc*', '', 1)

* files found
If TemplateCount > 0
	* Maximum length of file name
	MaxFileLength = 0
	
	* Strip '.doc' from file name
	For Counter1 = 1 To TemplateCount
		FileArray(Counter1,1) = Strtran(FileArray(Counter1,1), '.docx')
		FileArray(Counter1,1) = Strtran(FileArray(Counter1,1), '.DOCX')
		FileArray(Counter1,1) = Strtran(FileArray(Counter1,1), '.doc')
		FileArray(Counter1,1) = Strtran(FileArray(Counter1,1), '.DOC')
		MaxFileLength = Max(MaxFileLength, Len(FileArray(Counter1,1)))
	Endfor
	* Sort array
	Asort(FileArray)
	* WordTemplates cursor
	Create Cursor WordTemplates (FileName C(MaxFileLength))
	For Counter1 = 1 To TemplateCount
		Insert Into WordTemplates (FileName) Values (FileArray(Counter1,1))
	Endfor
Endif


Auguy
Sylvania/Toledo Ohio
 
For starters, I'd nuke all that fiddling with extensions and use JustStem() instead.

Is there a pattern to what gets left out?
 
Thanks, I'll make that change. I believe any new file added to the folder is not seen by the app. I did have the client re-boot thinking maybe windows was having a problem

Auguy
Sylvania/Toledo Ohio
 
I would debug this to see what's going on. Your code does not filter out any name, but you still could check if in the end Reccount("WordTemplates") = TemplateCount is true.

Using Juststem will help also to remove other extensions, eg docy, but that's not expected for one thing and doesn't change the count.

What VFP is respecting is the hidden attribute, but I don't assume users actually set files hidden, word does not create hidden doc or docx.

Are you sure users are aware you filter for doc and docx only? Putting in any rtf, html, txt and other formats word also saves obviously does not add to the dir.

And maybe the error rather is you don't get back to your code to redo the WordTemplates once it already exists and is filled. That problem also is easily spotted, if you just set a break point and see if you reenter this code at all.

Bye, Olaf.
 
I would step through the code and check every relevant value on each line. In particular, check the contents of TemplateCount and of the array immediately after the ADIR(). And check the array after the inner loop and the sort. And check the cursor immediately after the INSERT.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
One other point: Is it possible you have another array named FileArray somewhere outside this function? The reason I ask is that you are declaring FileArray as a variable, not as an array. That probably doesn't matter, but if you had a public array with the same name, that would take precedence, and that could conceivably cause the error you are seeing (it's a long short, but I thought I'd mention it).

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Thanks to everyone for the suggestions, time for some more thorough debugging!

Auguy
Sylvania/Toledo Ohio
 
Sorry it took so long to let everyone know how this worked out. I'm embarrassed to say Olaf was right, I had FileArray defined twice as Private. Mike, I also changed the declaration of FileArray to an array. I changed the code to the following and it now works on Windows 7. Still not sure why all of a sudden the old code stopped working, but it's fixed now. Thanks again to everyone.
Code:
Private FileArray(1,5), MaxFileLength, Counter1

* Find Word template files
TemplateCount = Adir(FileArray, gTemplateFilePath + '*.doc*', '', 1)
	
* files found
If TemplateCount > 0
	* Maximum length of file name
	MaxFileLength = 0
		
	* Strip '.doc' from file name
	For Counter1 = 1 To TemplateCount
		FileArray(Counter1,1) = JustStem(FileArray(Counter1,1))
		MaxFileLength = Max(MaxFileLength, Len(FileArray(Counter1,1)))
	Endfor
	* Sort array
	Asort(FileArray)
	* WordTemplates cursor
	Create Cursor WordTemplates (FileName C(MaxFileLength))
	For Counter1 = 1 To TemplateCount
		Insert Into WordTemplates (FileName) Values (FileArray(Counter1,1))
	Endfor
Endif

Auguy
Sylvania/Toledo Ohio
 
Auguy,

it works and that is the good thing. But for my understanding why are you declaring the FileArray private? Should it not be local?

Regards,

Jockey(2)
 
Jockey(2), Thanks, There's a lot of other code I omitted here. I will double check but you are probably correct.

Auguy
Sylvania/Toledo Ohio
 
Problem with PRIVATE is, that it does NOT declare a variable itself:

Code:
PRIVATE paula
? Vartype(paula)
? Type("paula")
? Vartype(pauler)
? Type("pauler")

See? Four Us, both paula and pauler are undeclared variables, even though there is a "PRIVATE paula" statement.

This in itself doies not decalre a variable.

It only ENDS the scope of a variable paula, if one was declared before as private on a higher stack level (eg by the caller) and it also STARTS a new scope for this variable name, but only the name yet, which only comes to life (so to say) if you use this name in an assignment.

There is a very obvious difference between PRIVATE and LOCAL, if you take a look at the help, as PRIVATE also allows such forms of the statement as PRIVATE ALL LIKE p* or PRIVATE ALL EXCEPT goApp.

This is just defining a namespace in a way or hiding whatever was using that namespace up till the PRIVATE statement.

And the scope of this namespace is from the PRIVATE statement up to all methods or functions you call, too, without needing to pass the variable on, unless these functions end the scope by restating to want this variable as their PRIVATE variable again.
But that also does neither release these variables, nor redefine them.

Maybe seeing this in code helps more to understand than just the words:
Code:
RELEASE ALL
PRIVATE pcMyPrivateVariable
pcMyPrivateVariable = "This value was assigned in main code"
? "before function call:", pcMyPrivateVariable
myFunction()
? "after function call:", pcMyPrivateVariable

Function myFunction()
   ? "in function head:", pcMyPrivateVariable
   PRIVATE pcMyPrivateVariable
   * ? "in function, after PRIVATE, but before new assignment", pcMyPrivateVariable

   pcMyPrivateVariable = "This value was assigned in the function"
   ? "in function, after assignment:", pcMyPrivateVariable
Endfunc

In the first place, just look at one aspect: The last output shows the variable still lives with the initially set value.

You actually haven't lost this variable through the inner function and you get back to it. Ater returning from the function, it's inner private scope ends, but the outer one still exists.

Now uncomment the one commented line and you'll also see, that the PRIVATE statement within the function already blends out the variable coming from outside, as if it never was declared.

And so the output directly after PRIVATE fails with the error "Variable not found", even though the outer private scope variable still exists. If you now click to ignore this error and finally go back, "This value was assigned in the function" is output.

If you think of PRIVATE meaning it's privately only belonging to the currently running stack level of code, meaning the current function or method, then you're wrong and LOCAL is what you want. PRIVATE is more like PUBLIC, it only hides your variables from callee, but it makes this available to all further code called until coming back and ending the current code/stack level.


I personally don't use PRIVATE variables at all, I even predeclare arrrays coming from ASOMETHING() functions, eg ADIR(), beforehand as LOCAL typically, to avoid, that they are created private, because I don't want to have variables scope "spill into" any further code.

What I do besides passing on values as parameters to forward them into functions or methods, is setting object properties, or pass on objects, to pass on a set of values, eg objects created by SCATTER NAME or store data into dbf/cursor and share it this way. Well, and of course using classes, to have the scope of an object, THIS, as the container holding together, what belongs together.

This is much easier to maintain and understand than making use of this weird scope "PRIVATE".

Bye, Olaf.






 
correction:

...And so the output directly after PRIVATE fails with the error "Variable not found", even though the outer private scope variable still exists. If you now click to ignore this error and finally go back, "This value was assigned in main code" is output...

So what PRIVATE actually is, is a dividing barrier between the usage of a variable name before itself and after itself. Whatever variables with the name(s) sepcified exist are hidden, stored on some variable stack, poped out again, once that new scope ends. And whatever variables with the names specified you set after the PRIVATE statement then don't overwrite these protected stored variables and instead are a new variable with the same name.

If there is no variable with the name(s) you specify in a PRIVATE statement, this statement is exactly doing nothing at all.

Bye, Olaf.
 
Thanks Olaf, another great explanation!

Auguy
Sylvania/Toledo Ohio
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top