Sorry for the delay Agusec, 

Here is a bare bones example.  I've only used one date picker in this example, and the code is activated by the button click, rather than the on_exit in the sample code above.


The current code assumes you have set your Windows clock to display 24 hour time, otherwise this code will close your program twice a day

102

(47 replies, posted in Script)

Kofa,


I've been trying to get this to work for monitors of different resolutions and I have failed.


It seems there is a Windows magnification factor that MVD can't cope with. It might be due to the version of Delphi that is used to make MVD.



Here is what I've tried, but it fails if the monitor is set to 150%.


procedure ScaleForm  (F: TForm; ScreenWidth, ScreenHeight: LongInt) ;
begin

 F.Scaled := True;
 F.AutoScroll := False;
 F.Position := poDefaultPosOnly; //poScreenCenter;
 F.Font.Name := 'Arial';
 if (Screen.Width <> ScreenWidth) then
 begin
     F.Height :=  (F.Height * Screen.Height) div ScreenHeight;
     F.Width :=  (F.Width * Screen.Width) div ScreenWidth;
     F.ScaleBy(Screen.Width,ScreenWidth) ;
 end; 
end;

procedure CentreForm(Form: TForm);
begin
    with Form do
    begin
        Left := Application.frmMain.Left + (Application.frmMain.Width - Width) div 2;
        if Left < 0 then Left:=0;
        Top := Application.frmMain.Top + (Application.frmMain.Height - Height) div 2;
        if Top <0 then Top:=0;
   end;
end;

Called in the default begin...end by:

 ScaleForm(frmMain,1920,1080) ;

//OR

  CentreForm(frmMain);

