Link to home
Start Free TrialLog in
Avatar of lloydie-t
lloydie-t

asked on

How to create procedures

I have two procedures, one extracts text from a file line by line and inserts them into a database, the other revieves text from a serial port and inserts the info into the same database. The data they are inserting into the database is the same format. So rather than basically writing the same code twice I think I need to create a procedure.

text file code-------------------------------------------------
procedure TMainForm.CdrButtonOKClick(Sender: TObject);
var
i : integer;
J : integer;
k : integer;
areacode : string;
stdsearch : Pchar;
QueryCharge : Pchar;
TrunkCharge : Pchar;
CallInsert : Pchar;
begin
    TimeBandStart := StrToTime('08:00:00');
    TimeBandEnd := StrToTime('18:00:00');
    CdrButtonOK.Enabled := False;
    CdrImportEdit.Enabled := False;
    LB_query.Lines.Clear;
    Edit1.Clear;
With CollexDB do
  Begin
CollexDB := TliteDB.Create(self, 'collex.db');
//CollexDB.use ('collex.db');

  end;
Assignfile(CdrText, CdrImportEdit.Text);
Reset(CdrText);
Progressbar1.Position := 1;
j := 0;
k := 0;
while not EOF(CdrText) do begin
ReadLn (CdrText, Buffer1);
j := j + 1;
ProgressBar1.Max := j;
end;
Reset(CdrText);
ProgressBar1.Visible := True;
//loop though each line of text
while not EOF(CdrText) do begin
ReadLn (CdrText, Buffer1);
group_no := GrpNum(buffer1);
start_no := StartNum(buffer1);
ExtVar := PhoneNum(buffer1);
Exten := ExtNum(buffer1);
CallDay := DateOfCall(buffer1);
direction := CallDir(buffer1);
trans := Transfer(buffer1);
extn_no := ExtNum(buffer1);
trunk_no := TrunkNum(buffer1);
ddi := 'None';
dest := PhoneNum(buffer1);
SQLDuration := SQLLenofCAll(Buffer1);
ring_time := RingLen(buffer1);
call_time := SQLDateOfCall(buffer1)+' '+TimeOfCall(buffer1);
CallTime := TimeOfCall(buffer1);
 k := k + 1;
ProgressBar1.Position := k;
Duration := LenOfCall(buffer1);
if  direction = 'Out' then begin

