Topic: Can someone help me to find the correct order for this script

My knowledge is very limited
can someone help me to find the correct order for this script

Thank you in advance

Ps  This is my project https://www.dropbox.com/s/z2299xqme5dpu … 3.rar?dl=0

Post's attachments

Attachment icon script.txt 4.11 kb, 608 downloads since 2017-01-26 

2 (edited by mathmathou 2017-01-27 04:06:53)

Re: Can someone help me to find the correct order for this script

Hello casedemarcat,


It's a bit complicated to correct you script as I don't really known what it does.


What I can try to show you is how a script is organized.


-----> AT THE BEGINING OF THE SCRIPT

you can (but not always) find what we call global variables. It is not recommended, but if you can not avoid using them, they must be declared on the first lines like this :

var
   Timer: TTimer;
   iSeconds: integer;

No begin, end or procedure declarations, just VAR and then the variables you declare.


-----> WITHIN THE SCRIPT

this is where all your procedures and functions will be declared. More a less, a procedure DOES something while a function returns a RESULTS, but this is not always the case.

A procedure is declared like this :

procedure frmLogin_bLogin_OnClick (Sender: string; var Cancel: boolean);
begin
     //what the procedure will do
end;

you must use the keyword procedure first, then give it a name (without spaces), then (eventually), parameters between ( and )
most of the time, this will be written my the Object Inspector when you when you double click in the desired event (onclick, onmousedown, onclose and so on).
begin and end; are there to fix the limits of the procedure, everything outside will be ignored (two exception that we will see later)


If you need some variables to make you procedure run, they are declared AFTER the procedure keyword, and BEFORE the begin statement like this :

procedure frmLogin_bLogin_OnClick (Sender: string; var Cancel: boolean);
var
     i : Integer;
     s : String;
begin
     //what the procedure will do
end;

I'm making this clear because I found some VAR outside procedures in your script and that makes them global variables and your script is hard to read after that smile


I said they were exceptions to the fact that everything outside the begin/end is ignored.

The first exception is global variables : if you declared a global variable at the begining of your script like

var
     sUser : string;

then in the previous example of procedure you do not need to redeclare it, you can assign it right away like this :

procedure frmLogin_bLogin_OnClick (Sender: string; var Cancel: boolean);
var
     i : Integer;
     s : String;
begin
     sUser := 'Mathias';     
     //what the procedure will do
end;

The second exception I can think of (there might be others) is when a procedure makes a call to another procedure, but that is another story.


-----> AT THE END OF THE SCRIPT
you will find this :

begin
     //some script, but not always
end.

Did you notice that every instruction during your code ends with a ; when the last end at the end of the script is followed by a dot (.) ?


Everything you place AFTER that statement will be ignored.


What about the instructions between those tags ? Well, they are always executed everywhere.
For example, in my scripts, you will fond this :

begin
    //---> Hints delays and duration
    Application.HintHidePause := 15000; //How long will the hints be displayed
    Application.HintPause := 300; //After how long will the hints appear
end.

With this, I am sure that on any Form of my application, if I set up a Hint, they will be displayed after 0,3 second of pause, and for 15 seconds (as long as the user does not move the mouse).
I also think that this is the first code executed by the program on startup (not sure), so if you want to check for the presence of users, you could put it here. I personally put this on the onshow event of Form1, because after it's been checked, I don't need it anymore. Personal taste.


-----> A FEW MORE THINGS
Somewhere at the begining of your script I found :

var
   sUser: string = '';

This is correct, as you declare the variable and assign it an empty string (which is not NULL but empty).


But this same variable is used in a following procedure like this :

     begin
          sUser := frmLogin.edUser.Text; // remember username

Why assign a value to a global variable and then assign it another value when you first use it ? Just declare it globally and the assign it a value when you use it. Just my opinion, you might have reasons I did not guess.


Also, I saw this :

