Thanks EHWagner,


The code isn't working in Outlook when I tested it today, I just get the HTML as text. However, I discovered a parameter that I will try tomorrow which might just change that.

I read at Microsoft that the oleobject for Outlook includes object.HTMLBody  and I was using object.body.


So, tomorrow when I have access to Outlook, I'll give it a try and see what happens.

127

(10 replies, posted in General)

Hi Kees,


I think Brian means using a file similar to MVD's 'Settings.ini'.

To load a ini file use code similar to:


procedure loadSettings;
var
  settingsIni : TStringlist;
  lngth : integer;
begin
   settingsIni := TStringList.Create;
   settingsIni.LoadFromFile ('Settings.ini');
   dbName := SettingsIni[4];
   SettingsIni.free;
   lngth := Length(dbName) - 7;
   dbName := copy(dbName, 8, lngth);
   FrmMain.lbDbPath.Caption := ExtractFilePath(Application.ExeName)+ dbName;
end;

That code is for loading the standard settings.ini file and finding the name of the database.

To save a file change LoadFromFile to SaveToFile .

128

(31 replies, posted in General)

Papafrankc,

In the code you provided, you haven't assigned the text in your edit box to sKey.

Assuming you have sKey as a string type variable you need -

sKey := formName.EditBoxName.text;

I'm trying to take the contents of a tablegrid and  convert it to HTML for the body of an email.


My problem is that I only seem to get one complete row and the first two columns into the second row into HTML.
I'm practising with a tablegrid that has four columns and five rows.


The code I'm using is below

   sList:TstringList;
begin
         sList:=TStringList.Create;
         sList.Add('<html>');
         sList.Add('<head>');
         sList.add('<style>');
         sList.Add('table, th, td {');
         sList.Add(' border: 1px solid #dddddd; text-align: left; padding: 8px');
         sList.Add('}');
         sList.Add('</style>');
         sList.add('</head>');
         sList.Add('<body>');
         sList.Add('<table>');
         sList.Add('<tr><th>BSuite#:</th>'+ '<th>Part Number</th>' + '<th>Description'+ '</th>'+'<th>Qty'+'</th></tr>');

         for indx := 0 to frmEmail.tgEmailList.RowCount-1 do
         begin
            sList.Add('<tr><td>'+frmEmail.tgEmailList.Cells[0,indx] + '</td>' + '<td>' +frmEmail.tgEmailList.Cells[1,indx] +'</td>'+'<td>'+frmEmail.tgEmailList.Cells[2,indx]+'</td>'+'<td>'+frmEmail.tgEmailList.Cells[3,indx]+'</td></tr>');
         end;
         sList.Add('</table>');
         sList.Add('</body>');
         sList.Add('</html>');

        openURL('mailto:'+frmEmail.cmbEmailAddress.Text+'?subject='+frmEmail.cmbSupplierList.Text+'Order'+'&Body='+sList.text);
sList.Free;

I'm just not seeing why I'm only getting 1 and a bit rows.  This will be going into Outlook, but  my personal email client (emClient) has to have the HTML input manually. My suspicion is that I'm missing an HTML tag, but I can't see where!


Any thoughts gratefully received.

130

(6 replies, posted in General)

Hi Blackpearl8543,


I don't know how to close an MVD program by checking Windows processes as I don't think th ePascal Script allows access to the THandle type.


However, if you have your users 'login' then you can use the following script .


//user_log.pas
var
  logged_in : boolean = False;

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