begin
CollexDB.DoQuery('select areacode, band, destination from stdcodes where areacode = (SELECT MAX(areacode) FROM stdcodes WHERE '''+dest+''' LIKE areacode || ''%'')');
//if there is a match, run calculations
if  CollexDB.RowCount > 0 then
Begin
TimeOfCall1 := StrToTime(CallTime);
DayBand := DayOfWeek(StrToDate(CallDay));
LB_query.Lines.Add(CollexDB.Results[0][0]+': '+CollexDB.Results[0][1]);
band := CollexDB.Results[0][1];
dest_name := CollexDB.Results[0][2];
//Check wether weekend
If (DayBand = 1) or (DayBand = 7) then
begin
CallBand := 'we_end';
end else
// If not weekend, is it day or night
begin
      If (TimeBandStart <= TimeOfCall1) and (TimeBandEnd >= TimeOfCall1) then Begin
      CallBand := 'day';
        end
        else begin
      CallBand := 'night';
      end;
        end;
// Run query to find charge band and
....................................................and so on
--------------------------------------------------------------------------------------


serial port code--------------------------------------------------------------------
procedure TMainForm.ProcessSearch(S : String);
var
i : integer;
areacode : string;
stdsearch : Pchar;
QueryCharge : Pchar;
CallInsert : Pchar;

begin
    TimeBandStart := StrToTime('08:00:00');
    TimeBandEnd := StrToTime('18:00:00');
    CdrButtonOK.Enabled := False;
    CdrImportEdit.Enabled := False;
    Edit1.Clear;
    IncomingDataEdit.Lines.Add(sSearch);

With CollexDB do
  Begin
CollexDB := TliteDB.Create(self, 'collex.db');
//CollexDB.use ('collex.db');
 end;

ExtVar := PhoneNum(sSearch);
Exten := ExtNum(sSearch);
CallDay := DateOfCall(sSearch);
direction := CallDir(sSearch);
extn_no := ExtNum(sSearch);
ddi := 'None';
dest := PhoneNum(sSearch);
SQLDuration := SQLLenofCAll(sSearch);
call_time := SQLDateOfCall(sSearch)+' '+TimeOfCall(sSearch);
CallTime := TimeOfCall(sSearch);
if  direction = 'Out' then begin

begin
CollexDB.DoQuery('select areacode, band, destination from stdcodes where areacode = (SELECT MAX(areacode) FROM stdcodes WHERE '''+dest+''' LIKE areacode || ''%'')');
//if there is a match, run calculations
if  CollexDB.RowCount > 0 then
Begin
TimeOfCall1 := StrToTime(CallTime);
DayBand := DayOfWeek(StrToDate(CallDay));
LB_query.Lines.Add(CollexDB.Results[0][0]+': '+CollexDB.Results[0][1]);
band := CollexDB.Results[0][1];
dest_name := CollexDB.Results[0][2];
//Check wether weekend
If (DayBand = 1) or (DayBand = 7) then
begin
CallBand := 'we_end';
end else
// If not weekend, is it day or night
begin
      If (TimeBandStart <= TimeOfCall1) and (TimeBandEnd >= TimeOfCall1) then Begin
      CallBand := 'day';
        end
        else begin
      CallBand := 'night';
      end;
        end;
// Run query to find charge band and
-------------------------------------------------------------------------------------------------------------
Avatar of sftweng
sftweng

We could write the procedure for you, given the code you have posted but that would be the lazy way and wouldn't help you in the future. I'd like to offer some comments about what procedures and parameters are all about and why they are good things. Forgive me if I get overly simplistic - I do not intend to be condescending.

Harlan Mills was research scientist at IBM. I first heard him speak about 30 years ago. He was the father of "top down" programming, a concept that was crucial to all modern software development.

His essential thought was that if computers were smart enough, they could just listen to us and program themselves. However, they aren't, so we have to find a way of making them smarter, so we have languages that we can both understand.

He suggested that we start from the top - describing a problem and a desired solution in a way that we can understand. Then taking a piece of that and making it more detailed, in a way that the computer could understand. Eventually by doing this "stepwise refinement", we and the computer could agree on a way to do something.

Some of it would be repetitive, habitual. That's what computers are really good at. That's why we have "procedures".

A procedure is a sequence of events that can be used by other procedures, with predictable results. The simplest procedures always return the same results. E.g, a procudure called "Pi" would always return the number 3.141592...

But procedures that always do the same thing are boring, like a friend that always tells the same joke, so we invented parameters.

A parameter tells a procedure how to tell a different story. So I could create a different procedure, perhaps called "MathConstant" that gives me either "pi" or "e".

It would look something like:

function MathConstant ( parameterThatSays WhichOneAndDefaultsToPi : boolean) : real;
begin
  if (parameterThatSays WhichOneAndDefaultsToPi = true)
  then result = 3.141592...
  else result = 2...... {can't remember the detail about 'e' but it's another fundamental constant}
end {MathConstant};

So here's what you should do. Decide what is constant for each call to the procedure. That needs no parameters or if statements.

Decide what changes (or could change) each time. Make those parameters. Use conditional statements to control what actuall gets done.

This works best if you think about the procedures ahead of time, in a "top-down" manner rather than trying to retrofit existing code (e.g., as you have decided to do with your code). This process is fundamental to good design and programming. Do it first. Think "top-down".

Once again, forgive me if this sounds too condescending and you already know it. You're looking for an immediate silution and perhaps someone else will do it for you. But in the long run, you need to do it yourself.

Have fun,
Alan

ASKER CERTIFIED SOLUTION
Avatar of sftweng
sftweng

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 lloydie-t

ASKER

OK, I have made a start and realised that what I am trying to do actually requires functions as they arre returning values (sorry about the elementary mistakes). Based on the information, does this mean that the following would be the correct way of using a function.

code----------------------------------------------------------
dest := PhoneNum(buffer1);
CallTime := TimeOfCall(buffer1);
CallDay := DateOfCall(buffer1);

procedure TMainForm.CdrButtonOKClick(Sender: TObject);
begin
CollexDB.DoQuery('select areacode, band, destination from stdcodes where areacode = (SELECT MAX(areacode) FROM stdcodes WHERE '''+dest+''' LIKE areacode || ''%'')');
band := CollexDB.Results[0][1];
CheckCallBand(Callday, Calltime ); {uses new function}
QueryCharge := Pchar( 'SELECT '+CheckCallBand+', min, max, fixed, min_bill FROM chargecode WHERE band = '''+band+'''');


//My first function
function CheckCallBand (WhenDay, WhenTime : String) : boolean;
var
TimeBandStart := StrToTime('08:00:00');
TimeBandEnd := StrToTime('18:00:00');

begin {CheckCallBand }
WhenDay := DayOfWeek(StrToDate(WhenDay));
Whentime := StrToTime(WhenTime);
//Check wether weekend
 If (WhenDay = 1) or (WhenDay = 7) then
 begin
 result := 'we_end';
 end else
 // If not weekend, is it day or night
 begin
  If (TimeBandStart <= Whentime) and (TimeBandEnd >= Whentime) then Begin
  result := 'day';
  end
  else begin
  result:= 'night';
  end;
 end;
end {CheckCallBand };
-------------------------------------------------------------------------
Don't apologize. There are no stupid questions, just stupid answers

Yes, you have mad a good start. I could use your function "CheckCallBand". So could others. But you might want to change its name to something like "IsItNight" and return only a single boolean, not a string.
does this mean the function declaration is wrong.
------------------------------------------------------
function CheckCallBand (WhenDay, WhenTime : String) : boolean;