begin
     // SQL query for check user and password
     s := VarToStr( SQLExecute('SELECT count(id) FROM users WHERE (login = ''' + frmLogin.edUser.Text + ''') AND (password = ''' + frmLogin.edPassword.Text + ''');') );

     // if SQL query found login and password
     if (s <> '0') and (s<>'') then
     begin
          sUser := frmLogin.edUser.Text; // remember username

          // check admin rights
          s := VarToStr( SQLExecute('SELECT administrator FROM users WHERE (login = ''' + sUser + ''');') );
          if s='0' then Form1.bUsers.Enabled := False; // if the user does not have administrator privileges, deactivate the button to create other users

          // check permissions to read
          s := VarToStr( SQLExecute('SELECT read FROM users WHERE (login = ''' + sUser + ''');') );
          if s='0' then Form1.bEdit.Enabled := False; // deactivate the button to edit the record

          // check write permissions
          s := VarToStr( SQLExecute('SELECT write FROM users WHERE (login = ''' + sUser + ''');') );
          if s='0' then
          begin
               Form1.bAdd.Enabled := False;      // deactivate the button to add the record
               frmEmployee.bOK.Enabled := False; // deactivate the button to save the record
          end;

          // check permission to delete
          s := VarToStr( SQLExecute('SELECT remove FROM users WHERE (login = ''' + sUser + ''');') );
          if s='0' then Form1.bDelete.Enabled := False; // deactivate the button to delete the record

          // check permission to search
          s := VarToStr( SQLExecute('SELECT search FROM users WHERE (login = ''' + sUser + ''');') );
          if s='0' then Form1.bSearch.Enabled := False; // deactivate the button to search the records


          frmLogin.Close; // close login form
     end else MessageDlg('Parola dvs nu este corecta', mtError, mbOk, 0); // message if the password is incorrect

end;

This is perfectly correct but you use 5 SQLQueries to check rights one after another when you could just use one like this :

procedure frmLogin_bLogin_OnClick (Sender: string; var Cancel: boolean);
var
   s: string;
   Rights : TDataSet;
begin
     // SQL query for check user and password
     s := VarToStr( SQLExecute('SELECT count(id) FROM users WHERE (login = ''' + frmLogin.edUser.Text + ''') AND (password = ''' + frmLogin.edPassword.Text + ''');') );

     // if SQL query found login and password
     if (s <> '0') and (s<>'') then
         begin
              sUser := frmLogin.edUser.Text; // remember username

              SQLQuery('SELECT * FROM users WHERE login = "'+sUser+'"', Rights); //one query and all the results are assigned to the DataSet called Rights
              while not Rights.Eof do //shuffle through the DataSet calling the fields by their names
                  begin
                      if Rights.FieldByName('administrator').AsInteger = 0 then Form1.bUsers.Enabled := False;
                      if Rights.FieldByName('read').AsInteger = 0 then Form1.bEdit.Enabled := False;
                      if Rights.FieldByName('write').AsInteger = 0 then
                          begin
                              Form1.bAdd.Enabled := False;
                              frmEmployee.bOK.Enabled := False; 
                          end;
                      if Rights.FieldByName('remove').AsInteger = 0 then Form1.bDelete.Enabled := False;
                      if Rights.FieldByName('search').AsInteger = 0 then Form1.bSearch.Enabled := False;
                      Rights.Next;
                  end;
              Rights.Free;
              frmLogin.Close; // close login form
         end
     else MessageDlg('Parola dvs nu este corecta', mtError, mbOk, 0); // message if the password is incorrect

end;     

code is untested, but you get the idea I hope.


That's what I can tell you for the moment. I know it might not be the solution you were expecting, but I hope it helps a bit.


Cheers


Mathias

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

3 (edited by mathmathou 2017-01-27 04:33:13)

Re: Can someone help me to find the correct order for this script

Hello again,


Work was not to heavy today, so I had time to check and try to correct your code.


There was an onshow procedure declared twice and a few other things, but nothing too rough, your ideas are good.
The MAIN problem was that the default form (teh orange one in the tab section of MVD) was not Form1 but anotherone, so all your procedures were not executed.


I also modified 4 pieces of your code :

1- added a second password edit field for creating users and checking if passwords match
2- modified the procedure that checks if users exists and that create the admin if no users found
3- used a DataSet to check users rights and activate /deactivate buttons with just 1 sql query instead of 5
4- changed the naming convention of your backups for more natural sorting of the files


You might want to MD5 the passwords before saving just to make sure no-one can read them directly in the database.


I commented the code everywhere, I hope it will be clear enough.


Have a good week-end


Cheers


Mathias

Post's attachments

Attachment icon 123123_corrected.zip 361.03 kb, 563 downloads since 2017-01-27 

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

4 (edited by casedemarcat 2017-01-27 11:38:47)

Re: Can someone help me to find the correct order for this script

begin by thanking you for the effort, my English is understanding and help from Google Translate : )I tried changes and sincerely thank you again, operates in version 3.1 it is possible to use  these changes in version 1.46 (free version) I tried and I get this error   : Unknown type : ' TDataSet ' at 95:21

Thanks again and I appreciate the break of your time for something free.




Original romanian text : smile
Incep prin a multumi pentru efortul depus , engleza mea este la nivel de intelegere si ajutor de la google translate smile

Am incercat modificarile si sincer multumesc inca o data ,  pe utlima versiune 3.1 functioneaza ok   crezi ca este posibil sa folosec aceste modificari in versiunea  1.46 , am incercat si primesc aceasta eroare  unknown tipe TDataSet at 92 :21

Multumesc inca o data si apreciez  ca rupeti  din timpul vostru pentru o chestie gratuita .

Re: Can someone help me to find the correct order for this script

Hello casedemarcat and sorry for the delay,


If the free version does not support TDataSet, just comment (or erase) my procedure, and activate yours (the procedure you wrote with the 5 queries) and it should work smile


Cheers



Mathias

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Can someone help me to find the correct order for this script

mathmathou wrote:

Hello casedemarcat and sorry for the delay,


If the free version does not support TDataSet, just comment (or erase) my procedure, and activate yours (the procedure you wrote with the 5 queries) and it should work smile


Cheers



Mathias



Thanks again and I appreciate the break of your time for something free.