Link to home
Start Free TrialLog in
Avatar of HenryM2
HenryM2

asked on

Delphi Loading Data Into Two Dynamic Arras From a Single Procedure

I have a called lest say, Procedure1, declaring the following two dtynamic arrays:
Var SourceArray, DestArray : array of String;

From Procedure1 I want to call Procedure2 or Function2 where I want to load data into SourceArray or DestArray, by passing the name of the Array to Procedure 2, hence controlling through the passing of the Array's name, into which Array Procedure 2 is to load the data.  How is this done?
Avatar of sas13
sas13
Flag of Russian Federation image

type
  TMyArray = array of String;

var
  SourceArray, DestArray : TMyArray;

// using

proedure Procedure2(const Source: TMyArray; var Dest: TMyArray);
...
SOLUTION
Avatar of aflarin
aflarin

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cyberkiwi
SourceArray and DestArray will need to be visible to Procedure2.
3 options:
Procedure2 will be an internal procedure to Procedure1
SourceArray/DestArray is passed directly to Procedure2
SourceArray, DestArray are declared globally.

Assuming Proc2 is external to Proc1, I would just pass the array by reference.
I don't understand why you would pass the name instead of the array directly?

procedure Proc1(Var SourceArray, DestArray : array of String);
begin
  // do something
  Proc2(SourceArray); // or DestArray
  // do something else
end;

Procedure Proc2(Var anArray: array of String);
begin
  // do something
end;
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Geert is right on what you are looking for.
He is so good at interpreting fuzzy questions ;o)
And if all the others where also using VAR keyword, Geert explained WHY.
He is sooo close to Genius now !

His Test2 procedure is the simplest example of what you need.
If you need more help, you'll have to be more specific about how you actually want to fill your array
I think I have no room to answer question here in delphi zone, I better see some in c#.
>>epasquier
i used to have a manager who gave me an analysis on a 5x5cm piece of paper
like this:
  lbl designer SATO
  + security flow
  oracle db

are you jealous of me being so close to genius ?

 




systan : I admit that the field is a bit overcrowded with regard to the number of questions, but what best way to learn and improve could you imagine other than keep trying and see how others are thinking, interacting, and ultimately finding the best answer possible ? That is team work.

If you go have a look how it is in C# zone, I'll be glad if you one day post a topic in Delphi Zone just to share your feelings about the C# zone : level of askers, of experts, nb of questions/day... And compare with Delphi zone
>>systan
you could do like cyberkiwi ... post in *all* the zones :)
>>epasquier, get back to work
or you'll break my all time record in delphi TA
@Geert : jealous ? not at all ! I only took the opportunity to give you credits for your continuous work. You've been here longer than me, and I have been at some point like an iron ball chained at your feet, getting in your way for easy points. Pretty much the same as aflarin is doing now :o)

I suppose that is the order of things here, some new experts get excited by the challenge, they came here first because they had time, and then reality comes in the way and we have to earn some money at some point, so we calm down and let some room to newcomers.

I'm glad you are almost there to the biggest title a Delphi expert could dream of (really, there is missing one or even 2 ranks between Genius and Savant...That's just impossible to reach 10Mpts in Delphi in a lifetime).

I always knew you would do it before me. If aflarin does not get in my way, I'll try to join you as the fifth (does that not remind you of something?)
>>epasquier, get back to work
or you'll break my all time record in delphi TA

Now, THAT is my intention :o))
>>HenryM2
sorry for cluttering up your post
but sometimes, we just can't help ourselves
There is just no Delphi Chat corner, just a lounge for everything, but no one monitors that

(does that not remind you of something?)
You want me to give a party with lots of beer ?

Yeah, you and lately aflarin are stealing a lot of easy poinx !
Fwiw, you both are only half as competitive as ciuly and ziolko were
They had/have the extra of being cleanup volunteers
I also asked to be cleanup volunteer ... still waiting ...
Hmm... am I too late to join the chat? LoL
chat ? yeah, you'r too late :)


>> you could do like cyberkiwi ... post in *all* the zones :)

Hm.. was that supposed to imply something?  I actually do Delphi for work.

Anyway, I cannot seem to link the question to Geert's solution, notwithstanding epasquier's endorsement thereof.  Maybe I need some beer.
Avatar of HenryM2
HenryM2