procedure startLogs;
begin
   If SqlExecute('SELECT count(username) FROM user_log WHERE username = "' + Application.User.Username + '"') > 0 then
     Begin
        MessageBox(Application.User.Username + ' is already logged in.' + #13#10#13#10 + 'If this is not correct, please see your administrator.','Login Problem',MB_OK+MB_ICONERROR);
        frmMain.Close;
     End;
   
   frmMain.lbMainUser.Caption := 'Current User is: ' +Application.User.First_name + ' ' + Application.User.Last_name+'  Role: '+Application.User.Role+'  Last Login: '+DateToStr(Application.User.Last_Login);
   SqlExecute('INSERT INTO user_log (username,Logged_In,isLogged_In) VALUES ("' + Application.User.Username + '","' + FormatDateTime('YYYY-MM-DD hh:nnampm',Application.User.last_login) +'",1)'); 
   logged_in := True;  
end;

procedure frmMain_tgLogged_OnCellDoubleClick (Sender: TObject; ACol, ARow: Integer);
begin
       showmessage(frmMain.tgLogged.Cells[ACol,ARow] +' '+frmMain.tgLogged.sqlValue);
       SqlExecute('Delete FROM user_log WHERE username = "' + frmMain.tgLogged.sqlValue + '"');
end;


begin
end.

You can remove the messagebox code and just go straight to formMain.Close

131

(31 replies, posted in General)

Papafrankc


JB is the man to ask as that is his code snippet.


I'd be wary about saving the serial numbers to a table unless you can encode them (which is possible) as otherwise anyone with copy of SQL Browser or SQL Studio would be able to open the database, read and take your keys.


To save the key to registry all you need is to write:

reg.WriteString('Key', 'sKey');

Assuming that sKey now contains the serial entered via your textbox.

132

(31 replies, posted in General)

papafrankc wrote:

CDB,

So I'm guessing there should be a form called frmNagScreen


Yes


Is there a standard NagScreen form I can use or do I have to create one myself?
Thanks, Frank


You need to create it yourself.  As you are creating the form yourself, you can call it whatever you want, making the appropriate changes in the code to reflect your choice of name.

133

(31 replies, posted in General)

Papafrankc,

I think this needs to be a global constant, so will need to be at the top of the script file, before any procedure or functions.

You can either write:
CONST
   APP_NAME = 'records.exe';

and then in the function   APP_NAME

or

CONST
   APP_NAME = records.exe;

in the nag screen function  'APP_NAME' either should work.


If you copied and pasted JB's code, you might have missed changing some of Jean's frmNagScreen to the name of your own 'nag' forms' name.

PS. Sorry JB I didn't see your reply when I was typing mine.

134

(31 replies, posted in General)

papafrankc,


Did you try substituting APP_NAME  with the actual name of your program, or, make a constant called APP_NAME referring to your program name including the .exe?

A possible but unsatisfactory workaround is to use a try.... except wrap-around.

try
      Outlook := CreateOleObject('Outlook.Application');



    vMailItem := Outlook.GetNamespace('MAPI');

    vMailItem.Logon;
    vMailItem := Outlook.CreateItem(olMailItem);
    vMailItem.Recipients.Add('dibbledabble@somewhere.someplace');
    vMailItem.Subject := 'What a wonderful test email';
    vMailItem.Body := 'This is a test --> how amazing';
    vMailItem.Send;
    Outlook := nil;
    except
     openFile('mailto:?Subject=PURCHASE ORDER PO: 123 &Body= no outlook installed')
 end;

I attempted to use this code suggested by Dmitry -  http://myvisualdatabase.com/forum/viewt … 702#p31702  to determine if Outlook is installed on a users PC.


This fails on two points when compiling.


1.  The type TCLSID  is not recognised.


2. The function CLSIDFromProgID  causes an error 'Undeclared identifier'.


Has this type and function not been included in MVD 6.4, or is there an alternative call?



The code I've written.


function CheckAppInStalled(AValue: String): boolean;
var
    FCLSID: TCLSID;
begin

    Result := (CLSIDFromProgID(PChar(AValue), FCLSID) = S_OK);

end;


procedure Form1_Button2_OnClick (Sender: TObject; var Cancel: boolean);
const
  olMailItem = 0;
var
  
  Outlook: Variant;
  vMailItem: variant;
begin
 
   if CheckAppInstalled('Outlook.Application') then
   begin
      Outlook := CreateOleObject('Outlook.Application');
   
      vMailItem := Outlook.GetNamespace('MAPI');
      vMailItem.Logon;
      vMailItem := Outlook.CreateItem(olMailItem);
      vMailItem.Recipients.Add('dibbledabble@somewhere.someplace');
      vMailItem.Subject := 'What a wonderful test email';
      vMailItem.Body := 'This is a test --> how amazing';
      vMailItem.Send;
      Outlook := nil;
  end
  else begin  // open non outlook installed client
     openFile('mailto:?Subject=PURCHASE ORDER PO: 123 &Body= no outlook installed')
  end;
end;

137

(5 replies, posted in General)

Hi dbk,

First I should note that using the above code you never see your email message, by that I mean the email is created and sent 'behind the scenes', unlike using mailto: or openfile(mailto:) which opens the email create page.

I don't know the answer to the rest of your question. I do know that the Outlook object has a number of item folders that can be searched such as contacts, calendar, email folders.

This link to Microsoft might help https://docs.microsoft.com/en-us/previo … office.11)

or

http://delphi-kb.blogspot.com/2011/06/o … _6280.html

138

(5 replies, posted in General)

In case anyone else would like to know how to send emails where you can't access the information needed to use the SendMail function, here is how I've managed to send an email using Outlook.

This code has been scrounged from StackOverflow where it was scrounged from somewhere else.

procedure Form1_SendEmail_OnClick (Sender: TObject; var Cancel: boolean);
const
  objMailItem = 0;
var
  OKToUse: boolean;
  Outlook: Variant;
  vMailItem: variant;
begin
 // OKToUse := false;


      Outlook := CreateOleObject('Outlook.Application');
    
    vMailItem := Outlook.GetNamespace('MAPI');
    vMailItem.Logon;  {[color=blue]this allows an email to be sent if Outlook is not open at the time of sending[/color]}
    vMailItem := Outlook.CreateItem(objMailItem);
    vMailItem.Recipients.Add('someperson@someplace.something');
    vMailItem.Subject := 'What a wonderful test email'; {[color=blue]this could be a text box with the string contained in it[/color]}
    vMailItem.Body := 'another string or stringlist with the body text';
    vMailItem.Send;
  

  Outlook := nil;  {[color=blue]free the object - this might not be necessary, some sources say it automatically frees when out of scope[/color]}
end;

139

(2 replies, posted in General)

Would this help?

Ignore the SQL, you don't need to do that, the trick is in using MessageDlg function which has both button options and a message capability.

procedure frmEditOrderQty_btnFrmAmendDeleteRecord_OnClick (Sender: TObject; var Cancel: boolean);
 var
 text : string;
 btn :integer;
begin

  
   text := 'ORDER ITEM '+#13#13 + frmEditOrderQty.edtfrmAmendDescription.Text +'  x '+ frmEditOrderQty.edtNewQty.Text;

   btn := messageDlg('CONFIRM DELETION OF '+text,mtWarning, mbCancel+mbOK, 0);

   if  btn  = mrCancel then
      Exit
   else
     begin
       SQLExecute('DELETE FROM orders WHERE orders.id =  "'+ intToStr(frmMain.tgOrders.dbItemID) +'"');
       ShowMessage(#13#13 + text + ' has been DELETED' );
       frmMain.tgOrders.dbupdate
      end;

 // frmEditOrderQty.Enabled := True;

  frmEditOrderQty.Close;

end;

For other MessageDlg options see http://www.delphibasics.co.uk/RTL.asp?Name=messagedlg

I have a need to take selected items from a table grid and place them in the body of an email.

The code below using a stringlist works to an extent, however whilst my test 'showMessage' does show what I want, by the time it gets to an email body only the first two items ever show.

I could copy to clipboard and then manually paste into the email body, but that is unsatisfactory as I hope to make this automatic with the user only having to press 'send' in their email client.

My current code is

procedure frmEmail_SendEmail_OnClick (Sender: TObject; var Cancel: boolean);
const

  CRFL = #13#10;
var
  emailList : TStringlist;

  indx,colmn : integer;

begin
     emailList:= TStringList.Create;
     emailList.Clear;

     for indx := 0 to frmEmail.tbgEmailList.RowCount -1  do
     begin

         for colmn := 0 to frmEmail.tbgEmailList.Columns.Count -1 do
        begin
         emailList.add(frmEmail.tbgEmailList.Cells[colmn,indx]);

        end;
        emailList.add(CRFL);
     end;
    // try

        //st := clipboardGet;


      openURL('mailto:'+frmEmail.cmbEmailAddress.Text+'?Subject='+frmEmail.cmbSupplierList.Text+' Order'+'&Body='+ emailList.text);
      emailList.free;
     // SQLExecute('UPDATE orders SET orderEmailed = 1 WHERE orders.id =');
end;
jean.brezhonek wrote:

Hello abu7akm

Neither for the web
JB

Hi Jean,


Are you sure about that?  Under the menu item 'Project' there is the Webgrid option, which makes for a very basic web based program. It requires mySql as the database.

A link to a demonstration page  http://myvisualdatabase.com/webgrid_rus/

This works for me, I have it in the button_OnAfterClick event.

У меня это работает, у меня это в событии button_OnAfterClick

procedure Form1.............
var
count, indx : integer;

count := Form1.edGrid.RowCount -1;

for indx := 0 to count do
begin
     if Form1.edGrid.Selected[indx] then
     begin
           your edit code here
      
     end;
end; 

143

(0 replies, posted in General)

If your browser has a language translate function, I can recommend MVDs Russian language help webpage. I find it more helpful than the current English language one.

The link is http://myvisualdatabase.com/doc_ru/ 


I've attached an example that my browser has converted to English as a demonstration.

Думаю в винде не работает. Я могу ошибаться

I think in Windows it doesn't work. I might be mistaken

vit007


You used Form1.TableGrid1.CELL[0,i], the example code used Form1.TableGrid1.CELLS[0,i] - important difference.


Вы использовали Form1.TableGrid1.CELL[0, i], в примере кода использовалась Form1.TableGrid1. CELLS[0, i] - важное отличие.

abu7akm wrote:

What is the programming language used in script?

Pascal

FORMx.buttonX.Caption := FORMx.tablegridX.Cells[column,row];

148

(4 replies, posted in FAQ)

Found it.

ver.2.0.4_ErrorFastReport  is the project you need to search for by RC Service.  Here is part if this contributors image setup code. Some of it is in English, as I started to google translate it so I could understand what they have done.

Нашел.

ver.2.0.4_ErrorFastReport - это проект, который нужно искать с помощью RC Service. Вот часть кода настройки изображения этого автора. Некоторые из них на английском, поскольку я начал переводить их в Google, чтобы я мог понять, что они сделали.


// 3.1. Library images for button : ImageList
  { on Form1 }
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\compress_repair.png');        // #0- Library Work: мужик с ключом
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\car--exclamation.png');       // #1- Library ТТХ Car: машинка+!
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\book_spelling.png');          // #2- Dictionaris:
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\mopar.png');                  // #3- Mopar Parts: логотип Mopar
  { on frmWorkList }
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\report_add.png');             // #4- New Work:
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\report_edit.png');            // #5- Edit Work:
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\report_delete.png');          // #6- Delete Work:
  { on ALL FORM'S }
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\database_save.png');          // #7- Save Record: сохранить запись
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\broom.png');                  // #8- Clear Record: очистить-метла
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\reject.png');                 // #9- ClearSearch: сброс поиска
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\account_functions.png');      // #10- Personal: мужик с ключом
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\group.png');                  // #11- Library User: человечки
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\group_add.png');              // #12- New User: человечки+
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\group_edit.png');             // #13- Edit User: человечки & pen
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\group_delete.png');           // #14- Delete User: человечки-
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\group_key.png');              // #15- Save User: человечки & key
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\coins.png');                  // #16- Price Nch: монетки
  { on frmNewEditCatalogLOP }
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\AllDay.ru.png');              // #17- Catalog LOP: молоточки
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\service_status.png');         // #18- New TTX Car: grey +
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\reject.png');                 // #19- Clear TTX Car: red x
  { on frmListWork }
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\arrow-skip-090.png');         // #20- стрелка вверх:
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\arrow-skip-270.png');         // #21- стрелка вниз;
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\accept_button.png');          // #22- галочка-ОК;
  { on frmNewEditCatalogLOP }
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\add.png');                    // #23- New Work/Part: + в кружке зеленый
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\cancel.png');                 // #24- Delete Work/Part: - в кружке красный
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\pencil_add.png');             // #25- Edit Work/Part: - карандаш с плюсиком
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\file_workflow_tasks.png');    // #26- сбросить все фильтра
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\filter_clear.png');           // #27- сбросить фильтра: по категориям
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\arrow-transition-090.png');   // #28- создать основную работу: синяя стрелка вверх
  ImageList.AddPng(ExtractFilePath(Application.ExeName)+'Images\IconButton\coins_in_hand.png');          // #29- выбрать акцию для расчётов: ладошка с монетами


-------------------------------------------------------------------------------------------------------------





{ on frmViewCalculation }
  frmViewCalculation.btnClearCalculation.Images := ImageList;
  frmViewCalculation.btnPrintCalc.Images := ImageList;
  frmViewCalculation.btnExitCalc.Images := ImageList;
  { on frmViewMapWork }
  frmViewMapWork.btnClearMapWork.Images := ImageList;
  frmViewMapWork.btnExitMapWork.Images := ImageList;
  frmViewMapWork.btnPrintMapWork.Images := ImageList;
  { on frmDocuments}
  frmDocuments.btnClearSearchFileAuto.Images := ImageList;
  frmDocuments.btnViewTO.Images := ImageList;

  // 5.1. Select images for icon's buttons...
  { on Form1 }
  Form1.btnLibraryWork.ImageIndex := 0;
  Form1.btnLibraryDataCar.ImageIndex := 1;
  Form1.btnLibraryNoMopar.ImageIndex := 46;
  Form1.btnLibraryZapCh.ImageIndex := 3;
  Form1.btnLibraryPersonal.ImageIndex := 10;
  Form1.btnLibraryUser.ImageIndex := 11;
  Form1.btnPriceNch.ImageIndex := 16;
  Form1.btnCatalogLOP.ImageIndex := 17;
  Form1.btnChangeUser.ImageIndex := 30;
  Form1.btnClearDB.ImageIndex := 6;

149

(4 replies, posted in FAQ)

There is a poster here who has done that, I just can't find their post.  It was a big project around a car dealer. I think they may have overlayed the buttons using clickable images.


Здесь есть плакат, который это сделал, я просто не могу найти его пост. Это был большой проект, связанный с автомобильным дилером. Я думаю, они могли наложить на кнопки изображения, на которые можно нажимать.

Я обнаружил, что для изменения подписей и т. Д. На frmdbcore его необходимо ввести между значениями по умолчанию BEGIN ... END скрипта.


Example:


begin

   frmdbCoreUsers.bDelete.Caption:='Привет мир!';
   lbAcknowledge := TLabel.Create(frmdbCoreLogin);
   lbAcknowledge.Left := 113;
   lbAcknowledge.Top := 170;
   lbAcknowledge.Width := 300;
   lbAcknowledge.Height:= 15;
   lbAcknowledge.Margins.Top :=10;
   lbAcknowledge.Margins.Bottom := 10;
   lbAcknowledge.Parent := frmdbCoreLogin;
   lbAcknowledge.Wordwrap := true;
   lbAcknowledge.Caption := 'image copyright free from unsplash.com/photos/jXd2FSvcRr8';
   lbAcknowledge.Visible := True;

   frmdbCoreLogin.Caption := 'FORM CAPTION';

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

end.