xsharp.eu • scatter / gather FoxPro commands
Page 1 of 1

scatter / gather FoxPro commands

Posted: Wed Jul 01, 2020 11:20 pm
by jpmoschi
Good morning forum,
I continue my task of testing xsharp migrating from foxpro I would like to know the status of the very useful commands scatter and gather.At least the following variants that allow copying the current row from one table to another with the same or similar structure
select SOURCEALIAS
scatter memo to MIAYYAR
or
SCATTER memo MEMVAR
select DESTINATIONALIAS
APPEND BLANK
gather from MIARRAY memo
or
gather memo memvar


In case they do not exist and you need to develop them what would be the best way. Are there similar functions in other dialects?
Thanks
Juan

scatter / gather FoxPro commands

Posted: Thu Jul 02, 2020 9:21 am
by robert
Juan,

SCATTER, GATHER, COPY TO ARRAY and APPEND FROM ARRAY are all on our todo list.

If you want to do something like a scatter/ gather to an from an array for example, your code could look like this (limited error checking in this example, assuming you want all fields, including memos)

Code: Select all

FUNCTION ScatterToArray() AS ARRAY
LOCAL aResult as ARRAY
LOCAL nFld        AS DWORD
LOCAL nMax       as DWORD
nMax := FCOUNT()
aResult := ArrayNew(nMax)
FOR nFld := 1 to nMax
    aResult[nFld] := FieldGet(nFld)
NEXT
RETURN aResult

FUNCTION GatherFromArray(aData as ARRAY) AS LOGIC
LOCAL nFld   AS DWORD
LOCAL nMax  AS DWORD
nMax := Min(ALen(aData), FCOUNT())
FOR nFld := 1 to nMax
    TRY
         FieldPut(nFld, aData[nFld])
    CATCH
          RETURN FALSE   // FieldType error ?
     END TRY
NEXT
RETURN ALen(aData) == nMax   // return FALSE when the array is shorter or longer than FCount()
A Scatter to/from memvars could use the function FieldName() to retrieve the name of each field and then MemVarGet() or MemVarPut() to read/write the memory variables.
To use a like or an Except clause you would have to match the field names with the pattern with the Like() function.

Scatter to Object would create an instance of the Empty class and then call the AddProperty() method on this class to create properties for each field in the cursor.

I think that the SCATTER command could/would call a couple of different functions, depending on the options:
- ScatterToArray() // all fields
- ScatterToArray(fieldNames, fieldNameMask, LikeOrExcept, lMemo, lBlank) // list of fields, mask, memo and blank clause
- ScatterToMemVars()
- ScatterToMemVars(fieldNames, fieldNameMask, LikeOrExcept, lMemo, lBlank)
- ScatterToObject()
- ScatterToObject(fieldNames, fieldNameMask, LikeOrExcept, lMemo, lBlank)

And similar functions would have to be created for Gather
COPY TO ARRAY and APPEND FROM ARRAY would repeatedly call the Array functions for one or more records.


Robert

scatter / gather FoxPro commands

Posted: Thu Jul 02, 2020 8:05 pm
by jpmoschi
To solve it and also learn how to integrate with .Net types:
How can I do the same functions of your example but saving column name and value to make gatherFrom work fine according to the target structure
* returns a dictionary (key, value) with the name and value of each field of the current record in the current workarea
FUNCTION ScatterToDictionary () AS Dictionary <string, object>
* replaces the value of each field that exists in the current row and workarea
FUNCTION GatherFromDictionary (Dictionary <string, object>)

scatter / gather FoxPro commands

Posted: Fri Jul 03, 2020 3:30 am
by robert
Juan,

Yes that would work. I would recommend Dictionary <string, usual>, since the field values are usuals anyway, so you need less conversions.

Robert

scatter / gather FoxPro commands

Posted: Mon Jul 06, 2020 7:57 pm
by jpmoschi
Thanks Robert, my devolution: Tipical VFP scatter /gather MEVAR commands
FUNCTION ScatterTo() AS Dictionary<STRING,USUAL>
oReturn := Dictionary<STRING,USUAL>{}
LOCAL nFld AS DWORD
LOCAL nMax as DWORD
nMax := FCOUNT()
FOR nFld := 1 to nMax
cKey := FieldName(nFld)
cValue:= FieldGet(nFld)
oReturn:Add( cKey, cValue )
NEXT
RETURN oReturn
*****************************************************
FUNCTION GatherFrom(aData AS Dictionary<STRING,USUAL>) AS LOGIC
LOCAL nFld AS DWORD
LOCAL nMax AS DWORD
local actual:= alias()
foreach f as KeyValuePair<STRING,USUAL> in aData
TRY
fieldputalias(actual,f:Key,f:Value)
CATCH e as Exception
d_log ("gather error" + f:key + ":"+ transform(f:Value,""), e:ToString())
RETURN FALSE
END TRY
endfor
return true

scatter / gather FoxPro commands

Posted: Tue Jul 07, 2020 6:57 am
by robert
Juan,

Yes that would work.
I would personally in the Gather also use a loop to loop through the field names and then use a aData:ContainsKey() to check of the dictionary contains the field name.
That has the advantage that the 2 workareas do not have to have the same structure. Extra fields in the source table will not lead to exceptions then.
And you can also log then if there are fields in the target table that are not included in the dictionary.
Robert

scatter / gather FoxPro commands

Posted: Wed Jul 08, 2020 12:07 am
by FoxProMatt
These functions can be used for new dev work, but, can they soon be wrapped with proper SCATTER / GATHER *commands* so that existing VFP code will run?

scatter / gather FoxPro commands

Posted: Wed Jul 08, 2020 5:48 am
by lumberjack
Hi Matt,
FoxProMatt wrote:These functions can be used for new dev work, but, can they soon be wrapped with proper SCATTER / GATHER *commands* so that existing VFP code will run?
I tried to explain the basics in this thread of last year. Should give somebody in the VFP community a hint how to do something like this.
The thread:Click here

scatter / gather FoxPro commands [Issue #387]

Posted: Wed Jul 15, 2020 9:03 pm
by FoxProMatt
BTW - This item is listed as Issue #387 on GitHub:

https://github.com/X-Sharp/XSharpPublic/issues/387

So, It might be more helpful to post any further discussion about this topic in that Issue thread.