ASKER

Sorry got interrupted with another problem, back now.
I think the Array names SourceArra and DestArray cased some confusion and perhaps made my question "Fuzzy" hece the perception that Procedure2 has to handle both Arrays at the same time.

I need only process the information in ONE of the arrays at a time, thus I want to process and load data into SourceArray OR DestArray, depending on which one the calling Procedure need the data loaded into.
Geert, Epasquier;
lol, you guys are  all delphi genius.

Thanks

Back to the problem of HendryM2,

Listening...
And hence my Proc2 only has One array input...
I read it this way - you want to say "SourceArray" in a string as the array name, but in Delphi, you just pass a reference to the array?

procedure Proc1(Var SourceArray, DestArray : array of String);
begin
  // do something
  Proc2(SourceArray); // or DestArray
  // do something else
end;

Procedure Proc2(Var anArray: array of String);
begin
  // do something
end;
HenryM2 ...
That didn't really unfuzzy the fuzziness.

Yes, Geert sorted that already, wouldn't you think ? That's much clearly said though.

Here is a  solution that summarize all the above hints

So, does it works for you or you are needing something else ?
Type
 TStringArray=Array of String;

Procedure DisplayStrings(StrList:TStringArray);
Var
 Str:String;
 i:integer;
begin
 Str:=Format('Array has %d elements',[Length(StrList)]);
 for i:=Low(StrList) to High(StrList) do Str:=Str+#13#10+StrList[i];
 ShowMessage(Str);
end;

procedure LoadStrings(Var StrList:TStringArray;NbItems,Offset:integer);
Var i:integer;
begin
 SetLength(StrList,NbItems);
 for i:=Low(StrList) to High(StrList) do StrList[i]:=IntToStr(i+Offset);
end;

procedure Procedure1;
Var
 A1,A2:TStringArray;
begin
 LoadStrings(A1,5,10);
 LoadStrings(A2,10,100);
 DisplayStrings(A1);
 DisplayStrings(A2);
end;

Open in new window

i guess you want to want to make a decision based on the caller of the procedure ?

if so,
you will need to provide some kind of hanger (handle) to check who's calling ...

like a onClick event attached to Button1 and Button2:

procedure TForm1.OnButtonClick(Sender: TObject);
begin
  if Sender = Button1 then
    Test2(SourceArr)
  else
    Test2(DestArr);
end;

Are you looking for something like this ?

>>epasquier,
sorry if this is taken in a direction which you hadn't thought of yet ...

:)
Avatar of HenryM2

ASKER

Thanks for all contributed so far.  Yes Geert Gruwes this is what I want.  I think a global declaration for SourceArray and DestArray will be better.  Thus Procedure1 has to call Procedure2 and pass a reference to Procedure2(SourceArray) or Procedure2(DestinationArray);
global ?
ouch ... that will start a new discussion ... but while we are at it ...

you should consider the scope of those variables
i think you don't really need global

do you care to clarify a little more what the goal is
you have abstracted a little too much i think

the problem is like a database, you can normalize it completely
but for performance reasons, the last step is somewhat denormalizing it :)
Option 3 then.  We have blast off.  Glad to help.

3 options:
1,Procedure2 will be an internal procedure to Procedure1
2,SourceArray/DestArray is passed directly to Procedure2
3,SourceArray, DestArray are declared globally.

begin
  // do something
  Proc2(SourceArray); // or Proc2(DestArray)
  // do something else
end;
you are somewhat limiting cyberkiwi ...
there are a lot more options, i'm sure of that

consider the path the comments have made this question follow
I am always open to be educated.
Set aside methods like storing a pointer to (pointer to SourceArray) in a component Tag and passing the component reference and extracting the tag and casting to (pointer to array of string).

How would you get Procecure2 visibility of SourceArray?

(1)
Procedure Proc1();
var SourceArray, DestArray: array of string;
var isSource: boolean;
  Procedure Proc2();
  begin
    //if isSource then ... work on SourceArray else DestArray
  end;
begin
  // do something
  isSource := True;
  Proc2();
end;

(2)
Procedure Proc2(var inputArray: array of string);

Procedure Proc1();
var SourceArray, DestArray: array of string;
var isSource: boolean;
begin
  Proc2(SourceArray); // local var to Proc1 passed directly to Proc2
