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

macro substitution for creating file names 2

Status
Not open for further replies.

davisonpro

Programmer
Oct 11, 2010
34
US
I have some very old code that has always used a "double macro" substitution for creating temporary files.

Now, in VFP9, I'm getting very different results from the same code that's been around for ages.

There's a lot of this but most all of it looks like this:
** Establish blank temporary data file
COPY STRUCTURE TO &m0datadr.&m0tmpf1..dbf
USE &m0datadr.&m0tmpf1..dbf ALIAS temp_h EXCLUSIVE
(yes I know this is a rotten way to do it but I've inherited this code and there are more than 1,000 instances like this in a very large, fragile, and poorly documented system)

Now, here are 3 different results I get (there may be more):
1) stand-alone PC (XP and up) - it works fine; substitutes the variable name and creates the file and works
2) on a network file server (Windows and Linux), it creates a file named &m0tmpf1..dbf - literally! That is the name so, it cannot work for a subsequent user
3) in the VFP9 development environment, I get very mixed results regardless of where the data is being housed. Usually, it runs with no problem and does what it always did. But, compiled as an EXE...big problems. Inconsistent.

Anybody seen this before? I'm looking for an environmental solution if there is one. Yes, I will re-write the code but that will take months in this system and we're at crunch-time.
This was most unexpected and unwelcome.

Thanks!
Al
 
In regard to case 2)
IF no variable m0tmpf1 exists, &m0tmpf1. is taken literally, and as it is an allowed file name will be generated. So the outset before running this code must have changed and gone wrong.

Also apaces in the variables will break this code(!)

You also might need to add a final backslash to m0datadr, or files will end up one folder level higher than expected with the intended folder name being start of the file name., eg instead of creating c:\data\table1.dbf you create c:\datatable1.dbf

The only reasoning the OS would have an influence on this kind of macro substitution I can think of is system environment settings influencing how the variables are set. Eg if variables are set using GETENV(), this can vary strongly on OSes, including the problem with spaces, if some system folder has moved to a path including spaces in vista / win7, which hasn't had spaces on XP.

What is the code populating the variables m0datadr and m0tmpf1. Debug their values at runtime and see, if they contain spaces.

I know you can't change many instances of such code in a good and testable and reliable manner, but if you don't like the replace feature of code references take a loo at gofish4, the VFPX refubished version, so to say.

I'd change &m0datadr.&m0tmpf1..dbf to (ADDBS(m0datadr)+m0tmpf1+".dbf"), perhaps aslo adding a check for the variables existing, being of type char and not being empty or null.

Bye, Olaf.
 
Al,

If you've really got more than 1,000 instances of this code, and you decide to change them as Olaf suggested, the easiest way to do that will probably be the Replace feature in Code Reference (on the Tools menu).

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Thank you both! Always reliable and helpful are the two of you and it is greatly appreciated.

I have already done some of what Olaf is suggesting - checked carefully to make sure my variable is populated (and spelled correctly) - that's part of the puzzle that it creates the desired file name in the desired location in the stand-alone but it just seems like something about file servers interpret the results differently although I know that the file server is not doing any interpretation. BTW: the final "\" is always part of the m0datadr variable so it's never a problem about where it goes.

I'll look into those other suggestions, too. This past 16 months of owning this business and this code has been very challenging to say the least. No changes are ever simple due to the structure of the code and the tables. I have inadvertently broken it so many times but, luckily, only shipped one bad update which was quickly corrected.

Thanks!
Al
 
Hi,

Apart from the good advise of Mike you realy should also take a quick look at Thor and its Replace method.
Basicly with Thor you should be able to replace all those 1000+ instances into a more robust tested procedure with exactly 1 (one) click. Amazing and in your case worthwhile to investigate.
Thor can be found at VFPX.

Best regards,

Jockey(2)
 
When you figure out how to change the code quickly, I vote for changing:

&m0datadr.&m0tmpf1..dbf

to:

forceext(forcepath(m0tmpf1, m0datadr), "dbf")

That assumes that m0tmpf1 is the filestem, and m0datadr is the path you want.

Tamar
 
@Jockey2 - Where are you finding a Replace tool in Thor? I've just spent several hours working my way through what Thor offers (not in response to your comment, but for my own purposes), and I don't remember anything like that. Maybe Code References or GoFish?

Tamar
 
Thanks for the tips!

I discovered another quirky thing with it today - it fails to resolve the variable in the file name portion on the first couple of tries so the user ends up with the variable name as the file name - not good but works for some folks OK.
Then, later in the same code, it finally resolves the name, so it tries to connect to a non-existant file at that point.

Not much code-pounding for me today...I'll try your suggestions soon.

Thanks!
Al
 
fails to resolve the variable"

No, if a variable exists makrosubstitution never fails. The variable simply is not in scope , not declared and set, when you get &m0tmpf1 as a file name. That's the only reason possible for makrosubstition failing. And in this case it doesn't error, as & and dot are valid chars in a file name. They also can't be of wrong type or null or empty, they MUST be undeclared/undefined at that moment, or you'd get a type error or no file name, if they were empty.

In other places in code you would get error "variable not found", but in this case this is still a vaild name portion of the copy structure command.

So find out where the variables m0datadr and m0tmpf1 are declared and how they are set and where they are released either by CLEAR RELEASE or by ending scope.

Bye, Olaf.
 
Tamar,

The replace tool is to be found in GoFish4.

The path in the default menu as made by Thor:
Thor ->Run Tool -> GoFish -> GoFish4 Now click button Options and click tab Replace

And there are also a Thor and a GoFish4 ( separate ) Google discussion groups.

Regards,

Jockey(2)
 
An update of sorts and thanks for all your suggestions!

OK, following the simplest path first, I put in an IF to see if the variable was populated (which should have thrown an error if it didn't exist or had been released or out of scope).
The variable always existed and it was always populated with the correct data. However, the simple testing of it seems to have cured the issue. Can I explain this? Nope. I don't really care at this point because I've got another issue now that this one is behind me but, it should be in another thread.

Thanks!
Al
 
What conditions did you use for your IF? Could it be that your test caused you to simply skip over the file write code?
 
Hey dbMark,

Nope. I just stuck a super-simple IF that says
IF LEN(ALLTRIM(m0tmpf1)) < 1
m0tmpf1 = "0"+ALLTRIM(m0custno)
ENDIF

Old School style.

But, I watch the the temp files that get created through the whole process and it never uses the custno - it always uses the name that was originally assigned. In other words, the IF never evaluates as true. (It had a messagebox in it for a while when I was first testing)
 
Your source code may have been newer than the object code and changing it compiled it. That may have been all.

No matter what exactly, I tried some variations and found creating a file name containing "&variablename" is possible with a wrong variable type, eg numeric:

Code:
var42=42
create table &var42 (iint I)
? "success:",file("&var42.dbf")

But Alltrim would fail on a numeric value. Another valeu "working" this weird way is NULL.

Using macro substitution for a name this way for sure is causing trouble on conditions one may not overview at design time, so going for addbs(pathvariable)+filenamevariable+".dbf" or forceext(forcepath(filenamevariable, pathvariable), "dbf") is the way to go anyway.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top