1

(1 replies, posted in SQL queries)

Greetings to all. I have a button with SQL query. The problem is when to specify a search on a field with numbers.

WHERE                                            
    (
        ({Edit3} = '' OR PReg.PSum >= {Edit3}) AND
        ({Edit4} = '' OR PReg.PSum <= {Edit4})
    )

constant error that the syntax is not valid for MySQL.

i tried

(
        (IFNULL({Edit3}, '') = '' OR PReg.PSum >= IFNULL({Edit3}, 0))
        AND 
        (IFNULL({Edit4}, '') = '' OR PReg.PSum <= IFNULL({Edit4}, 999999999999))
    )

but the same thing.

Maybe someone has an example of a SQL query using a request for numeric (more and/or less), dates (more and/or less), checkboxes. Because when I don't have certain fields filled in on the search form, the request gives a constant error about incorrect syntax.

Or maybe it is better to do it through a script in the program to additionally control the conditions. But how is it correct to edit the selected record after filling the table?

2

(6 replies, posted in General)

Thanks a lot for your help Sparrow & derek. Got it figured out. it's just that the data fill/filter function call must be done before the form translation code. Once again, thank you very much for your help.

3

(6 replies, posted in General)

Thank you sparrow, derek for the quick reply. However, I think I missed an important point. My program uses a login replacement window from a related topic. I also have a project on MySQL

Part of my login window code

function GetCombo: TdbComboBox;
var
  i: integer;
begin
  for i := 0 to frmdbCoreLogin.componentCount - 1 do
  begin
    if frmdbCoreLogin.Components[i] is TdbCombobox then
    begin
      Result := TdbComboBox(frmdbCoreLogin.Components[i]);
      Result.dbFilter := 'is_active = 1';
      exit;
    end;
  end;
end;

procedure Login_OnClick( Sender:TObject; var Cancel:boolean );
var
  tmpMD5: string;
  tmpUsername: string;
    begin
  if frmdbCoreLogin.edLogin.Visible then
    tmpUsername := frmdbCoreLogin.edLogin.Text
  else
    tmpUsername := GetCombo.Text;
  tmpMD5 := StrToMD5( frmdbCoreLogin.edPassword.Text + tmpUserName );
  if SQLExecute('SELECT count(*) FROM _user WHERE username = "'+tmpUserName+'" AND password = "'+tmpMD5+'" ') = 0 then
    MessageBox('Invalid login or password','Error', MB_ICONWARNING + MB_OK )
  else
  begin
   SendMessage( frmdbCoreLogin.bLogin.handle , wm_LButtonDown, 0, 0);
   sleep(100);
   SendMessage( frmdbCoreLogin.bLogin.handle , wm_LButtonUp, 0, 0);
 end;
end;

procedure Init;
var
  tmpLoginButton: TdbButton;
begin
  tmpLoginButton := TdbButton.Create( frmdbCoreLogin );
  tmpLoginButton.Parent := frmdbCoreLogin;
  tmpLoginButton.Top := frmdbCoreLogin.bLogin.Top;
  tmpLoginButton.Left := frmdbCoreLogin.bLogin.Left;
  tmpLoginButton.Width := frmdbCoreLogin.bLogin.Width;
  tmpLoginButton.Height := frmdbCoreLogin.bLogin.Height;
  tmpLoginButton.Caption := 'Entry';
  tmpLoginButton.Font := frmdbCoreLogin.bLogin.Font;
  tmpLoginButton.Default := True;
  tmpLoginButton.OnClick := 'Login_OnClick';
  frmdbCoreLogin.bLogin.Visible := False;
end;

4

(6 replies, posted in General)

Hello everyone. Maybe someone uses the standard login form and knows how to hide inactive users from the combobox?

5

(5 replies, posted in General)

And thanks again for the tips and care. It worked, but again got stuck on the data sample. That is, I need to "copy" into the temporary table only those data that are selected in Tablegrid. Any tips on how to do this? I tried this way