end;

(3)
var SourceArray, DestArray: array of string; // globally

Procedure Proc2(var inputArray: array of string);

procedure Proc1();
begin
  Proc2(SourceArray); // global var passed to Proc2
end;
Avatar of HenryM2

ASKER

I hope the simple code here shows what I am trying to do.  This does not work as the  I suspect the Array Of String in the parameters of Procedure2 is out of place I need to add the Type
 TStringArray=Array of String;
somewhere? But where?  Sorry, I am a little new on the Type thing, is this what they call Type Casting?

The example may also explain why I think a global declaration of the Arrays may be better.  How does the VAR passing the information back effect speed?

procedure TMainFrm.Procedure2(ItemRecordNo :Byte; Var ArrayName : Array Of String);
Begin
  SetLength(ArrayName, 2);

  if ItemRecordNo = 1 then
  ArrayName[1] := 'Come'
  else
  ArrayName[1] := 'Go';
End;

procedure TMainFrm.WriteEquipPropertiesToURS;
Var SourceArray, DestArray : Array Of String;
    RecordNo : LongWord;
Begin
 Procedure2(1, SourceArray);
  Label1.Caption := SourceArray[1]; // Returns 'Come' in SourceArry[1]

  Procedure2(2, DestArray);
  Label2.Caption := DestArray[1]; // Returns 'Go' in DestArray[1]
End;
 
i think filling in the array's is NOT the problem here

it's determining what to fill in based on who's calling

it's the who's calling which is the problem

the declaration of the array's is just scope problem
can you explain without using code ?

is this similar to problem of incoming/outgoing traffic in a factory ?
Avatar of HenryM2

ASKER

Procedure1 has the Arrays declared in it (Or globally if need be)
 Var SourceArray, DestArray : Array Of String;

Then Procedure1 has to call Procedure2 passing it an address of where to fetch the data from and then depending on where that data is from, it must go into SourceArray or DestArray inside Procedure1.

Procedure1 then goes ahead and compares the data in SourceArray with the data in DestArray.
procedure TMainFrm.Procedure2(WhereFrom :Byte; Var ArrayName : Array Of String);
Begin
  SetLength(ArrayName, 2);  // for this to work going back to caller, VAR is needed for proc param

  if <WhereFrom ... test> then
   //Update ArrayName from "where to fetch the data"
  else
   //Update ArrayName from "somewhere else to fetch the data"
End;

procedure TMainFrm.WriteEquipPropertiesToURS;
Var SourceArray, DestArray : Array Of String;
    RecordNo : LongWord;
Begin
 // ..somehow set up SourceArray
 // ..somehow set up DestArray

 if <.. some condition ..> then
   Procedure2(<fetch loc 1>, SourceArray)
 else
   Procedure2(<fetch loc 2>, DestArray);

 // compares the data in SourceArray with the data in DestArray.
End;
 
Avatar of HenryM2

ASKER

The problem with:
procedure TMainFrm.Procedure2(WhereFrom :Byte; Var ArrayName : Array Of String);
Begin
  SetLength(ArrayName, 2);  // for this to work going back to caller, VAR is needed for proc param

The compiler generates an Incompatible types error on SetLenght here.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of HenryM2

ASKER

Where exactly do you put the
type
  TStringArray = array of string;

When I add this under the Type declarations, I get 1 Error, from the compiler, with message
[DCC Fatal Error] F2039 Could not create output file 'C:\Site Designer IV\RunTime\SiteDesignerIV.exe'  
anywhere in a general unit

off course you'll have to add it to the uses clause
all procedures/functions/methods using that type will need to know that unit or type declaration
only declare it once, or you'll have other conflicts
that error is because the app was still running
hit Ctrl-F2 first for a naughty close of the app ...
Avatar of HenryM2

ASKER

Oeps, thanks, forgot the ap was runing on in the back ground from a previous compilation.
epasquier would say ...
it takes a genius to see that !
Avatar of HenryM2

ASKER

Thanks to all who contributed.  This was actually not so difficult but ended up in some interesting detours to get to the answer and at least I learned quit a bit.
> it takes a genius to see that !
I would not say that. But it definitely took too much guessing to answer this question