Attaching the file will be helpful as mentioned by Derek, but in the meantime, it might be worth checking your antivirus or firewall is not preventing the program from opening correctly.

Thinking about how to make the connection secure, by which I take you mean the connection string is obfuscated in some way, I came up with the following idea. Not tested, so have no idea if it would work, and is probably more complicated than needs be! smile

1. Create a SQLite database that has just one table and for security about 5 fields.
..... Field 1 contains an encrypted form of the connection path details.
..... Field 2 ........   contains the encryption key spread across one or more fields, the other fields  contain dummy information and or the password
.

2. Before opening the SQL Server connection as demonstrated above, read in the SQLite database contents and perform the deincryption.

3. Parse the results into the actual  db_settings:='Provider=SQLOLEDB;Server=localhost;database=DatabaseName;UID=UserName;PWD=password';
 
To make it more secure, a function could be written that actually changes the encryption key (some sort of randomise function) each time the program is run, This could be placed on the MainForms OnClose event where the new encrypted path and key can be written back to the database. I assume the SQL Server DB would be disconnected at this point as well.

I've probably over thought this far more than is necessary, but if it worked, this idea could also be used for other settings in the ini file such as column widths in tablegrids etc.

The other option would be to have the encryption or password key in plain sight, but looking like an encrypted  string.

28

(7 replies, posted in Script)

I have an auto/manual log out function which I've attached below.  I came up with this because the SQLite DB is on a mapped drive and the IT department have a periodic cache scraper programme running. This plays havoc with SQLite cuasing users to either be logged out or never logged out even after they have closed the program. Obviously SQLite is not designed to run on mapped/shared drives.


I have an extra table called user_log  which contains logging on time and last logged in time.

//Forced logout by user.


procedure frmMain_btnLogOut_OnClick (Sender: TObject; var Cancel: boolean);

