Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Frustration with private dataset not saving
Message
From
19/10/2010 13:56:21
 
 
To
19/10/2010 13:01:40
Al Doman (Online)
M3 Enterprises Inc.
North Vancouver, British Columbia, Canada
General information
Forum:
Visual FoxPro
Category:
Forms & Form designer
Environment versions
Visual FoxPro:
VFP 9 SP1
OS:
Windows 7
Miscellaneous
Thread ID:
01486018
Message ID:
01486169
Views:
68
Al,

Thanks much for the detailed explanation! These behaviors are actually much more complicated than I thought. I stepped through your code and confirmed the results. I was really surprised to see that:

>SELECT AA
>REPLACE AA.cString WITH "VV", BB.cString WITH "WW" IN CC && fails, no rows/EOF() in cursor specified by IN clause
>? "Results 4", AA.cString, BB.cString

fails. It seems like "bad behavior" It seems as if either a) prefixing the column name with the alias or b) using the in clause should force the replacement to occur as long as the intended table or cursor is referenced. I would think that prepending the alias would take precedence, and that the in clause would be used to disambiguate a column that was referenced without the alias. But, it looks like it doesn't work that way.

I originally thought that:

select cc
replace cstring with 'ZZ' in aa && works

would be functionally equivalent to:
select cc
replace aa.cstring with 'ZZ' && would not work

But, it isn't!

BTW, I tried this in VFP 6, didn't try 7,8 or 9. This behavior hasn't changed?



>You can perform a REPLACE on a table that isn't the currently selected table without using the IN clause, if you prefix the columns with the appropriate alias:
>
>* Create a couple of test cursors:
>CREATE CURSOR AA ;
>	( cString C( 2 ) )
>
>CREATE CURSOR BB ;
>	( cString C( 2 ) )
>
>* Add blank rows to each, so neither is at EOF() during subsequent REPLACEs:
>SELECT AA
>APPEND BLANK
>
>SELECT BB
>APPEND BLANK
>
>* REPLACE in AA while BB is selected, without IN clause:
>REPLACE AA.cString WITH "AA"
>
>SELECT AA
>
>* REPLACE in BB while AA is selected, without IN clause:
>REPLACE BB.cString WITH "BB"
>
>? "Results 1", AA.cString, BB.cString
>
>* Now create a third cursor with no rows:
>CREATE CURSOR CC ;
>	( cString C( 2 ) )
>
>SELECT CC
>REPLACE AA.cString WITH "XX", BB.cString WITH "YY"	&& fails, no rows/EOF() in currently selected cursor
>? "Results 2", AA.cString, BB.cString
>
>* Use IN clause to "perform" the REPLACE in a work area that is not at EOF():
>REPLACE AA.cString WITH "XX", BB.cString WITH "YY" IN AA
>? "Results 3", AA.cString, BB.cString
>
>* Just to be contrary, use IN with CC while AA is the current alias:
>SELECT AA
>REPLACE AA.cString WITH "VV", BB.cString WITH "WW" IN CC    && fails, no rows/EOF() in cursor specified by IN clause
>? "Results 4", AA.cString, BB.cString
>
>So yes, there are some of the benefits you mention by using the IN clause, especially if you're only REPLACEing in a single table. But it's slightly misleading; what the IN clause actually does is instruct the REPLACE to execute "in" a work area that has a table that (hopefully) is not at EOF().
>
>>My understanding was always that the IN clause was added so that you could perform a replace on a table that wasn't the currently selected table. I have always used it for this purpose, and I always use it in every replace statement. It seems like a good defensive programming technique, and it makes the code self-documenting, and it reduces lines of code, and it eliminates or reduces the possibility of side effects where some other routine changes the currently selected table. No?
>>
>>
>>
>>>If you're using REPLACE instead of UPDATE - SQL, IMO the IN ... clause is mandatory for unexpected/Heisenbug resistance.
>>>
>>>IIRC the behaviour Dragan points out goes back to dBASE III, if not earlier. Since it's possible to purposely design software where the REPLACE doesn't happen if EOF( [currently selected alias] ) is .T., it's officially a "feature", not a bug, and Fox Software perpetuated the behaviour in FoxBASE/FoxPro.
>>>
>>>The introduction of the IN ... clause basically lets users who consider this behaviour a bug, to turn it off.
>>>
>>>>Interesting - I have never needed that clause in the past (that I know of), but will definitely try it!
>>>>>>
>>>>>>PARAMETERS l_check
>>>>>>
>>>>>>* l_check values
>>>>>>* 1 = yes
>>>>>>* 2 = no
>>>>>>SET STEP ON
>>>>>>
>>>>>>thisform.pageframe1.page1.tol_no.Value = 0
>>>>>>thisform.pageframe1.page1.tol_yes.Value = 0
>>>>>>
>>>>>>
>>>>>>IF thisform.isloading AND thisform.isediting then
>>>>>>	l_check = VAL(jcpmt.tolerance)
>>>>>>ELSE
>>>>>>	replace jcpmt.tolerance WITH ALLTRIM(STR(l_check))
>>>>>>ENDIF
>>>>>>	
>>>>>>IF l_check = 1		&&yes
>>>>>>	thisform.pageframe1.page1.tol_yes.Value = 1
>>>>>>ELSE
>>>>>>	thisform.pageframe1.page1.tol_no.Value = 1
>>>>>>ENDIF
>>>>>>
>>>>>>thisform.pageframe1.page1.tol_yes.Refresh
>>>>>>thisform.pageframe1.page1.tol_no.Refresh
>>>>>>
>>>>>>
>>>>>>the replace command sometimes just doesn't update the table....what am I missing here?
>>>>>>
>>>>>>thanks in advance!
>>>>>
>>>>>Let's try with usual suspects first. In case you're sitting on an alias which is at eof(), the replace won't take place... unless
>>>>>
>>>>>
replace jcpmt.tolerance WITH ...whatever... in jcpmt
>>>>>
>>>>>which circumvents that.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform