Avatar billede skindbeni Nybegynder
29. januar 2008 - 16:36 Der er 8 kommentarer og
1 løsning

Kan ikke få min funktion til at makke ret

Hej.

I mit forsøg på at sammensætte et skatteberegningsprogram får jeg en fejl, når jeg forsøger at indsætte nogle databaseværdier i en selvlavet funktion

function BeregnBundskat(var PI: integer;KI,KIaf: Integer;Gift: boolean): integer;
begin
  Result:= PI;
  If KI > 0 then Result:= Result + KI;
  If (Gift = true) and (KIaf < 0) then Result:= Result - Min(KI,KIaf * -1);
  Result:= Round(Result * SatsBundskat);
end;

Derefter har jeg en procedure, hvor jeg prøver at bruge funktionen herover. Den kan godt finde funktionen, da der kommer hjælpetekst op, problemet opstår når jeg skal indsætte første parameter.

Procedure BeregnBundskatPerson1;
begin
  clientdataset1Bundskat.AsInteger := BeregnBundskat(clientdataset1PI.asInteger,clientdataset1KI.asInteger,clientdataset1KI2.asInteger,clientdataset1Gift.asBoolean);
end;

Det kan den ikke klare.

Skriver jeg eksempelvis flg. er der ingen problemer, men det mener jeg ikke bør være nødvendigt:

Procedure BeregnBundskatPerson1;
var
  PI,KI,KI2: integer;
  gift: boolean;
begin
  PI := clientdataset1PI.asInteger;
  KI := clientdataset1KI.asInteger;
  KI2 := clientdataset1KI2.asInteger;
  Gift := clientdataset1Gift.asBoolean;

  clientdataset1Bundskat.AsInteger := BeregnBundskat(PI,KI,KI2,Gift);
end;

Kan i andre se, hvad der kan være galt?
Avatar billede kroning Nybegynder
29. januar 2008 - 16:44 #1
Hvilken fejl får du?
Avatar billede nca Juniormester
29. januar 2008 - 17:58 #2
Jeg tror at fejlen ligger i din var-parameter, der jo kommer fra et dataset, som så skal holdes opdateret af procedure.
Prøv at lave en global variabel PI, som du sætter lig med funktionens result. Altså PI:=BeregnBundskat(KI,KIaf: Integer;Gift: boolean;
Avatar billede skindbeni Nybegynder
29. januar 2008 - 20:08 #3
Jeg får følgende compilerfejl:

[Error] Skatteberegning.pas(131): E2197 Constant object cannot be passed as var parameter

som svarer til denne linie:

clientdataset1Bundskat.AsInteger := BeregnBundskat(clientdataset1PI.asInteger,clientdataset1KI.AsInteger,clientdataset1KI2.AsInteger,clientdataset1Gift.AsBoolean);

Fejlen ligger vist et sted i den første parameter, for når jeg der skriver clientdataset1PI. så kommer der ikke en liste med valgmuligheder, men når jeg når til 2. og 3. parameter og skriver clientdataset1KI. så kommer en liste, hvor jeg eksempelvis kan vælge asInteger, som vel indikerer, at Delphi kan finde ud af det, jeg laver og omvendt.

@nca: Jeg er ikke lige helt klar over, hvad det er du mener.

PI er en parameter i function BeregnBundskat(var PI: integer;KI,KIaf: Integer;Gift: boolean): integer;

Det er bundskatten, der skal blive resultatet og ikke PI.
Avatar billede kroning Nybegynder
29. januar 2008 - 20:14 #4
prøv at fjerne var, altså:
BeregnBundskat(PI: integer;KI,KIaf: Integer;Gift: boolean): integer;
Avatar billede skindbeni Nybegynder
29. januar 2008 - 20:25 #5
Hej Kroning.

Det havde den ønskede virkning og problemet var min forkerte konstruktion af funktionen.

Smid et svar.

Det forvirrer mig lidt, at i nogle events, funktioner og procedurer, bliver der brugt var, const eller som her ingenting i konstruktionen. Hvornår skal man egentlig konstruere på hvilke måder?
Avatar billede kroning Nybegynder
29. januar 2008 - 20:48 #6
nca svarede først, så hvis han smider et svar.

Det med var, const osv er nok en længere forklaring men her er lige lidt af hvad jeg bruger i hverdagen.

procedure Aba(x : integer);
du kan kalde proceduren med en konstant eller en var, du kan ændre på x i proceduren uden at den var du evt. kaldte den med ændres.

procedure Aba(var x : integer);
Her skal Aba kaldes med en var parameter og man kan altså ikke benytte en konstant, når du ændre på x i proceduren ændre du også på den var du skrev.

procedure Aba(const x : integer);
her bliver x read-only, dvs. du kan ikke ændre på x i proceduren og du kan ikke bruge x som en var parameter i en anden procedure.

hvis du bruger objecter som parameter så er der andre regler:
procedure Aba(x : TObject);
x er her kun en pointer til selve objectet dvs. hvis du ændre på en af x´s værdier så er det det object som du kaldte Aba med du ændre på.
dvs. om du skriver Aba(x : TObject), Aba(var x : TObject) eller Aba(const x : TObject) har ingen større betydning.

Men mht. med eller uden var så gør jeg normalt sådan:
Hvis der kun skal returneres en enkelt værdi så benytter jeg en funktion:
function Aba(x : integer) : integer;
i stedet for procedure Aba(var x : integer);

hvis der skal returneres flere værdier så benytter jeg var og evt. samtidig en function:
function Aba(var x, y : integer) : double;

Andre kan sikkert skrive en masse mere om dette og rette det jeg har skrevet :-)

Men prøv også at læse i hjælpen, i Delphi 7 står det faktisk meget godt beskrevet.
Avatar billede nca Juniormester
29. januar 2008 - 21:36 #7
Hej Kroning, det var et pænt træk ;-)
Jeg lægger et svar her.
Avatar billede hrc Mester
29. januar 2008 - 23:05 #8
Tidligere blev koden optimeret af const'er i parameterheaderen, men jvf. Marco Cantù er den i praksis overflødig nu. Hans anbefaling var at skippe den - og i Delphi-kredse er han jo ret tæt på gud (Hejlsberg - også selvom han valgte den mørke side).

Jeg gør det dog konsekvent ved parametre jeg ikke har tænkt mig at rette. Synes det gør koden lettere at læse. Desuden er jeg stædig!
Avatar billede skindbeni Nybegynder
29. januar 2008 - 23:47 #9
Hej siger tak til alle.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester