Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: petrusic - Aprile 20, 2021, 12:59:21 pm

Titolo: [Risolto] variabile array restituita da function
Inserito da: petrusic - Aprile 20, 2021, 12:59:21 pm
Per farmi restituire più variabili da una function ho sempre utilizzato variabili array.
Non ho mai avuto problemi, anche in Lazarus. Ho però impiegato variabili di tipo variant.
Questa volta, dovendo ricevere dati della stessa natura, ho messo in campo variabili String.
Però il compilatore non accetta le mie dichiarazioni e mi fornisce errori come l seguenti:
Citazione
frmmain.pas(1114,13) Error: Incompatible types: got "TtbRitorno" expected "AnsiString"
frmmain.pas(1357,21) Error: Incompatible types: got "AnsiString" expected "TtbRispo"
Riporto il codice scritto:
Codice: [Seleziona]
function LeggiRecPiaCont(coVoce: String): String;
type
  TtbRitorno = array[0..4] of String;

var
  swErro: Boolean;

  descrMov: String;
  sql: String = 'SELECT * FROM piancont WHERE NumVoce = ';

  tbRitorno: TtbRitorno;
begin
  sql:= sql + coVoce;
  Form1.ZQuery1.SQL.Text:= sql;
  try
    Form1.ZQuery1.ExecSQL;
  except
    on E: Exception do
    begin
      swErro:= True;
       ShowMessage('ERRORE ' + E.Message + System.lineending + 'nella LETTURA del record ContabFamDB.piancont.' + coVoce + System.lineending + System.lineending  + '***** Il programma verra'' chiuso *****');
       Application.Terminate;
    end;
  end;
   tbRitorno[0]:= Form1.ZQuery1.FieldByName('NumVoce').AsString;
   tbRitorno[1]:= Form1.ZQuery1.FieldByName('NomeVoce').AsString;
   tbRitorno[2]:= Form1.ZQuery1.FieldByName('ContrPartSiNo').AsString;
   tbRitorno[3]:= Form1.ZQuery1.FieldByName('DtPrimoUso').AsString;
   tbRitorno[4]:= Form1.ZQuery1.FieldByName('DtUltimUso').AsString;
   Result:= tbRitorno;   <--- produce ERROR
end;                     

procedure InsRecMovvgg(dtTratt, infTb: String; ixTbMovv: Integer);
type
   TtbRispo = array of String;                 
[...]
var
tbRispo: TtbRispo;
begin
[...]
          tbRispo:= LeggiRecPiaCont(tbMovv[i, 3]);   // tbMovv[i, 3], cioè "codice Voce"  <--- produce ERROR
          SetLength(tbRispo, 2);
          nomeVoce:= tbRispo[0];   // piancont.NomeVoce
          segnContrPart:= tbRispo[1];   // piancont.ContrPartSiNo
[...]

Da ieri cerco di risalire all'errore, ma qualsiasi soluzioone tentata dalla mia immaginazione è fallita. Ho provato anche a sostituire il tipo di variabili da String a Variant, ma inutilmente.
Titolo: Re:variabile array restituita da function
Inserito da: nomorelogic - Aprile 20, 2021, 01:09:09 pm
il fatto è hai dichiarato la funzione che restituisce una string (e quindi result è di tipo string)
è normale che se si assegna a result qualsiasi cosa che non sia string dia errore

dovresti quindi dichiarare una funzione che restituisca il tipo TtbRitorno

tipo:

Codice: [Seleziona]

type
  TtbRitorno = array[0..4] of String;


...

function LeggiRecPiaCont(coVoce: String): TtbRitorno;

var
  swErro: Boolean;

  descrMov: String;
  sql: String = 'SELECT * FROM piancont WHERE NumVoce = ';

  tbRitorno: TtbRitorno;
