Jump to content
Henry Olive

Function with 2 return values ?

Recommended Posts

Good Day,
 

MyQuery Result is like below

TotalCost...TotalCostWıthExp

100              110

 

Is it possible something like below function

function.GetBomCosts (ItemCode:String): Value1,Value2 : Double

Thank You

 

 

 

Share this post


Link to post

Hi, only a single result but you can change to

 

function GetBomCosts(const ItemCode : String; var value1, value2 : Double) : boolean
begin
with TFDQuery.Create do
begin
 Value1:=0;
 value2:=0;
 Connection:= FDConnection1;
 SQL.Text:='SELECT itemcode,value1,value2 from table where code='+quotedstr(itemcode);
 active:=true;
 if fieldbyname('Itemcode').isNull then result:=false 
 else begin
        value1:=FieldByName('value1').asFloat;
        value2:=FieldByName('value2').asFloat;
        result:=true;
      end;
 active:=false;     
end;

end;

 

  • Like 2

Share this post


Link to post

You can return a record:

TTotalCostResult = record
  TotalCost: Double;
  TotalCostWıthExp: Double;
end;
function GetBomCosts(ItemCode:String): TTotalCostResult;

 

  • Like 1

Share this post


Link to post

You can return a TArray<Double>:

function GetBomCosts(const ItemCode : String) : TArray<Double>;
begin
  { Retrieve values }
  ...
  
  { Return values as array }
  SetLength(Result, 2);
  Result[0] := value1;
  Reuslt[1] := value2;
end;

 

Share this post


Link to post
9 minutes ago, Uwe Raabe said:

You can return a TArray<Double>:


function GetBomCosts(const ItemCode : String) : TArray<Double>;
begin
  { Retrieve values }
  ...
  
  { Return values as array }
  SetLength(Result, 2);
  Result[0] := value1;
  Reuslt[1] := value2;
end;

 

Whilst you can, this doesn't feel like a great idea. It's one thing returning a tuple in a language like Python with support for unpacking. But a Delphi dynamic array should be used for arrays, things where each item is a different value of the same thing. That's not the case here. They are two distinct things. 

 

Use a record, or two out params. 

Share this post


Link to post
9 hours ago, David Heffernan said:

Whilst you can, this doesn't feel like a great idea. It's one thing returning a tuple in a language like Python with support for unpacking. But a Delphi dynamic array should be used for arrays, things where each item is a different value of the same thing. That's not the case here. They are two distinct things. 

 

Use a record, or two out params. 

I do not necessarily agree with this. I agree on the fact that a record would work better for several reasons and that a generic list has a number of disadvantages; however, if the function is eventually going to have multiple values, then a typed list (i.e. a generic but with a concrete type) would probably work better. However, if changes are infrequent and/or the values must be easy to identify then a record is absolutely the way to go.

I would never use a dynamic array because it's too easy to mis-identify things. 

Share this post


Link to post
8 hours ago, David Heffernan said:

That's a pair not a tuple

A pair is a tuple where n is 2 - so yes it is a tuple

  • Like 1

Share this post


Link to post
1 hour ago, Stefan Glienke said:

A pair is a tuple where n is 2 - so yes it is a tuple

OK. What name would you give this type

 

array [0..2] of Double 

Share this post


Link to post
5 hours ago, David Heffernan said:

OK. What name would you give this type

 

array [0..2] of Double 

A static array of Double with the size 3 - exact type name would be context-specific and since you are not giving any context I cannot name it.

Share this post


Link to post
3 hours ago, Stefan Glienke said:

A static array of Double with the size 3 - exact type name would be context-specific and since you are not giving any context I cannot name it.

We don't need any context to know that a fixed length array shouldn't be named a tuple. 

Share this post


Link to post
Posted (edited)

You can return a TPointF:

procedure Test;
var
  A, B: Currency; // <-- ?
  P: TPointF;

  function GetResult(const s: string): TPointF;
  begin
    result.X := 99.98;
    result.Y := -1.01;
  end;

begin
  { get going fast }
  P := GetResult('ABC');
  { in order to be able to play with some data types }
  A := P.X;
  B := P.Y;
end;


 

Edited by Gustav Schubert
Use of Double should be questioned before optimization.

Share this post


Link to post

Thank You So Much

Serge, Cristian, Uwe, David, Andrea, Frost.Brutal, Stefan, Leif, Bill, Gustav

Share this post


Link to post
1 hour ago, Gustav Schubert said:

You can return a TPointF:


function GetBomCosts(ItemCode: string): TPointF;

procedure Test;
var
  BC: TPointF; // cointains X and Y of type single
  TotalCost: double;
  TotalConstWithExp: double;
begin  
  BC := GetBomCosts('ABC');
  TotalCost := BC.X; // conversion to double will be implicit
  TotalCostWithExp := BC.Y;
end;


 

It goes from bad to worse!! 

Share this post


Link to post
12 hours ago, Uwe Raabe said:

that would be better named TDouble

TDoubleDouble - we really need to mark what's inside 🙂

  • Like 1

Share this post


Link to post
38 minutes ago, David Heffernan said:

It goes from bad to worse!! 

But it started with two good answers at the top, which I liked, to make it clear. 🙂 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×