1. Is foxpro incapable of returning an array from a function by using the return statement
2. Does foxpro have a function that merges 2 arrays
3. How do you pass an array as an argument to a function in a class when the array is a class variable
For example:
define class test as Custom
dimension Arr(1)
procedure asdf(tmpArray, tmpString)
* do stuff
endproc
.. etc etc
How do I call the procedure asdf (from some other procedure in this class) using Arr as an argument
oh, and I almost forgot -> I'm using foxpro 9

[noob questions] Arrays..
Tom Le-Rademacher
But I still don't understand :)
So you mean that it really is impossible to do a call by reference with an array that has the prefix "THIS."
Hmm, I just read something about macro substitution and I think that it might help me.
(btw, thanks to you guys I now have more than enough insight and examples on how to make an alternative solution to my problem )
NormanHH
Well, you answered what I didn't understand
I don't have any experience with VB, but in C++ I do it like this:
class cTest
{
private:
int var1;
public:
cTest(){
this->var1 = 12345;
this->display(&this->var1);
}
void display(int *pInt) {
cout<<*pInt<<endl;
}
};
And in PHP it is almost similar:
class cTest
{
protected $var1;
function cTest() {
$this->var1 = 12345;
$this->display(&$this->var1);
}
function display($var) {
echo $var;
}
}
In the function display I can change the content of the class property var1.
So I assumed that this would also be possible in foxpro with an array but I was wrong
LANDDIS
If you are interested in the "why" (at least as far as someone without access to the VFP sources can say), you might want to check out my article "How FoxPro works internally" on http://www.foxpert.com/docs/howfoxproworks.en.htm.
pablex
It depends on your needs.
Kennibal
Alex has already answered you specifically, but if you tell us what you are trying to do, maybe there is an easier (VFP-specific) way (as Alex said, VFP is a database and has integrated data handling capabilities that make passing arrays around redundant)
peter_heard01
You are right, I saw that it is even possible to use sql statements on cursors!
But now I use an external MySql database from which I retrieve data and send it to an array. My code now looks something like this:
reslt = SQLEXEC(this.gnConnHandle, sqlQuery, "tmpc")
select * from tmpc INTO ARRAY tmpArr
The compiler complains when I want to merge the content of tmpArr to a global class variable called arr:
this.ArrayMerge(@this.Arr, @tmpArr)
But I see now that it is perhaps much easier to merge cursors instead of arrays. (But I'm still curious about how to pass the array as an argument :) )
asdsasdd
Since you insist, here is how you do it it:
******** BEGIN CODE *********
*** Create the source array from a query
SELECT * FROM account WHERE cacref = 'B' INTO ARRAY laSce
*** Create the destination array from a query
SELECT * FROM account WHERE cacref = 'A' INTO ARRAY laDest
"Before Merge"
"Source:", ALEN( laSce, 1 ), ALEN( laSce, 2 )
"Target:", ALEN( laDest, 1 ), ALEN( laDest, 2 )
*** Call the function
ArrayMerge( @laSce, @laDest )
"After Merge"
"Source:", ALEN( laSce, 1 ), ALEN( laSce, 2 )
"Target:", ALEN( laDest, 1 ), ALEN( laDest, 2 )
FUNCTION ArrayMerge( taSource, taDest )
LOCAL lnSRows, lnSCols, lnTRows, lnStart, lnToAdd, lnRow, lnCol
*** How many rows/cols in Source
lnSRows = ALEN( taSource, 1 )
lnSCols = ALEN( taSource, 2 )
*** How Many Rows in Destination
lnTRows = ALEN( taDest, 1 )
*** How many rows to be added
IF lnTRows = 1 AND EMPTY( taDest[1,1] )
*** This is an empty array
lnStart = 0
ELSE
*** We have something already
lnStart = lnTRows
ENDIF
*** Arrays in VFP are 1-based NOT 0 based!!!!
FOR lnCnt = 1 TO lnSRows
*** Add the row
lnRow = lnStart + lnCnt
DIMENSION taDest[ lnRow, lnSCols ]
*** Now populate the columns
FOR lnCol = 1 TO lnSCols
taDest[ lnRow, lnCol] = taSource[ lnCnt, lnCol]
NEXT
NEXT
RETURN
james_h
What don't you understand You cannot do things in VFP as if it were VB - it isn't!
If you would tell us what you want to do, and why, maybe we can help but without some idea of what you want it is hard to guess the answer.
>> So you mean that it really is impossible to do a call by reference with an array that has the prefix "THIS."
Yes. An array with the the prefix "THIS." is a property and you cannot pass a PROPERTY by reference (this has nothing to do with arrays - it applies to ANY property).
By definition a property belongs to the object that defines it. All you can ever do is pass the propety's values or copy the values to something that is NOT bound to the object (i.e. a copy!).
The reason is obvious. If you could pass a property by reference you could not release the original object as long as the reference existed - this would be extremely difficult to manage, and impossible to debug.
RHocking
I spent a lot of time in other programming languages where I used to solve almost all problems using arrays. After the comment from Alex I looked into the cursors... and I found that they are indeed a very powerful alternative to arrays, so perhaps I'll just use cursors instead. One question remains for me however: you say they are in-memory like tables, but is using them not much slower then using arrays
But I still can't figure out how to call the procedure asdf using the class variable Arr. I did know I had to use a call by reference but the problem was that I can't put an @ in front of 'this.Arr' because the compiler will complain.
Like this:
asdf(@this.Arr, "blah blah")
I have a function in my class that merges two multidimensional arrays and i just can't find a way to pass the array as an argument. There must be a way :)
digitallyskilled01
acopy(this.aArray, laSomeArray)
and pass laSomeArray by reference. You might also handle it in your code and if a parameter is not passed use this.aRecs instead.
Don't get into macro substitution much. It's something abused frequently.
kareddy
1) You must pass arrays by Reference not by Value. You do this by prepending a "@" to the array name. ( MyFunction(@MyArray) )
See: http://fox.wikis.com/wc.dll Wiki~PassingArrays
2) Not directly. You and copy arrays ( with ACOPY() ) or insert array elements ( with AINS() ).
See:
http://msdn.microsoft.com/library/default.asp url=/library/en-us/dv_foxhelp9/html/4cfd7044-d4e6-46ee-a6f0-98b5c8d8ffca.asp frame=true
You could make it easier by converting the array to a cursor (or table) and then joining both arrays in the table, then copying to an array.
Check the help for:
APPEND FROM ARRAY
http://msdn.microsoft.com/library/default.asp url=/library/en-us/dv_foxhelp9/html/5b11bd53-12f9-4727-9ae3-f5a7d3d21274.asp frame=true
COPY TO ARRAY
http://msdn.microsoft.com/library/default.asp url=/library/en-us/dv_foxhelp9/html/977adad9-d33e-4f01-8f63-244fd066d832.asp frame=true
and SELECT (SQL) command that can also copy to arrays.
3) By Reference
HTH
Paszt
2) Indirectly with Acopy(),Ains()..
3) Indirectly. First you need to acopy() it to an array and pass that by reference
ie:
[code]
o = CREATEOBJECT('myClass')
LOCAL
laRecs1[1], laRecs2[1]SELECT
* FROM customer WHERE .f. INTO CURSOR crsShow readwriteUSE IN
'customer'laRecs1 = o.GetRecsIntoArray("customer","cust_id between 'B' and 'C'")
APPEND FROM ARRAY
laRecs1BROWSE TITLE
"laRecs1 content"zap
laRecs2 = o.GetRecsIntoArray("customer","cust_id between 'F' and 'G'")
APPEND FROM ARRAY
laRecs2BROWSE TITLE
"laRecs2 content"zap
o.MergeArray(@laRecs1,@laRecs2)
APPEND FROM ARRAY
laRecs1BROWSE TITLE
"Merged content"ZAP
APPEND FROM ARRAY
o.aRecsBROWSE TITLE
"Class aRecs content"USE
Define Class
myClass As SessionDataSession
= 2 Dimension aRecs[1] Procedure GetRecsIntoArray(tcFrom,tcFilter) If Empty(m.tcFilter) Select * From (m.tcFrom) Into Array This.aRecs ElseSelect
* From (m.tcFrom) Where &tcFilter Into Array This.aRecs EndifReturn
@This.aRecs EndprocProcedure
MergeArray(taRecords1, taRecords2) Local lnPosToStartCopylnPosToStartCopy =
Alen(taRecords1)+1 Dimension taRecords1[ALEN(taRecords1,1)+ALEN(taRecords2,1),ALEN(taRecords1,2)] Acopy(taRecords2,taRecords1,1,-1,m.lnPosToStartCopy) ENDPROCEnddefine
[/code]Paras Dhawan
Ah, but that is because the other languages you refer to do not implement a strong containership model. VFP does.
But in the examples you show, the function is part of the same class anyway. In that case you do not NEED to pass anything. All properties defined in a strong containership environment are automatically visible to all member methods. So you can do this:
DEFINE CLASS cTest AS session
var1 = 0
FUNCTION ctest()
This.Var1 = 12345
This.DisplayVar()
This.Var1 && 7890
ENDFUNC
FUNCTION displayvar()
This.Var1 && 12345
This.Var1 = 7890
RETURN
ENDFUNC
ENDDEFINE
Array Properties can be handled directly as well - providing that they are members of the class, or of a parent class (no multiple inheritance in VFP!). For details see "Protecting and Hiding Class Members" in the VFP Help file.