sparrow wrote:

Hi Derek, Roberto


Some fixes and improvements have been made.
Completely (hopefully) fixed typing in color in Edit.


Hello Sparrow, Show de Bola! Here in Brazil we use the expression "Show de Bola" - which has its origins in our football - to say that it was really good! Congratulations and thank you!

I have attached again the project that allows changing the colors of a form and some of its respective controls at run time. Here are some observations:

➤ I used the script developed by Sparrow. Derek's is very good too;
➤ I used Derek's suggestion to create a button to reset the color settings;
➤ I placed the procedure of the same name in the "OnChange" property of TextBox fields, which is below, to correct the error pointed out by Derek (which is an MVD bug), which does not maintain the text color (foreground) in the field TextBox type, when this is changed. It's the solution I managed to find....using part of the code written by Sparrow.
➤ As soon as the forms are opened, they create a record in the tbl_forms table, which will store the colors defined by the end user;
➤ included the option to increase or decrease the font size of form labels and text in textbox and memo fields

procedure OnChange (Sender: TObject);
//*** to fix MVD bug that does not maintain the foreground color when typing
var
     i: integer;
     tmpFrm: TAForm;
begin
       for i := 0 to Screen.formCount - 1 do
       begin
         if TAForm(Screen.Forms[i]).name = frm_custom.Edit_form_custom.text then tmpFrm := TAForm(Screen.Forms[i]);
       end;
       CompLoad(tmpFrm);
end;

Thank you Derek and K245 for your contributions.

4

(5 replies, posted in Database applications)

sparrow wrote:
jrga wrote:

I'm sorry it doesn't work in MVD 5.6....


Supports versions 5.6 and higher

Thankyou!

5

(5 replies, posted in Database applications)

I'm sorry it doesn't work in MVD 5.6....

sparrow wrote:

Hi Roberto,

Let's simplify the script a little.
Something like this


Hello Sparrow! Congratulations, it turned out great! You used 1/3 the number of lines I used in my script to get the same result. I'm glad we have experts like you on the forum. Thank you very much.

Hello everybody. I use MVD 5.6 and I wanted to create a script that would allow the end user to change the color of the application's forms and some of its controls. It was good, but maybe the code could be simplified. I do not currently have a deeper knowledge of MVD to improve the project. Any help to improve it is always welcome.

sparrow wrote:

Hi Roberto.
It needs to be a little different...
It is necessary that the deletion of the table, its creation and filling be done in the "atualiza_overview" procedure. I'll attach the script.


Hi Sparrow, I used the script.pas you sent in the project, uploaded the file and updated the download link in the original post. Thanks again for helping to improve this project. Everyone wins!

sparrow wrote:

Sorry Roberto)

that's exactly what I meant). "Lost"