begin
  sql:= sql + coVoce;
  Form1.ZQuery1.SQL.Text:= sql;
  try
    Form1.ZQuery1.ExecSQL;
  except
    on E: Exception do
    begin
      swErro:= True;
       ShowMessage('ERRORE ' + E.Message + System.lineending + 'nella LETTURA del record ContabFamDB.piancont.' + coVoce + System.lineending + System.lineending  + '***** Il programma verra'' chiuso *****');
       Application.Terminate;
    end;
  end;
   tbRitorno[0]:= Form1.ZQuery1.FieldByName('NumVoce').AsString;
   tbRitorno[1]:= Form1.ZQuery1.FieldByName('NomeVoce').AsString;
   tbRitorno[2]:= Form1.ZQuery1.FieldByName('ContrPartSiNo').AsString;
   tbRitorno[3]:= Form1.ZQuery1.FieldByName('DtPrimoUso').AsString;
   tbRitorno[4]:= Form1.ZQuery1.FieldByName('DtUltimUso').AsString;
   Result:= tbRitorno;   <--- produce ERROR
end;       
Titolo: Re:variabile array restituita da function
Inserito da: petrusic - Aprile 20, 2021, 03:13:56 pm
il fatto è hai dichiarato la funzione che restituisce una string (e quindi result è di tipo string)
è normale che se si assegna a result qualsiasi cosa che non sia string dia errore

dovresti quindi dichiarare una funzione che restituisca il tipo TtbRitorno

Sicuramente la prova da me riportata non dimostra di avere provato anche quella che mi hai suggerito, ma ti assicuro di avere messo in pratica anche quella.
Ecco cosa viene fuori:
Codice: [Seleziona]
function LeggiRecPiaCont(coVoce: String): String;
type
  TtbRitorno = array[0..4] of String;

var
  swErro: Boolean;

  descrMov: String;
  sql: String = 'SELECT * FROM piancont WHERE NumVoce = ';

  tbRitorno: TtbRitorno;
begin
  sql:= sql + coVoce;
  Form1.ZQuery1.SQL.Text:= sql;
  try
    Form1.ZQuery1.ExecSQL;
  except
    on E: Exception do
    begin
      swErro:= True;
       ShowMessage('ERRORE ' + E.Message + System.lineending + 'nella LETTURA del record ContabFamDB.piancont.' + coVoce + System.lineending + System.lineending  + '***** Il programma verra'' chiuso *****');
       Application.Terminate;
    end;
  end;
   tbRitorno[0]:= Form1.ZQuery1.FieldByName('NumVoce').AsString;
   tbRitorno[1]:= Form1.ZQuery1.FieldByName('NomeVoce').AsString;
   tbRitorno[2]:= Form1.ZQuery1.FieldByName('ContrPartSiNo').AsString;
   tbRitorno[3]:= Form1.ZQuery1.FieldByName('DtPrimoUso').AsString;
   tbRitorno[4]:= Form1.ZQuery1.FieldByName('DtUltimUso').AsString;
   Result:= tbRitorno;    <-- riga 1116
end;                                                                                                                                                   

Ecco l'errore segnalato dal compilatore:
Citazione
frmmain.pas(1116,13) Error: Incompatible types: got "TtbRitorno" expected "AnsiString"
Titolo: Re:variabile array restituita da function
Inserito da: DragoRosso - Aprile 20, 2021, 03:55:23 pm
@petrusic
Codice: [Seleziona]
function LeggiRecPiaCont(coVoce: String): String;

Questa funzione ritorna una stringa, è per quello che il compilatore di dice che si aspetta una AnsiString ...  ;D
Titolo: Re:variabile array restituita da function
Inserito da: petrusic - Aprile 20, 2021, 05:21:40 pm
@ DragoRosso
Non capisco cosa vuoi dire.
Il mio array "tbRitorno" è di tipo String, quindi è corretto che la funzione restituisca una String.

In altra function in cui l'array "tbRitorno" è di tipo Variant, la function restituisce una Variant e NON da errore. Allora perchè quello di tipo String  mi da Errore?

