Newbie looking for CDS record guidance

I'm just starting out with Scripter - and having read the manual and run a couple of the samples I'm still a bit uncertain on how to proceed.

I have a situation whereby I have code that parses a .csv file and populates a ClientDataSet  (or maybe FDMemTable).

There are fields in the CDS that will be populated based on values extracted from the .csv.

So, for example, I might load a number of purchase order transactions from CSV.

I'll need to categorize the type of order based on some criteria - say, Canadian vs U.S. destination, and PO number 2-digit prefix.

Loading the CSV in an adaptable fashion (ie field mapping) is simple. Post-processing the data record-by-record is simple.

What I'm looking for is guidance in how I would supply a record-by-record "post validate" script that an end-user could modify (eg to add a new PO 2-digit prefix to a case statement). That is:

  cds.first;
  while not cds.eof do begin
     Scripter.SomeValidation( pass in cds at current record);
     cds.next;
  end;

I don't mind spending a bunch of time figuring this out - but a head-start would be great!

TIA.

Cheers,
EdB


Hi Ed,

there are a couple of ways to accomplish that, depending on how you want your user to write the script. You can simply define a global property in script named "Dataset" using DefineProp, and in the implementation of the getter of that property, you return the dataset you want (in this case, the cds variable). For example (not exact code, just for reference):

DefineProp(?Dataset',tkClass, __GetScriptDataset, nil, TDataset);

procedure TSomeClass.__GetScriptDataset(AMachine: TatVirtualMachine);
begin
 with AMachine do
ReturnOutputArg(TScriptGPObject(CurrentObject).InBuffer[VarToInteger(GetArrayIndex(0))]);
end;

procedure TSomeClass.__SetScriptInBuffer(AMachine: TatVirtualMachine);
begin
 with AMachine do
    ReturnOutputArg(ObjectToVar(cds));
end;

then your user just write the script as he wants, using "Dataset" variable to get the reference to the cds. From your code you just call:

while not cds.eof do begin
  Scripter.Execute;

and that's it.
Alternatively, you can require your user to write a procedure with specific signature if he wants validation, for example, a procedure named "OnValidation", receiving a dataset. So your user will write this in script:

procedure OnValidation(Dataset: TDataset);
begin
  // Do something
end;

then from Delphi code you call it like this:

while not cds.eof do begin
  Scripter.ExecuteSubRoutine('OnValidation', [cds]);

Thanks Wagner - that should give me a good start..

One thing, I have the Scripter Manual in my install, but there doesn't seem to be an actual help file. I'm having to open the source files and read the comments ...

Is there an actual help file available?

Cheers,
EdB

Hi Ed, no help reference, only the manual indeed.

In the end, I elected to drop D7 support and move on to Seattle.

In my "prepare" I have:
    atScripter1.DefineClassByRTTI(TDataSet,'',[mvpublic,mvpublished],true) ;
    atScripter1.AddComponent(cds1);

In my project "Process" I have:
      cds1.First;
      while not cds1.eof do begin
         atScripter1.ExecuteSubroutine('OnValidation',[cds1]);
        cds1.Next;
      end;

And the script contains:
procedure OnValidation( Dataset: TDataset );
begin
  Dataset.edit;
  DataSet.FieldByName('FromScrST').AsString := GetShipToClass( DataSet.FieldByName('PONo').AsString );
  Dataset.post;
end;

(GetShipToClass is also defined in the script).

WAY easier.

I see you already have a testimonial in the vein of "I wish I'd started using this sooner" - I have to agree: I've been wandering around all week thinking of all the places TMS Scripter would have made my life easier.

Better late than never.

Cheers,
EdB


Hi Ed, thanks for the feedback and the nice words!