begin

   ClearLogs;

   MessageDlgTimeOut('You have logged out'+#13#13+' Program will CLOSE in 4 seconds','LOG OUT INFORMATION',0,4000);
  
   frmMain.Close;
end;

//Clear Logs


//user_log
var
  logged_in : boolean = False;

procedure ClearLogs;
begin
    SqlExecute('DELETE FROM user_log WHERE username = "' + Application.User.Username + '"');
end;

Combined with this I also have an auto program close for each user (they can set their own time span), as people were going home and not closing the program down causing major database corruption.

Мне интересно, почему в вашем коде для создания динамической формы (или других объектов) вы не «освобождаете» экземпляры при закрытии формы.

Я заметил, что MVD не делает этого с собственным созданием форм, они просто складываются, когда не используются, как скрытые.

Процедура есть как часть TObjectClass(). FreeAndNil, кажется, тоже работает, по крайней мере, компилируется.





I'm wondering why in your code for creating a dynamic form (or other objects) you don't "free" the instances when the form is closed.

I've noticed that MVD doesn't do this with native form creation, they just fold up when not in use and become hidden.

The procedure is there as part of TObjectClass(). FreeAndNil seems to work also, at least it compiles.

This works.

procedure createf (Sender: TObject; var Cancel: boolean);
var
 frm:TForm;
begin
 //   Frm := TForm.Create(Form1);   // or  
   Frm := TForm.Create(Application);
  Frm.ShowModal;
end;

31

(2 replies, posted in Script)

Use the upper or lower case function Uppercase() or LowerCase(), either when you first enter the hash number into your database or run the sHash variable through it  .

sHash := UpperCase(sHash)

You could also run the edit1.text through the function instead.

32

(7 replies, posted in Script)

identity wrote:

I got error for this script.

What error did you get? There should be an extra END;  at the bottom of the script, which I didn't put in.

33

(6 replies, posted in General)

begin
   form1.color:= clGray;  //whatever default colour you want the form to be
   
   if form1.CheckBox1.Checked := True then
   begin
       form1.CheckBox2.Checked := False;  //make sure you don't have both boxes checked
      form1.color := clBlue;
   end
   else if
   begin
     form1.CheckboxBox2.Checked := True then
     form1.CheckBox1.Checked := False;
     form1.color := clred;
   end;
    

The above allows the form to keep it's default colour if no checkbox is ticked.

If you wished, in the form OnClose event, you could untick both checkboxes as above so that if the form is called again, everything is in it's default state.

34

(7 replies, posted in Script)

You could do something like this.

Procedure something;
var
    
    lngth : integer;
begin

  lngth :=  Length(Form1.Edit1.text); //check how many digits have been entered

  if lngth <> 10 then
   begin
     messageDlg('Personnel Number  must be 10 digits ',mtError, mbCancel, 0); //your choice of message and buttons
     Form1.Edit1.SetFocus; // Make the edit box the focus - so the correct number can be typed in
   end;
   

35

(2 replies, posted in General)

I think all you need is the opposite function to the one you used to encode the database.

It would only work for your database though .

I've never been able to get the MVD DecryptRC5 to work for me though, it always crashes the program.

36

(8 replies, posted in Russian)

Here is a link to a fastscript forum concerning the use of TfsXMLDocument, they came to the conclusion it is better to use OLE  Microsoft.XMLDom.

http://forums.blumentals.net/viewtopic. … amp;t=7169

Thread:   http://forums.blumentals.net/viewtopic. … 169#p24988

Generally speaking, you could export the current database in CSV format and then import into the new database. If the new fields are to the right of the old fields (so to speak), you should be able to just import the records so long as the old field names have not been changed.

The Export and Import function provided in MVD under options should do the trick.

38

(8 replies, posted in Russian)

Sounds interesting.

39

(4 replies, posted in General)

Is Tax rate actually being filled? Try changing  Tax from a double to (temporarily) Int or Var putting in a

TaxRate := sqlexecute('select TaxRate from TaxRates where id = '+frmRevenue.cbTaxRate.sqlvalue);
showmessage((InttoStr(taxrate));

or "varToStr


If TaxRate is not getting data assigned your next line will fail as you would be dividing zero by 100 (0/100) which will cause an error.  The declaration of Tax as a double might also be causing a problem in MVD

40

(5 replies, posted in General)

This was the article I was thinking of.

https://createmyvisualdatabaseapp.blogs … -post.html

41

(5 replies, posted in General)

I think you need to have a look at K245 posts in the Russian section, his latest 'tutorial' address that kind of thing using MVD.

Were you thinking of this? I posted parts of this on the forum previously.


Если вы подумали об этом, я ранее публиковал часть этого на форуме.



function CountBackups(dir: string) : string;
var
  fileList : TStringList;
 // count : integer;
begin
   result := '0';
   fileList := TStringList.Create;
   fileList.Text := GetFilesList(dir, '*.db',False);
   result := intToStr(fileList.Count -1);                                                                       

   fileList.Free;

end;
procedure frmMain_OnClose (Sender: TObject; Action: string);
begin
   
     CopyFile('Test.db', 'backup/backup '+ FormatDateTime('dd-mm-yyyy hh-nn-ss', now)+'.db');  
    dbBackup(b);
  
     Timer.Free;
     
end;
procedure OnTimer;
begin

     iSeconds := iSeconds + 1;
     frmMain.lbCounter.Caption := ' '+intToStr(iSeconds);
     AutocloseSet;
     if iSeconds > 30 then // backup every 3.5 hours (14400 seconds)
     begin
         // dbBackup(b);
          dbUpdateTimer;  
          iSeconds := 0;
     end;
end;

procedure dbBackup(d: string);
 var
  z : boolean;
begin

    z := ForceDirectories(d);

    if z then
       CopyFile(dbName, d + '/WOS_backup '+ FormatDateTime('dd-mm-yyyy hh-nn-ss',now)+'.db')
    else
      messageBox('Folder '+d +' does not exist', 'Backup Folder', 0);

   frmMain.lbFileCount.Caption := CountBackups(d);

end;
procedure frmMain_OnShow (Sender: TObject; Action: string);
var
b,y :string;
begin

   b :=  ExtractFilePath(Application.ExeName);
   y :=  b;
   b := b + 'backup\backup ' + dtToday;
   y := y + 'backup\backup ' + dtYesterday;
   //CreateDir(y); // this is required to stop file does not exist message on first open
  { if y < b then
     DeleteDB(y); move this to onClose}

    dbBackup(b);
  
//global code
var
  Timer : TTimer;
  iSeconds : integer;

Do you need to store the calculations in the database or just view them?

If just viewing you will need to write a 'calculated field' entry. This means everytime you view the record the time will be calculated on the spot as you look at the record.

To do this on the database setup page find the table that has the start and finish times and make a new calculated field:


Field Name:   timings

strftime(%s, TABLE_NAME.your_field_finishtime) - strftime(TABLE_NAME.your_field_starttime)

A way papafrankc is for the duplicate test to convert all the text to either uppercase or lowercase.

UpperCase(s:string): string;  or LowerCase(s:string): string;

45

(12 replies, posted in General)

Go to the Russian part of this forum and look for K245 he has just written up on how to turn an image of some kind in to operating like a button.

https://createmyvisualdatabaseapp.blogs … /ui-1.html

The website is in Russian. You will need to either have Google page Translate installed in your browser or cut and paste into Google Translate.

46

(16 replies, posted in General)

haruna wrote:

HELLO CDB

I'm still around.

47

(6 replies, posted in General)

If your modem uses the AT command set, I would think it possible.

There is a large project on here somewhere that sends SMS, I think was called iAPPt

papafrankc,

If you are taking a typed in date from a memo field  and want to make it an actual date from MVD/Pascal point of view you need to use strToDate(Form.Memo.Text) might also be strToDate(Form.Memo.Lines[line number]) or DateToStr if taking a date and placing it into a memo field.

Ах я понимаю спасибо

You will need to do this using Script.

In the AfterClick event of your delete button you will need to run the deletefile function.


//Note not tested.

procedure frmYourFormName_Button1_OnAfterClick (filetext : string);
var FileName : string;
begin
  FileName := filetext;
  if FileExists(FileName) then
  begin
     DeleteFile(FileName);
  end
  else
    MessageBox('File ' + FileName + 'does not exist ','Delete Error ' , MB_OK+MB_ICONERROR);
end;

There are at least a couple of ways on how to pass the filename to the Button event.

First is to have a label or textedit that has its Visible property set to false and write the SQL to populate the label Caption or the Text of an edit text and then pass that to the filetext parameter.

or call the Button_OnClick event and write the delete SQL code there.

It depends on whether you have already written code to delete the entry in the database or if you are letting MVD do it for you behind the scenes.

var
 localImagePath : string;
ImageId:string;
begin
ImageId := intToStr(frmYour_form_name.your_component_name.dbItemID);

localImagePath := SQLExecute(' SELECT your_database_field_name FROM your_table_name WHERE id="'+ImageId+'"');
frmEdit.text := localImagePath;

// The above code needs to be called before you delete the database entry if you are using the inbuilt delete function of MVD. If you are writing the code yourself for the complete delete function, you could combine the above code into the button click event. Unless you want a universal function to call for other file deletions.
end;