One more thing. Table "bar_data".
This table is used once to form a chart and is erased to form a new chart.
At the same time, the size of the database is constantly increasing.
Pay attention to this feature of SQLITE as a temporary table.

    SQLExecute('DROP TABLE IF EXISTS bar_data_temp');
    SQLExecute('CREATE TEMP TABLE bar_data_temp (eixo_x TEXT, eixo_y REAL)');
    SQLExecute('INSERT INTO bar_data_temp (eixo_x, eixo_y) ...  '+

Technically, SQLite stores temporary tables in a separate temp database.
It keeps that database in a separate file on disk, visible only to the current database connection.
The temporary database is deleted automatically as soon as the connection is closed.


Such a table does not need to be registered in MVD.
I offer it just for information. Perhaps it will be useful in future projects, and perhaps in this one too.

Hi Sparrow, I converted the graph table to temporary, as you suggested and re-uploaded the file, whose download link is in the original post. Thanks for the suggestions.

jrga wrote:
sparrow wrote:

Hi Roberto,


good job.


"frmOverview.TableGrid1.beginUpdate" was lost in the atualiza_overview procedure.
Adding the lost one will speed up the output of data to the table.

Hi Sparrow, I'll test it. Thanks.


Hello Sparrow! It worked. That is, it accelerated the consultation. Thanks.


procedure atualiza_overview;
//**** aciona geração da consulta e do gráfico de barras
var
    txt_sel, txt_sel1, txt_where: string;
    c,i: integer;
    total_grid: real = 0;
    Results: TDataSet;
    x_value: string;
    cf_y: string;
    y: integer;
begin
    frmOverview.TableGrid1.beginUpdate; //sparrow
....................
...................
...................
    frmOverview.TableGrid1.EndUpdate; //sparrow
end;

P.S.: Looking at the script I found frmOverview.TableGrid1.beginUpdate "lost" and now I understand your message.

sparrow wrote:

Hi Roberto,


good job.


"frmOverview.TableGrid1.beginUpdate" was lost in the atualiza_overview procedure.
Adding the lost one will speed up the output of data to the table.

Hi Sparrow, I'll test it. Thanks.

tcoton wrote:

@jrga
I see in the video that you are running the compiled project with wine on Mac OS, did you develop this project via wine too or did you use a PC/Virtual machine? I have a Mac too and I use virtual machines for Windows stuffs.

Hello tcoton! I used wine itself via playonMac to develop MVD applications on MAC and also on Linux (playonLinux). Please see the link https://myvisualdatabase.com/forum/view … hp?id=8566

hilal wrote:

anybody can be share sample MVD application with a BI tool ??

5 years ago, I created a solution to analyze data, which is part of the attached project and the one in the link https://youtu.be/gUu7wrpQZKY


Not a B.I. and it is light years away from that, but it allows, through a dynamic query, which makes reference to all the project's interrelated tables, to add values, quantities, check the percentage variation, filter by periods, etc.


Contains a simple graph. I called it "Data Crossing". The objective is the same as those that BI seeks: to assist in decision making.


In this project, which I did for my brother, the data was imported from Access and there were blank related fields and that's why I added the option to filter blank fields, but this is unnecessary when the project is built from scratch. Replaces names, addresses and telephone numbers.


Like so many things in MVD, it can be improved.


link for download:

https://drive.google.com/file/d/1kqnN06 … sp=sharing

sparrow wrote:

Hi Roberto


procedure Form1_OnKeyDown (Sender: TObject; var Key: Word; Shift, Alt, Ctrl: boolean);
begin
  if (Ctrl) and (key=107) then showmessage('You press "+"');   // PLUS on NumPad
  if (Ctrl) and (key=109) then showmessage('You press "-"');   // MINUS on NumPad
end;

Hello Sparrow! Happy 2024! Unfortunately it didn't work! My notebook has a keyboard with a specific layout for the Portuguese language (Brazil) and the '+' symbol is on the same key, above the '=' symbol. Maybe that's why your suggestion didn't work...Thanks anyway! I'll try to capture the decimal code of the key via MVD and, if it's right, I'll post the result here.

PS. Now it worked! Thank you again.:

procedure Form1_OnKeyDown (Sender: string; var Key: Word; Shift, Alt, Ctrl: boolean);
begin
     if ((Ctrl) and (key=107)) or ((Ctrl) and (key=187)) then
          showmessage('You press "+"');
     if ((Ctrl) and (key=109)) or ((Ctrl) and (key=189)) then
          showmessage('You press "-"');  
end;


Hello everybody! I've already used several examples of (Ctrl and/or Shift) + key, posted on the forum, but I didn't find Ctrl plus '+' and Ctrl plus '-'. I tried using the codes above, but without success. If anyone can help, I appreciate it.

derek wrote:

Hi Roberto,
If you want to increase / decrease the font size for all the edit, combobox and memo objects on a form, you could also do it something like this (see attached) which should save a bit of typing!
The attached example  uses ALT + A and ALT +D to increase / decrease the font
I sometimes find it useful to change font size, change object colour etc on forms that have a lot of input fields to make it easier for the user to see where they are (but obviously that is more interactive (ie when you actually enter / leave the input fields))
Regards,
Derek.

Hi Derek! You are always helpful! Thank you for simplifying and at the same time expanding the scope of font enlargement and reduction. I find this very useful in my case, as I have some difficulty with my vision, resulting from surgery, and this feature helps a lot. Happy 2024!

procedure frmNumber_OnKeyDown (Sender: TObject; var Key: Word; Shift, Alt, Ctrl: boolean);
begin //*** Proc 905 - aumenta e diminui o tamanho da fonte com teclas de atalho
     if (Key = ORD('A')) and Shift and Ctrl then
     begin
          frmNumber.ComboBox1.Font.size := frmNumber.ComboBox1.Font.size + 1;
          frmNumber.edNumber.Font.size := frmNumber.edNumber.Font.size + 1;
          frmNumber.Memo1.Font.size := frmNumber.Memo1.Font.size + 1;
     end;
     if (Key = ORD('D')) and Shift and Ctrl then
     begin
          frmNumber.ComboBox1.Font.size := frmNumber.ComboBox1.Font.size - 1;
          frmNumber.edNumber.Font.size := frmNumber.edNumber.Font.size - 1;
          frmNumber.Memo1.Font.size := frmNumber.Memo1.Font.size - 1;
     end;
end;

begin
     //*** ATENÇÃO: keypreview também pode ser acionado em PROPRIEDADES
     frmNumber.KeyPreview := True; //*** Proc 905 - aumenta e diminui o tamanho da fonte com teclas de atalho
end.

18

(2 replies, posted in General)

sparrow wrote:

Something like this.

Thankyou

Sparrow, I made the correction. Thanks!

sparrow wrote:

Hi,
You can try it like this


select PRINTF('AMD: %02d %02d %02d',
                        floor( alldays / 365.25 ),
                        floor( mod(alldays, 365.25) / 30.4375 ),
                        floor( mod( mod(alldays, 365.25), 30.4375) ) )
from (select 
    (julianday('now','localtime') - julianday('2022-10-13')) as alldays  ) as t;    

P.S.
Sorry, I didn't check right away.
For a version of SQLite in a program where some functions are not supported, the query is:

select PRINTF('AMD: %02d %02d %02d',
                         alldays / 365250 ,
                         (alldays % 365250) / 30437 ,
                         ( (alldays % 365250) % 30437)/1000 )
from (select 
    (julianday('now','localtime') - julianday('2022-09-03'))*1000 as alldays  ) as t;

Hi Sparrow, thanks for the suggestion. In fact, your instruction is much less complex than the one I showed you. However, my version of MVD is 5.6 and it does not support the "floor" and "mod" functions. I asked Bing's AI, who suggested replacing these two functions with "Castas...integer" and "%". Below is the instruction with these substitutions. Everything works and thanks again.

(select PRINTF("AMD: %02d %02d %02d",
                        cast((alldays / 365.25) as integer),
                        cast(((alldays % 365.25) / 30.4375) as integer),
                        cast((((alldays % 365.25) % 30.4375)) as integer))
from (select id,
     (case when conclusao is null then julianday('now','localtime') - julianday(inclusao) else 
     julianday('now','localtime') - julianday(conclusao) end) as alldays from tbl_subtasks) where id  =  tbl_subtasks.id)

There may be an easier way to do this, but that’s what I was able to create and it works!


(select PRINTF("AMD: %02d %02d %02d", ano,mes,dia) from (
     select id,        
     case when conclusao is null then round((julianday("now") - julianday(inclusao))/365.25-0.5) else 
     round((julianday("now") - julianday(conclusao))/365.25-0.5) end as ano, 

     case when conclusao is null then round((julianday("now") - julianday(inclusao)- round((julianday("now") 
     - julianday(inclusao))/365.25-0.5)*365.25)/30.41-0.5) else round((julianday("now") - julianday(conclusao)- 
     round((julianday("now") - julianday(conclusao))/365.25-0.5)*365.25)/30.41-0.5) end as mes,  

     case when conclusao is null then round(round((julianday("now") - julianday(inclusao)- 
     round((julianday("now") - julianday(inclusao))/365.25-0.5)*365.25))- round((julianday("now") -  
     julianday(inclusao)- round((julianday("now") - julianday(inclusao))/365.25-0.5)*365.25)/30.41-0.5)*30.41-0.5) else  
     round(round((julianday("now") - julianday(conclusao)- round((julianday("now") -  
     julianday(conclusao))/365.25-0.5)*365.25))- round((julianday("now") - julianday(conclusao)-   
     round((julianday("now") - julianday(conclusao))/365.25-0.5)*365.25)/30.41-0.5)*30.41-0.5) end  as dia

     from tbl_subtasks) where id = tbl_subtasks.id)  

I don't know if I understood the question well. I am using a translator. To not display a specific record in a tablegrid, I place it in the tablegrid definition panel, in "3o. Filter (Not required)": id <> num_id and the same thing in the properties of a combobox in "Filter".

tcoton wrote:

That looks very cool, if only we could design this kind of stuff within My visual Database!!


You can use Qlikview in any MVD application! I decided to share my experience for two reasons: 1 - to contribute to the forum from where I gained all my knowledge about MVD, from where I downloaded countless projects, which further enriched my learning. 2 - encourage users to continue using MVD, in view of that he has been discontinued.

I coupled an MVD 5.6 application with a BI tool, which is Qlikview 11 Personal Edition (freeware - link below), according to the video in the link below. Video capture was slow because everything was played on a MicroSD card.


link vídeo = https://youtu.be/PJEo3ch3Dic


I obtained the script below here on the forum, which exports data from the MVD application to a file in CSV format.


I created a dashboard in Qlikview from the CSV file. Below is the script I used in the dashboard, which loads data from the CSV file, which is used to create tables, graphs, etc. in Qlikview,


Qliview's capabilities and possibilities are far above this small example. There are countless tutorials, including videos, on the internet. In addition to the help file (CHM) and the examples that accompany it.


Limitations of the Personal Edition version (taken from the internet): "QlikView Personal Edition is a free version of QlikView for personal use. It is the full QlikView Desktop product and uses the same installation package1. However, there are some limitations and aspects to be observed:


     QlikView Documents: In QlikView Personal Edition, every document is saved with a user key that associates the file with the computer on which it was created1. This means that you cannot use your QlikView documents on other computers, share your QlikView documents with another unregistered user, and cannot open another user's QlikView document1. However, documents created in QlikView Personal Edition can be used with a licensed copy of QlikView Desktop and can also be published to a QlikView Server1.


     File recovery: If you change computers, you will not be able to open documents previously created with QlikView Personal Edition1. In this case, you can choose to recover your files1. QlikView will accept 4 user key changes in a document1. After this, the error message “Key length has reached maximum” will be displayed and the document will no longer open1.


     Support: QlikView Personal Edition users are not eligible for phone or email support from Qlik, but can get excellent support for QlikView from our Qlik1 Community."


Qlikview download link. I downloaded it from the manufacturer's website at the time:
    
https://drive.google.com/file/d/1jeWUs4 … sp=sharing


SCRIPT USED IN THE MVD APPLICATION

procedure frmOverview_bExpCSV_OnClick (Sender: TObject; var Cancel: boolean);
var
   filename: string;
begin
    frm_aviso.Show;
    Form1_bExport; //aciona rotina exportação de lancamento_all_view para arquivo CSV, que será utilizado no qlikview
    filename := 'dashboard_orcamento_jrga.qvw';
    OpenFile(filename);
    frm_aviso.Close;
end;

procedure Form1_bExport;
var Sl : TstringList;
  folder: string;
  TableNames: TDataSet;
  TableCols: TDataSet;
  TableName,ColName,Cols,SelectStmt,ColType: string;
begin
   ProgressBar := TProgressBar.Create(frmMyNotas);
   ProgressBar.Parent := frmMyNotas.pnProgressBar;
   ProgressBar.Width := frmMyNotas.pnProgressBar.Width;
   ProgressBar.Height := frmMyNotas.pnProgressBar.Height;
   ProgressBar.Position := 0;
   ProgressBar.Max := 10;
   Sl := TstringList.Create;
   //SelectDirectory('Select Folder to Export File', './', folder, True);  //Dialog to select folder for which the exported file will be created
   //If Folder = '' then Exit;             // If no folder is selected then cancel the export
   frmMyNotas.pnProgressBar.Visible := True;
   frmMyNotas.lblImpExp.Caption := 'Exporting Database';
   application.processmessages;
   SqlQuery('SELECT name FROM sqlite_master WHERE type="view" and name = "lancamento_all_view"',TableNames); // Retrieve all tablenames from database and load into a dataset
   while not TableNames.Eof do   // Run through each tablename dataset
      begin
        Cols := '';
        SelectStmt := '';
        TableName := TableNames.FieldByName('name').AsString;
        SqlQuery('pragma table_info(' + TableName + ')',Tablecols); // Retrieve column (fields) names for each table
        While not TableCols.Eof do   // Go through each column (field) and concatenate together with comma separation
          begin
             ColName := TableCols.FieldByName('name').AsString;
             ColType := Tablecols.FieldByName('type').AsString;
             If ColType <> 'BLOB' then Cols := Cols + ColName + ','; // Do not select images for exporting
             TableCols.Next;
          end;
        Delete(Cols, Length(Cols), 1);   // Remove ending comma from column list
        ProgressBar.Position := ProgressBar.Position + 10;
        ExportToSl(TableName,Cols,Sl);  // Run Export procedure - pass the tablename and the list of columns to the procedure
        TableNames.Next;  // Go to next table name in dataset
      end;
   Sl.SavetoFile(path_atual+'ExportedData.csv'); // Save the stringlist to a csv file into the specified folder
   ProgressBar.Free;
   frmMyNotas.pnProgressBar.Visible := False;
   frmMyNotas.lblImpExp.Caption := '';
   //ShowMessage('Dados foram exportados para CSV');
   Sl.Free;
   TableNames.Free;
   TableCols.Free;
end;

SCRIPT USED IN QLIKVIEW. Loads data for use with Qlikview graphical objects. The first 10 lines are created automatically. Once the table with the data has been chosen, Qlikview will generate the "LOAD ...FROM" structure

SET ThousandSep='.';
SET DecimalSep=',';
SET MoneyThousandSep='.';
SET MoneyDecimalSep=',';
SET MoneyFormat='R$ #.##0,00;-R$ #.##0,00';
SET TimeFormat='hh:mm:ss';
SET DateFormat='DD/MM/YYYY';
SET TimestampFormat='DD/MM/YYYY hh:mm:ss[.fff]';
SET MonthNames='jan;fev;mar;abr;mai;jun;jul;ago;set;out;nov;dez';
SET DayNames='seg;ter;qua;qui;sex;sáb;dom';

Directory;
Lancamentos:
LOAD TableName, 
     data as "Data",
     tipo_conta as "Iipo Conta", 
     conta as "Conta", 
     categoria as "Categoria", 
     subcategoria as "Subcategoria", 
     categoria &' : '& subcategoria as "Categ.e subcat.",
     cheque as "Nºcheque", 
     grupo as "Grupo fornecedor", 
     fornecedor as "Fornecedor", 
     if(id_tipo_operacao='1','Entrada','Saída') as "Tipo operação", 
     Replace(entrada,'.',',') as "Vlr entrada",
     Replace(saida,'.',',')*-1 as "Vlr saida",
     (Replace(entrada,'.',',') + Replace(saida,'.',',')*-1) as "Valor", 
     Replace(meta_anual,'.',',') as "Meta anual",
     notas as "Notas",
     id_lancamento as "ID lancamento", 
     id_tipo_conta as "ID tipo conta", 
     id_conta as "ID conta", 
     id_categoria as "ID categoria", 
     id_tipo_operacao,
     id_subcategoria as "ID subcategoria", 
     id_grupo as "ID grupo", 
     id_fornecedor as "ID fornecedor",
     checado as "Conciliado" 
FROM
ExportedData.csv 
(txt, utf8, embedded labels, delimiter is ',', msq) 
WHERE len(categoria) <>0;


LOAD data as "Data"
    , year([data]) as Ano
    , month([data]) as Mes
    , day([data]) as Dia
FROM
ExportedData.csv
(txt, utf8, embedded labels, delimiter is ',', msq);

P.S.: in the document settings, in Qlikview, it is possible to create a trigger, which updates the dashboard data, as soon as the QVW file is opened.

I improved this solution that I found here on the forum, which increases or decreases the size of several tablegrids in the same form, whenever the screen resolution is changed (MVD 5.6). As already said in the forum, MVD presents problems with expanding the size of several tablegrids in the same form.

In the image, there is a table containing different screen resolutions and the respective adjustment factors, which will be applied to the width and height of a tablegrid, to increase or reduce its size, depending on the chosen resolution.


//*** armazena altura e largura atual da tela
  form1.Edit_altura_tela.value := screen.height;                                                                                     
  form1.Edit_largura_tela.value := screen.Width;

//*** localiza em tabela altura e largura atual da tela e traz fatores de ajuste em caso de resize
  form1.Edit_fator_altura.value := sqlexecute('select altura_fator from monitorsizes where tela_altura  = "'+form1.edit_altura_tela.text+'"');
  form1.Edit_fator_largura.value := sqlexecute('select largura_fator from monitorsizes where tela_largura  = "'+form1.edit_largura_tela.text+'"');

//*** se altura ou largura não for encontra na tabela, avisa e fecha formulário
  if (form1.Edit_fator_altura.value <= 0) or (form1.Edit_fator_largura.value <= 0) then begin
     showmessage('Tamanho de largura e altera de tela não encontrado - reinicie'); form1.close; end;

//*** converte fatores em percentuais
  form1.Edit_fator_altura.value := form1.Edit_fator_altura.value / 100;
  form1.Edit_fator_largura.value := form1.Edit_fator_largura.value / 100;

................

//ajusta tamanho e posição dos tablegris com base nos fatores e adicionando espaços (variaáveis)
  form1.TableGrid_1.Width  := round(form1.TableGrid_1.width  * form1.Edit_fator_largura.value);
  form1.TableGrid_1.Height := round(form1.TableGrid_1.Height * form1.Edit_fator_altura.value);

  form1.TableGrid_2.Width  := round(form1.TableGrid_2.width  * form1.Edit_fator_largura.value);
  form1.TableGrid_2.Height := round(form1.TableGrid_2.Height * form1.Edit_fator_altura.value);

  form1.TableGrid_3.Width  := round(form1.TableGrid_3.width  * form1.Edit_fator_largura.value);
  form1.TableGrid_3.Height := round(form1.TableGrid_4.Height * form1.Edit_fator_altura.value);

  form1.TableGrid_4.Width  := round(form1.TableGrid_4.width  * form1.Edit_fator_largura.value);
  form1.TableGrid_4.Height := round(form1.TableGrid_4.Height * form1.Edit_fator_altura.value);