I think your problem might be solved by changing your quotes.



 frmScore.ComboBox1.dbSQLExecute('SELECT name, id FROM Specification WHERE id_Dogovor="'+frmScore.dogovor.sqlValue+"'');

Note the " then '+ and at the end +' then " before the final '.

The double '' are speech quotes  and the single is the apostrophe.


Думаю, вашу проблему можно решить, изменив цитаты.


Обратите внимание на [color = red] "[/ color], затем [color = red] '[/ color] и в конце [color = red]' [/ color], затем [color = red]" [/ color] перед final [color = red] '[/ color].

Двойное «» - это речевые кавычки, а одинарное - апостроф.

104

(30 replies, posted in General)

You might be able to bend the Change Password form to do some of what you want instead of creating a complete form from scratch.


To call the inbuilt change password form  you can choose from:



procedure form1_btnUser_OnClick (Sender: TObject; var Cancel: boolean);
begin

    //frmdbCoreUsers.ShowModal;
    Form1.mniUsers.click;
end;

procedure Form1_btnPassword_OnClick (Sender: TObject; var Cancel: boolean);
begin

   //frmdbCoreUserForm.ShowModal;
   Form1.mniChangePassword.click;
   //frmdbCoreUserChangePwd.show;
end;

The buttons are ones I've placed elsewhere in my program, but you could take Brian's code and place either the mniXXXX or the frmdbCoreUserXX in the code he has for the two buttons he has used.

105

(5 replies, posted in General)

A demo provided.   I forgot to declare the label above, however the code attached works.  The user and password is the default admin/admin

Thanks Alan,


I have added some code to make the times permanent by storing them in the _user table.

To this end, two extra columns are added to the table. In my case

closeStart and CloseEnd both of type TIME.

To save the time from the date pickers I've used the OnExit event, which requires clicking out of the date time picker. On reflection it is probably better to either test for the enter key being pressed or create two buttons that update the database. However, the current code is:

procedure frmAutoCloseSet_dtCloseSpanEnd_OnExit (Sender: TObject);
begin
  SQLExecute('UPDATE  _user SET closeEnd = "'+TimeToStr(frmAutoCloseSet.dtCloseSpanEnd.DateTime)+'" WHERE username = "'+ application.User.Username +'"');
end;

procedure frmAutoCloseSet_dtCloseSpanBegin_OnExit (Sender: TObject);
begin
  frmMain.lbTimeClose.Caption :=  frmMain.lbTimeClose.Caption + TimeToStr(frmAutoCloseSet.dtCloseSpanBegin.DateTime);
  SQLExecute('UPDATE  _user SET closeStart = "'+TimeToStr(frmAutoCloseSet.dtCloseSpanBegin.DateTime)+'" WHERE username = "'+ application.User.Username +'"');
end;

In the main forms OnShow event the following code is used. Note, if a default time is set in the database for all users, the Try...Except....End construct is not needed.  Without this as the database and code currently stand, you will get an error informing you that datetime cannot be ''''' if no time has been saved to the database.


try
     frmAutoCloseset.dtCloseSpanBegin.DateTime := strToDateTime(SQLExecute('SELECT closeStart FROM _user WHERE username = "'+application.User.Username+'"'));
     frmAutoCloseset.dtCloseSpanEnd.DateTime := strToDateTime(SQLExecute('SELECT closeEnd FROM _user WHERE username = "'+application.User.Username+'"'));
     frmMain.lbTimeClose.Caption :=  frmMain.lbTimeClose.Caption + TimeToStr(frmAutoCloseSet.dtCloseSpanBegin.DateTime);
   except
     frmAutoCloseset.dtCloseSpanBegin.DateTime :=  Time;
     frmAutoCloseset.dtCloseSpanEnd.DateTime := (Time + 1);
     frmMain.lbTimeClose.Caption :=  frmMain.lbTimeClose.Caption + ' ';
   end;

107

(47 replies, posted in Script)

Kofa,


Your problem is there is no such property Current Row available in MVD. What might work (and I haven't tried it) is:


Form1.Edit1.Text:=Form1.TableGrid1.Cells[Form1.TableGrid1.SelectedRow,5]

or if you have clicked on a row then simply in the click event

Form1.Edit1.Text:=Form1.TableGrid1.Cells[ARow,5]

108

(5 replies, posted in General)

Alan,

If you look at your script file before you have entered everything you'll see the following.

var
  sHello: string;  // delete this

procedure HelloWorld (s: string);  //delete this procedure, you'll never use it.
begin
  ShowMessage(s);
end;

begin
  // just for example 
  sHello := 'Script said hello!';    //here is where you put the code for your login form if using the default form.
  HelloWorld(sHello);
end.

So here here is what your script file will look like before you start adding your own events etc.

begin
  lbYourLabel := TLabel.Create(frmdbCoreLogin); //Whatever component must have component.create(frmdbCoreLogin)
  lbYourLabel.Left := 113;
  lbYourLabel.Top := 170;
  lbYourLabel.Width := 300;
  lbYourLabel.Height:= 15;
  lbYourLabel.Margins.Top :=10;
  lbYourLabel.Margins.Left :=10;
  lbYourLabel.Margins.Right :=10;
  lbYourLabel.Margins.Bottom := 10;
  lbYourLabel.Parent := frmdbCoreLogin;  //component.parent must be attached to frmdbCoreLogin
  lbYourLabel.Wordwrap := true;
  lbYourLabel.Caption := 'image copyright free from unsplash.com/photos/jXd2FSvcRr8';
  lbYourLabel.Visible := True;

  frmdbCoreLogin.Caption := 'MY Login form';
end.

109

(5 replies, posted in General)

asawyer13,

It is possible to add extra buttons and edit boxes to the inbuilt login form, see below.  You could also create your own two user and roles table and then you are free to do whatever you want.

Another way you could do this is to enable users and roles - this will create the database and then disable the feature. This would create the database tables for users and roles, however you will be completely responsible for not only the login form but also for checking roles etc.


To add to the current form this is what you need to do, my example is placing a label. Note positioning items is through trial and error.

In the default begin....end place code similar too.


lbYourLabel := TLabel.Create(frmdbCoreLogin); //Whatever component must have component.create(frmdbCoreLogin)
  lbYourLabel.Left := 113;
  lbYourLabel.Top := 170;
  lbYourLabel.Width := 300;
  lbYourLabel.Height:= 15;
  lbYourLabel.Margins.Top :=10;
  lbYourLabel.Margins.Left :=10;
  lbYourLabel.Margins.Right :=10;
  lbYourLabel.Margins.Bottom := 10;
  lbYourLabel.Parent := frmdbCoreLogin;  //component.parent must be attached to frmdbCoreLogin
  lbYourLabel.Wordwrap := true;
  lbYourLabel.Caption := 'image copyright free from unsplash.com/photos/jXd2FSvcRr8';
  lbYourLabel.Visible := True;

  frmdbCoreLogin.Caption := 'MY Login form';

110

(3 replies, posted in General)

Are the comboboxes getting their data from the same field/column in the database or from one table but different fields?

To give users a warning that the program is about to close add this line between ClearLgs and frmMain.Close.

MessageDlgTimeOut('Closing program','WARNING',1,10000);


The flaw with this code at the moment, is that it needs to be set each time the program is started, So the start... finish times either need to be entered into a table or added to the settings.ini file or as a registry entry.

I've hit a problem where users are forgetting to close the program when they leave work. This is partly due to the fact the IT department forbid PC's from being shutdown and must only go to screenlock.

Here is my code for people who would like to fiddle or use it as is in their own program. There is a time span during which the program will automatically close. This is to allow for some flexibility in the event someone stays later or doesn't finish on time.

It also allows for someone staying back to still use the program if they forget to untick the timepickers, it will just close during the timespan but not afterwards.

The call to the procedures are run in a timer called every 20 seconds at the moment. The reference to 'ClearLogs' is a procedure that deletes the user from the database tables user log entry.

The auto close code:

procedure AutoCloseSet;
var
    TmeCompare : string;
begin   {if timedate pickers are unchecked, this code is ignored}
    if (frmAutoCloseSet.dtCloseSpanBegin.Checked) or (frmAutoCloseSet.dtCloseSpanEnd.Checked) then
    begin
       TmeCompare := TimeToStr(Time); //Time now
       if (TmeCompare > TimeToStr(frmAutoCloseSet.dtCloseSpanBegin.DateTime)) and  (TmeCompare < TimeToStr(frmAutoCloseSet.dtCloseSpanEnd.DateTime)) then
       begin
         ClearLogs;  //delete user from user logs table
         frmMain.Close;   //close the program
      end;
    end;
end;

The set up form has two date time pickers where the user can choose their own time span for auto close or untick the option all together.

This form has:

procedure frmAutoCloseSet_OnShow (Sender: TObject; Action: string);
begin   {Add one hour onto begin time span when form first opens. This is to prevent the possibility of Autoclosing before time has beenset}
    frmAutoCloseSet.dtCloseSpanBegin.DateTime := frmAutoCloseSet.dtCloseSpanBegin.DateTime + EncodeTime(1,0,0,0);
end;

The timer code:

procedure OnTimer;
begin

     iSeconds := iSeconds + 1;
     
     AutocloseSet;
     if iSeconds > 30 then
     begin
       // other code here requiring timer
          iSeconds := 0;
     end;
end;

Timer set up in main form onshow:

 Timer := TTimer.Create (frmMain);
     Timer.Interval := 20000;
     Timer.Enabled := True;
     Timer.OnTimer := @OnTimer;

Hope that might be useful for someone.

113

(47 replies, posted in Script)

There are two ways of centering a header.

1. (and the easiest)  use the options in settings for the tablegrid as per image attached.


2. In script   Form1.TABLE.columns[column number].Header.Alignment := taCenter;

114

(7 replies, posted in Script)

Kees,


Quite simply Derek's program shows you how to use the application.user.xxxxx . In his example he has attached them to a label, you could instead display them in a form caption or an edit box.


Your question was , "How can I present user data on a form?", and Derek's program shows you one way of doing this. I assume you have run his program.


I take it from your question, that you are wanting to do more than just display a user on a form or are you wanting display a selection of users?


I suggest if you need an answer closer to your requirements either attach your program so far to a post and state what it is you are hoping to achieve or explain more precisely what it is your are trying to do.

115

(2 replies, posted in SQL queries)

Zahar2002,


Search the web for a program called DyBase, it doesn't appear to be supported anymore, the website and instructions are in Russian, but it is similar to MVD but purely for Access databases.

Here is an example from my program:


procedure frmMain_tgOrders_OnChange (Sender: TObject);
CONST
    DATE_ORD = 5; DATE_PO = 7; DATE_REQ = 8; ORD_QTY = 9; ORDER_REC = 10; DUE = 11;
var
row, column, rowcnt, colcnt: integer;
begin

   rowcnt := frmMain.tgOrders.RowCount -1;
   colcnt := frmMain.tgOrders.Columns.Count -1;

   frmMain.tgOrders.BeginUpdate;
   for row := 0 to rowcnt do
   begin
       if frmMain.tgOrders.Cells[DUE,row] = '0' then     //Complete order received colour red/pink
       begin
           for column := 0 to colcnt do
           begin
               frmMain.tgOrders.Cell[column,row].Color := $00BDA8FD;
           end;
      end
      else
      
      {Part order received   colour Blue}
          if (frmMain.tgOrders.Cells[DUE,row] < frmMain.tgOrders.Cells[ORD_QTY,row])    then     //Complete order received
           begin
               for column := 0 to colcnt do
               begin                                       //light blue
                   frmMain.tgOrders.Cell[column,row].Color :=$00FFFFA8; // interesting brown $0065AACD;
               end;
          end
    
      else
    
        {Quote pending colour green}
          if (frmMain.tgOrders.Cells[DATE_REQ,row] <> '') AND (frmMain.tgOrders.Cells[DATE_PO,row] ='') then
           begin
               for column := 0 to colcnt do
               begin                                          //light green
                   frmMain.tgOrders.Cell[column,row].Color := $00B4F2B6;
               end;
          end
    
      else
    

    {To be ordered colour yellow}
    if  ((frmMain.tgOrders.Cells[DATE_ORD,row] = '')AND (frmMain.tgOrders.Cells[DATE_PO,row] ='') AND (frmMain.tgOrders.Cells[DATE_REQ,row]= '')) then
       begin
           for column := 0 to colcnt do
           begin                                          //light yellow
               frmMain.tgOrders.Cell[column,row].Color := $0080FFFF;
           end;
      end;

   end;
  frmMain.tgOrders.EndUpdate;

end;

117

(4 replies, posted in Script)

SQLExecute(INSERT INTO sal (books) VALUES ("'+form2.ComboBox2.Text+'")');

118

(4 replies, posted in General)

Here you go Unforgettable.


This program is one I use to test out things.   All you need to look at is the drop down box. I have used the code in the 'On Close Up' event.

You could if you wished put the calling code in the 'OnClick' event or even have a button with the calling code in.


To use, just type a word into the drop down box without opening the drop down. It will then appear in the table grid and also in the drop down list after you have clicked outside the combobox.

119

(6 replies, posted in General)

I can't get the above code to work for me.


I am using the Login form and have inserted the above code in the global begin....end.


It doesn't matter if I have the code at the beginning or end of the code block, what I get on startup is the message telling me the program is already running, even on first instance.  It then goes on to open the login form and opens the main form.

If I move the code into my Mainfrm.show  it ignores the code completely.


begin

   frmdbCoreLogin.Caption := 'Workshop Parts Login';

   {logo is copyright free from  https://unsplash.com/photos/jXd2FSvcRr8 }
 frmdbCoreLogin.Image1.Picture.loadfromfile((ExtractFilePath(Application.ExeName)+ 'WOS_login.jpg'));

 if FindWindow(nil, 'workshopPartsDB') <> 0 then
  begin
     showmessage('already running');
     frmdbCoreLogin.Close;
  end;

I have even tried :

if FindWindow(nil, ExtractFileName(Application.ExeName)) <> 0 then
  begin
     showmessage('already running');
     frmdbCoreLogin.Close;
  end;

And that doesn't work at all!


I have just had a further fiddle and checked the result of the FindWindow function, and, it is always 0, so no wonder the code doesn't work.

I'm running on Windows 10 64bit.

120

(4 replies, posted in General)

unforgettable,


By editable do you just want to be able to add items to the combobox or edit them as well?

To add an item directly to the combobox:


 { Function to check if  combobox has had a new item added to it}

 frmEditPart.cmbEditCategory.dbItemID := add2ComboBox(frmEditPart.cmbEditCategory.text, frmEditPart.cmbEditCategory.dbItemID);



{function to allow selected comboboxes to have new data added to them directly}


function add2ComboBox (Sender: String;  indx: Integer): Integer;
begin
   if (indx = -1)  AND (Sender <> '') then
       begin
         SQLExecute('INSERT INTO table (field) VALUES ("'+Sender+'")');
         UpdateDatabase('TABLE');
         Result := Last_Insert_id;
         showmessage('TABLE updated with '+Sender )
      end
      else begin
       Result := indx;
   end;


end; 

121

(7 replies, posted in Script)

Does this help?


Login Form attributes.

Form = frmdbCoreLogin

Form Components:
Image1  = picture
bLogin  = login button
pnPassword =
edPassword = password edit box
pnLogin
edLogin = login edit box

frmdbCoreUserForm.ShowModal;
frmMain.mniChangePassword.click;
frmdbCoreUserChangePwd.show;
frmdbCoreUsers.ShowModal;
frmMain.mniUsers.click;

frmdbCoreLogin.Caption:=strCaption;  
 frmdbCoreLogin.Image1.Picture.LoadFromFile(ExtractFilePath(Application.ExeName)+'Images\logo.png');    //load custom image
 
 Application.User.id;
Application.User.Username;
Application.User.Email; 
Application.User.First_name; 
Application.User.Last_name; 
Application.User.Role; 
Application.User.RoleId; 
Application.User.is_admin; 
Application.User.is_active;
Application.User.is_logged; 
Application.User.Last_login; 
Application.User.Date_joined;
 

122

(5 replies, posted in Script)

Hi salahnecibi,



If you have table grid then try something like this.



procedure frmMyForm_grdTableGrid_OnCellClick (Sender: TObject; ACol, ARow: Integer);
var
    id: integer;
begin
   id := (frmMyForm.grdTableGrid.dbItemID); // Get ID

   id := id + 1; //increment ID

// use this if you want to fill the edit box before you do the database search
  frmMyForm.edtEditBox.Text := intToStr(id);  

 // use this if for some reason if you want to keep th eID number for use elswhere in your program
   frmMyForm.edtIDEditBox.Text := sqlExecute('SELECT id FROM TABLE WHERE id="'+intToStr(id)+'"');
end;

If you are not using a table grid then just shout and alternative code can be provided.

123

(4 replies, posted in General)

Papafrankc,


I don't have an answer to your problem but, I think once you have solved the problem your end users will not see this, but each time you compile the program you might have to recheck all your drop down boxes before distributing your program.



As an example my project suffers from two annoyances.


1. A group box and labels keep moving each time I compile the program.
2. My date time pickers like to untick themselves between compilations.

So I have to test to make sure after I have added a new form or script code that these items are reflecting what I want before I recompile.

I suspect your dropdown box problem may well require a similar approach.

124

(4 replies, posted in General)

Is this a PDF link saved in a database?

If it is the following code relies on Windows associating file types and will automatically open the correct program.

procedure frmMain_btnOpenPDF_OnClick (Sender: TObject; var Cancel: boolean);
var
  fName :string;
begin
  fName := SQLExecute('SELECT DISTINCT File_Filename FROM SomeTable WHERE id = '+frmMain.tgTable.SQLValue);
  OpenFile(fName); 


Alternatively if you only ever want to open a PDF file then the above becomes



var
  fName :string;
begin
  fName := SQLExecute('SELECT DISTINCT File_Filename FROM SomeTable WHERE id = '+frmMain.tgTable.SQLValue);
  OpenFile(fName,'AcroRD32.exe'); 

If you are not getting the file name from a database link, just substitute the fName :=  with path and file name of the file you want opened.  Obviously you could add in an OpenDialog if you want the user to search for a file or have an edit box for the user to fill out a name etc.

125

(3 replies, posted in Russian)

Согласно StackOverflow, единственный способ сделать текст в окне сообщения или диалоговом окне сообщения жирным шрифтом - это создать новый класс или создать собственное окно сообщения.


Основные шаги создания такой формы:
1. создать новую форму
2. Добавьте метку и две кнопки
3. Установите для надписи жирный шрифт.
4. добавить обработчик к обеим кнопкам, закрыв форму и установив какое-то свойство, для которого была нажата кнопка.


https://stackoverflow.com/questions/225 … messagebox



According to StackOverflow the only way you can make the text in messagebox or messgedialog bold, is to either create a new class or design your own message box.


The basics steps of creating such a form:
1.Create a new form
2.Add a label and two buttons
3.Set the label font to Bold
4.add handler to both buttons, closing the form and setting some property for which button was pressed.

https://stackoverflow.com/questions/225 … messagebox