Tu come faresti?
Titolo: Re:variabile array restituita da function
Inserito da: nomorelogic - Aprile 20, 2021, 05:40:39 pm
tbRitorno non è di tipo string, ma è di tipo array of string

per fare in modo che la tua funzione ritorni un array di string devi dichiararla come segue
Codice: [Seleziona]
function LeggiRecPiaCont(coVoce: String): TtbRitorno;
Titolo: Re:variabile array restituita da function
Inserito da: nomorelogic - Aprile 20, 2021, 05:42:49 pm
In altra function in cui l'array "tbRitorno" è di tipo Variant, la function restituisce una Variant e NON da errore. Allora perchè quello di tipo String  mi da Errore?

il tipo Variant è un tipo particolare
non ti dava errore perché Variant può assumere sia valore scalare (esempio string) chee "array of"
puoi vederla come un tipo di variabile che non ha tipo e che quindi può rappresentare sia valori singoli che multipli
Titolo: Re:variabile array restituita da function
Inserito da: petrusic - Aprile 20, 2021, 06:27:28 pm
tbRitorno non è di tipo string, ma è di tipo array of string

per fare in modo che la tua funzione ritorni un array di string devi dichiararla come segue
Codice: [Seleziona]
function LeggiRecPiaCont(coVoce: String): TtbRitorno;

Ma TtbRitorno è un type dichiarato dentro la stessa function, perciò scrivendo:
Codice: [Seleziona]
function LeggiRecPiaCont(coVoce: String): TtbRitorno;   
type
  TtbRitorno = array[0..4] of String;
var
  tbRitorno: TtbRitorno;             
[...]
ottengo il seguente Errore:
Citazione
frmmain.pas(1097,43) Error: Identifier not found "TtbRitorno"

Per farlo funzionare devo dichiararlo fra i type della sezione Implementation
Infatti, così facendo, l'errore in compilazione non si presenta più.

Confesso che una situazione simile non rientrava nel mio orizzonte di immaginazione.

Grazie, gr....sime.
Titolo: Re:variabile array restituita da function
Inserito da: DragoRosso - Aprile 20, 2021, 06:42:08 pm
Devi tenere presente che in Pascal le dichiarazioni sono fortemente tipizzate.

Cioè i tipi che vengono usati nelle dichiarazioni devono essere assolutamente compatibili.

Questo "rigore" in primis è necessario per avere poi un runtime che di base non dovrebbe avere delle problematiche legate alle assegnazioni.

Usando i puntatori (non sempre) e i variant si vanno incontro a delle problematiche (infatti hai visto che puoi passare come result qualsisi cosa se una funzione ha un valore di ritorno variant).
Se il chiamante non fà poi la tipizzazione del risultato della funzione che ritorna un variant, può accadere che prenda "lucciole" per "lanterne" come si suol dire.

Prova a pensare se fai manutenzione al codice dopo diverso tempo e magari nel result (variant) ci metti un nuovo dato non gestito da tutti i "punti" di chiamata di quella funzione ..........

Ciao
Titolo: Re:variabile array restituita da function
Inserito da: nomorelogic - Aprile 20, 2021, 06:50:02 pm
Per farlo funzionare devo dichiararlo fra i type della sezione Implementation
Infatti, così facendo, l'errore in compilazione non si presenta più.

infatti se guardi bene quì
http://www.lazaruspascal.it/index.php?topic=2460.msg15663#msg15663 (http://www.lazaruspascal.it/index.php?topic=2460.msg15663#msg15663)

la dichiarazione l'avevo portata fuori dalla funzione ;)
Titolo: Re:variabile array restituita da function
Inserito da: petrusic - Aprile 20, 2021, 10:04:52 pm
infatti se guardi bene quì
http://www.lazaruspascal.it/index.php?topic=2460.msg15663#msg15663 (http://www.lazaruspascal.it/index.php?topic=2460.msg15663#msg15663)

la dichiarazione l'avevo portata fuori dalla funzione ;)
8)