Hi,
I m trying to make a general opentable function that I will use with all my apps in the future. Now I need someone to explain to me a few things to see things more clear. Here is my code:
function OPENTABLE(TABLENAME) LOCAL TABLETOOPEN *Ok this is just a full path I make for the dbf file. I do not know if it the right way.what it gives is eg. c:\program files\my app\data\mytable.dbf |
Now when I call the first time for example from a main.prg this function and open a table eg. opentable("mytable") table opens fine! now the strange thing is that if I try to call it again eg. opentable("mytable") with the same table I should actually wait to return me a .f. right Well what I get back is a program error because program has passed the IF !USED(TABLETOOPEN) point of code and went to the USE (TABLETOOPEN) IN 0 SHARED point of code instead of the ELSE statement!
Why is that happening
How exactly is the !USED is working
Is there another more appropriate way I should work with open tables
Thanks for your help!
Athan

Need help on a small open table code
Daraius
I used to program VFP before a few years but after a 2 years pause I m trying to refresh my skills now. Well I used to be an expert in Java (and I say used... because I haven t programmed a line since 2001!). So my background is actually is OO and Java had this toString function that was converting anything to a string. Once I found it usefull and now I m still using it here as well! :)
Thanks for your answer, this was exactly what I needed. I understood what was my mistake!
Now about your code I ve got a question.
Ok you write:
Function OpenTable
Lparameters tcTableName
If !Used(JustStem(m.tcTableName))
Now. this m . What is it Is it an object Where it came from Where is it declared and which is the class Sorry if I m asking "stupid" questions but I m just trying to get into the spirit again.
Thanks Once again for your help.
Athan
evenkots
Athan,
This reply depends on guesses because you hide the most important piece:) No idea what does those ToString(....) return to TableToOpen variable.
used() works with alias names not full or partial dbf names. ie:
use (_samples+'data\employee.dbf')
used('employee') && .T. By default VFP assigns tablename as aliasname.
used('employee.dbf') && .F. - no such aliasname is even acceptable
To me it looks like your TableToOpen variable is assigned a value like:
c:\MyDtaPath\myTableName
used ('c:\MyDtaPath\myTableName') && would always be .F. - no such alias
In other words used() needs pure aliasname.
I understand that you're opening tables from a single directory and thus tablenames are unique. I just noticed you wrote "this gives c:\program files\my app\data\mytable.dbf". Then it was it:)
OK let's touch your function a bit so no matter what you pass it works for dbf files in the same folder:
OpenTable("c:\employee.dbf"), Used('employee'), Dbf('employee')
OpenTable("employee"), Used('employee'), Dbf('employee')
OpenTable("employee.dbf"), Used('employee'), Dbf('employee')
Function OpenTable
Lparameters tcTableName
Local lcAlias, lcFullPath
lcAlias = JustStem(m.tcTableName)
If !Used(m.lcAlias)
lcFullPath = ForcePath(m.lcAlias,GetConfigValue("DBF_PATH"))
USE (m.lcFullPath) In 0 Shared
Else
Return .F. && Why would you need to return a .F.
endif
EndFunc
* Simulate GetConfigValue
Function GetConfigValue && Just simulating and returning hard coded path
Lparameters tcConfigItem
Return _samples+'data'
However notice that no matter what you pass this code opens (try to open) the file from a known location. Returning .F. sounds weird there to me. It should return .F. for a failure to open. Identical shorter version would be:
Function OpenTable
Lparameters tcTableName
If !Used(JustStem(m.tcTableName))
USE (ForcePath(m.tcTableName,GetConfigValue("DBF_PATH"))) ;
In 0 Shared
Else
Return .F. && Why would you need to return a .F.
endif
EndFunc
Or even shorter:
* Main.prg
Set path to (GetConfigValue("DBF_PATH")+set("path"))
Function OpenTable
Lparameters tcTableName
If !Used(JustStem(m.tcTableName))
USE (m.tcTableName) In 0 Shared
Else
Return .F. && Why would you need to return a .F.
endif
EndFunc
eventually making such a function unnecessary. But since you have a function and things might go wrong when opening a table you could enhance it to include error checking and asking the location of the file if somehow it's moved.
Athan,
are you coming from a .Net background Asking that seeing ToString. Those values in VFP and in .Net are already string so no need for a conversion.
You can also use AllTrim() as a shortcut for rtrim(ltrim()). CheckPathsForSlash() I think is doing what built-in AddBs() does (at least since from VFP6).
leugim
Athan
sjc1776
The m. qualifier tells VFP that tcTableName is a memory variable, rather than the name of a field in the current ALIAS(). When/if the current ALIAS() has a field named the same as the name of a variable, VFP always gives precedence to the field.
So it's a good idea to always prefix a memory variable with the m. qualifier, especially in generic code in a library routine, because you never know what fields are in the ALIAS() in the current work area.
Also, since VFP has to check to see if the variable is also a field name in the current work area, your code is faster if you qualify variables with the m. qualifier, as VFP doesn't have to check the current work area.
Drew Speedie
VFP MVP