for i := 0 to Form1.TableGrid1.RowCount - 1 do
  begin
    SQLExecute('INSERT INTO IntermediateTable (PayeeSurname, Payment) VALUES (''' + Form1.TableGrid1.Cell[3, i].AsString + ''', ' + IntToStr(Trunc(StrToFloat(Form1.TableGrid1.Cell[4, i].AsString) * 100)) + ')');
  end;

but I understand that it is somehow broken.

6

(5 replies, posted in General)

Thank you for your reply. I have already tried a hundred versions of the script, but the error is always the same. could not convert variant of type (array variant) into type (integer).

7

(5 replies, posted in General)

Greetings to all fans of a cool tool for making wishes come true. Maybe there are active gurus who can help. It is necessary to create an export procedure (I already borrowed it). It should download only those data that are selected (by shift, for example, or filtered by search) from TableGrid. But the problem is that the first line of the file must contain the sum of the downloaded data and the number of downloaded lines. There is no way to write this summary line to a file.
Help, please.

8

(11 replies, posted in General)

sparrow wrote:
... wrote:

It's all about the formula for checking the correctness of entering the account relative to the control amount. It is necessary to operate with all symbols (31).


I will repeat to you once again that checking in DELPHI and other languages that cannot operate with very large numbers (in our case up to 31 digits) does not require converting the entire number and is performed on a string of characters.


Your code in DELPHI will not work.
How to do this in DELPHI is described in the article at the link I gave you above. In addition, this non-working code also contains a calculation error.

Infinite gratitude for help and advice. Thank you for pointing out my inattention.
I knew about the limitation of variables, I just gave as an example how I perform mathematical operations.
Thank you very much.

The finished code is below.

function CalculateIBANMod97(const IBAN: string): Integer;
var
  D, N: string;
  Index, Len: Integer;
begin
  D := Copy(IBAN, 3, Length(IBAN) - 2) + '1011'+ Copy(IBAN, 1, 2);
  N := Copy(D, 1, 9);

  for Index := 10 to Length(D) do
  begin
    N := IntToStr(StrToInt(N) mod 97) + Copy(D, Index, 1);
  end;

  Result := StrToInt(N) mod 97;
end;

procedure frmAddPayee_Edit3_OnExit (Sender: TObject);
var
  IBAN: string;
  Mod97Result: Integer;
begin
  IBAN := frmAddPayee.Edit3.Text;
  Mod97Result := CalculateIBANMod97(IBAN);
  ShowMessage(IntToStr(Mod97Result));
end;

9

(11 replies, posted in General)

pavlenko.vladimir.v wrote:

I don't understand at all:
Why copy the characters, I don’t see a continuation.
Why check IBANverify if its value will always be the same.

I'm checking my account against the checksum. Attached the full calculation.

sparrow wrote:

Why do you need to convert all the characters into numbers and what type of IBAN verification do you want to do?

It's all about the formula for checking the correctness of entering the account relative to the control amount. It is necessary to operate with all symbols (31).

10

(11 replies, posted in General)

sparrow wrote:

I don’t know what’s on the forums, but in the DELPHI Basic Tutorial it says:

  Min int64 value = -9223372036854775808
  Max int64 value = 9223372036854775807

http://www.delphibasics.co.uk/RTL.php?Name=Int64

Oh, only 19 characters up to 9223372036854775807. What can be done in my case? Will MVD not be able to handle this situation?

11

(11 replies, posted in General)

Please see an example...frmAddPayee_Edit3_OnExit

12

(11 replies, posted in General)

In the program, I write the code for conversion and verification of the IBAN of the account. In it, I operate with values of 31 characters. When executing StrToInt64 (1234567890123456789012345678901) gives an error: "1234567890123456789012345678901" is not valid integer value.

I read many forums and tips. Everywhere it says that it should work. What can be done about it?

13

(3 replies, posted in General)

derek wrote:

Hi,
The short answer to your question is 'no, you don't need to store the date in a text field'.
SQLite doesn't have a 'type' for 'date/time' - in MVD, dates and times are actually already stored as text and are then converted by the in-built date / time functions of SQLite at run-time.
What you actually 'see' on screen and what is stored depends on how you have defined it in your data schema.
If you have chosen 'date' in your schema then when you save a record, the date component is stored and the time component defaults to 00:00:000.
If you have chosen 'time' in your schema then when you save a record, the time component is stored and the date component defaults to 1899-12-30 (which is SQLite's minimum date)
If you have chosen 'date/time' in your schema then when you save a record, both the date and the time components are saved.
Have a look at the attached example and the screen shot showing how the SQLite date/time field type is stored.
Derek.

I have many different dates in my database. More than 100,000 approx. In order not to accumulate these "00:00:00.000" values (which occupy a certain place) in the database in the future, I would like to understand how to properly organize saving from the DateTimePicker.

14

(3 replies, posted in General)

When creating the table, I selected the DATE field type. Also, in the DateTimePicker element, I selected only the date, but when saving the entry to the database, the program always adds the time as well.

Do I need to store the date in a text field? Or maybe I need to save a record using a query?
Please help me to understand these dates.

sparrow wrote:

Something like this

Thank you very much. An interesting solution is to connect the comboboxes through a filter.

I'm trying to figure out how to bypass the searchable property. When setting this property, frequent friezes. Maybe there are good people who can share an option or a possible resolution of the problem, where it is provided that is available for search in ComboBox?

sparrow wrote:

Something like this.


This is fantastic. Thank you very much. Exactly what is needed. I just wanted to understand why I was not getting the grouped data of the last driver. Thank you very much for the detailed example. I will continue to study the features of programming and scripts. And thanks again.

Added a window to display the output result. I can't understand why it doesn't display the first result... The script works, but only from the second time, that is, the first result is empty and all the others are displayed. Accordingly, the last driver is not displayed on the screen.

From this script, I want to get the same result as the SQL-query, but have a more flexible setting in the report.

Thanks for the tip, but I didn't use it. To make it clear what I wanted, I am attaching the оption of solution. This is work with a report and not with a database.

But this solution does not work very correctly. Maybe someone will tell me how to properly organize a script in Fastreport?

I have the following field in a report. Driver [<Report."Driver.Name">] - trip#[<Report."trips.record_count">] in [IIF(Copy(<Report."trips.tripdate">,7,4)>=Copy(<Date>,7,4),'this year ' + <Report."trips.tripdate">,'previous year '+<Report."trips.tripdate">)] visit [IIF(PosEx(',',<Report."trips.countriesvisited">,8)>0,'more than two countries - '+<Report."trips.countriesvisited">,'only two countries - '+<Report."trips.countriesvisited">)] and take [IIF(PosEx(',',<Report."trips.countriesvisited">,8)>0,(<Report."trips.amount">+200),<Report."trips.amount">)]


Below is an image with the text that is displayed when grouping and with the text that should be displayed.

Thanks for the answer. This project that I have attached is an example. In my project there are fields that are calculated when entered for printing in FastReport. Sorry for not giving a complete example... The problem is that I don't know how to group directly into a fast report. I think that a script is needed before printing, which would control the fields on the page. Maybe someone will point to the necessary manual or a similar script.

sparrow wrote:

Something like this

Not just something like this, but exactly like that. Thank you.

Hello again everyone. I cannot group the data by driver in any way. I need all data on the driver to be written in a line. Example:
Driver Dendy - trip#10003 in 11.12.2023 visit Canada,Japan,Norway and take 200; trip#10004 in 02.11.2023 visit United Kingdom,Japan,Norway,Poland and take 500.
Driver Marco - trip#10001 in 27.07.2022 visit United Kingdom, Japan, Poland, Hungary, Canada, United Kingdom, Japan and take 1000.
Driver Terry - trip#10000 in 27.07.2022 visit Sweden, Norway, Portugal, Poland, Japan and take 100; trip#10002 in 12.11.2023 visit Canada, Hungary, Japan and take 150; trip#10005 in 11.12.2023 visit Canada,Romania and take 50.

But with different layouts of fields I get either 3 values for each driver or all six for each separately.
Maybe someone knows how to group values in one line?

My greetings to all users of the MVD. Need help. I found an interesting hack on the forum to fill the textbox with values from the combobox when it is changed. I took it into the project and had problems with filtering by textbox. I searched the forum for options for solving this situation. Did not find any variant as a filling of the many-to-many database. I wouldn't like to change the project structure. In fact, I need to search by a combination of values, not one by one. The field in the database filled with values has a standard separator.

25

(10 replies, posted in General)

Thank you again and thank you 100 times more. With these changes everything works, but rather slowly.