Jump to content

Ian Branch

Members
  • Content Count

    1352
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by Ian Branch

  1. Ian Branch

    Is a number in a string of numbers??

    Hi Lajos, Interdigital Interface Difficulties. a.k.a. Finger Fault - It should be ; :-( Thank you for the code, I will have at it. Regards, Ian
  2. Ian Branch

    Spell Checker implementation?

    Hi pyscripter, Thanks for the thought. Yes I was aware and I would have loved to use it, but regrettably my Users are still using Windows 7. :-( Nevertheless, should they ever update, I won't hold my breath, or I have a need elsewhere with Windows 8 or better OS, I will certainly entertain/use it. I have downloaded your SpellCheck.zip file. Thank you. Regards, Ian
  3. Ian Branch

    Fill Class Variables from a table row??

    Hi Uwe, Finally got to implement this, sorta. Customer had some issue I needed to deal with before I could get to this again. :-( So, I am using your Singleton implementation. As the Apps have grown over the years there were some legacy issues I had to deal with. One of which was matching the fields to the file field class definitions. What a pain but much more maintainable/readable now. I changed the MyCompanyData to AppCompanyData. As I went to implement the " Company.LoadInstanceFromCurrent(AppCompanyData);", it works fine but I realised that I had other AppCompanyData variables being set conditionally. e.g. if Company.FieldByName('UDR1').IsNull then AppCompanyData.UserDefRep1 := 'No User Defined Report added.' else AppCompanyData.UserDefRep1 := Trim(Company.FieldByName('UDR1').AsString); if Company.FieldByName('UDR2').IsNull then AppCompanyData.UserDefRep2 := 'No User Defined Report added.' else AppCompanyData.UserDefRep2 := Trim(Company.FieldByName('UDR2').AsString); if Company.FieldByName('UDR3').IsNull then AppCompanyData.UserDefRep3 := 'No User Defined Report added.' else AppCompanyData.UserDefRep3 := Trim(Company.FieldByName('UDR3').AsString); if Company.FieldByName('UDR4').IsNull then AppCompanyData.UserDefRep4 := 'No User Defined Report added.' else AppCompanyData.UserDefRep4 := Trim(Company.FieldByName('UDR4').AsString); if Company.FieldByName('UDR5').IsNull then AppCompanyData.UserDefRep5 := 'No User Defined Report added.' else AppCompanyData.UserDefRep5 := Trim(Company.FieldByName('UDR5').AsString); if Company.FieldByName('UDR6').IsNull then AppCompanyData.UserDefRep6 := 'No User Defined Report added.' else AppCompanyData.UserDefRep6 := Trim(Company.FieldByName('UDR6').AsString); So for now I am sticking with my original "SetCompanyGlobals;" function. I guess I can still use the " Company.LoadInstanceFromCurrent(AppCompanyData);" and then just have the "SetCompanyGlobals;" function set these odd ones. I changed MyCompanyData to AppCompanyData because I am going to apply the same singleton principle/technique to UserData => AppUserData and UserPermissions => AppUserPermissions. "Myxxxxxxxxxx" just didn't seem right. ;-) Thanks once again for your support, Ian
  4. Ian Branch

    Fill Class Variables from a table row??

    Hi Uwe, Yes, my fingers got ahead of my brain. Some little time later I realised it wouldn't work for that very reason. That'll teach me to think out loud... ;-( Ah Ha! That makes it a whole heap easier. Presumably if there is a property in the class that isn't in the data set it ignores it? I am going to rethink my approach now, again. :-) Regards, Ian
  5. Ian Branch

    Fill Class Variables from a table row??

    Hi Uwe, I am coming to grips with this methodology. I need to change a few things. Not the least of which is the order of the variables in the Class to match the order of records in the Company table. So, it occurred to me, is it possible to add the variables dynamically? i.e. The Class starts out without any variables defined and then programmatically the variables and values are added based on the field name & value? Or possibly all the variables are added as variants and then the assignment of the value from the fields sets the variant type?? This would add enormously to the whole package flexibility/usability. Don't sweat on it, just thinking out loud here... 😉 Regards, Ian
  6. Ian Branch

    Fill Class Variables from a table row??

    Tks Uwe, I haven't fully digested your first Unit yet, just a quick look, when I do I will then go through this one. A quick look suggests I have a couple of other applications I can use it in as well. There is another thread in the Forum that I guess this is indirectly related to... Thanks Again, Regards, Ian
  7. Ian Branch

    Fill Class Variables from a table row??

    Hi Lars, It is the User's Company and the User is only associated with one company so that Company table row/data is loaded to TCompany. There are multiple Users, 80+, with 3 Companies in the Company table. Each User has a Unique UserID related to one of the companies. When they log in their related Company details are loaded to TCompany for use throughout the various units in the App(s). In essence, this is my way of having Global Company variables. Ian
  8. Ian Branch

    Fill Class Variables from a table row??

    Hi Lars, Please clarify what you mean? I am not 100% into this instancing stuff. If you are referring to keeping the Company table open and using its normal field addressing, for various reasons not for here, I don't want to. If you are referring to something else, I am all ears... :-) Regards, Ian
  9. Ian Branch

    Fill Class Variables from a table row??

    Hi Uwe, Thank you for your input. The CompanyData Unit is normally populated in the App's DataModule by simple assignment.. uses CompnyData; .... .... Company.Open; TCompanyData.mlcApplicationGlobalEmails := Company.FieldByName('ApplicationGlobalEmails').AsBoolean; ... ... Company.Close; ... ... I am using the unit in various other Apps/Units to pass around the Company Record field values without having to keep the Company table open. So, in various App/Units I might have something like.. uses CompanyData; .. .. ... if TCompanyData.mlcApplicationGlobalEmails then do something else don't; If there is a better way to do this I am open to suggestions.. FWIW I have attached the full Unit. Regards, Ian CompanyData.zip
  10. Ian Branch

    GExperts 1.3.20 experimental twm 2022-01-30 released

    Hi Thomas, Thank you once again for all your work on and support for GExperts. Greatly appreciated. Ian
  11. Hi Team, D10.4.1, Win 10. Of late when I start D10.4.1 I have been getting the above error message as Delphi/IDE starts up. It used to happen infrequently and closing/restarting Delphi normally restored normal service. Of late it has become more prevalent requiring multiple restarts of Delphi before a normal start happens. If I OK the error and let it continue I end up with Delphi windows scattered on the screen. I have done a search of all .pas & .dfm files on my PC and can't find any 'DotNetForm' component. I have also removed third party stuff like GExperts & cnPack but it still persists. Open to any thoughts/suggestions. Regards & TIA, Ian
  12. Ian Branch

    Spell Checker implementation?

    Hi Team, FWIW I had been wanting to add spell checking to my Apps for some time (years) but never got around to it. 😞 Based on the @Alexander Halser post above I bit the bullet and purchased Addict 4, gulp! - AU$490, perhaps I should have waited for the exchange rate to improve..nahh, I should live that long, and installed and integrated NHunspell. Per his offer, Alexander was gracious enough to send me his current NHunspell files. Thanks Alexander. I contacted Glenn Crouch from ESBConsult and he sent me his current Addict4 files for D11. Thanks Glenn. They work for D10.4.2 as well. After a short learning curve I now have spell checking operational in my Apps. It was relatively painless. 🙂 My only question is about the currency of the actual dictionary .oxt files/data. The dict-en.oxt file I have suggests it is from July 2010. Is this still current or is there a more recent version? Is there any value in sourcing a more recent file? If so where from? I'm figuring it doesn't really matter, dictionaries wouldn't change all that much and any new words can be added as part of Addict's interface. Regards, Ian
  13. Ian Branch

    Printing in Dark Mode????

    Hi Team, Is it just my environment??? I thought I would give Delphi Dark Mode a try. Seems OK while working /developing. Not overly enthused about it but willing to let it grow on me. I printed a small unit.. WTH!! Unreadable. All the white text on the screen was printed white on the printer. Ummmm. Is there a fix for this or do I have to switch to an IDE lighter mode before printing?? Yes, I print in Colour but I would have thought this would have been accommodated. Regards, Ian
  14. Ian Branch

    Printing in Dark Mode????

    Bad news then! Nothings been done on this matter since 10.3! 😞
  15. Ian Branch

    Printing in Dark Mode????

    Hi Team, Turns out, perhaps not surprisingly, that there is already an RSP for this from D10.3. https://quality.embarcadero.com/browse/RSP-31142?jql=text%20~%20%22Print%22 Feel free to vote for it, I have. Don't know if there is any way to escalate it into D10.4.2 or D11 issue notice. Ian
  16. Ian Branch

    Printing in Dark Mode????

    Let's just say I am on the wrong side of 70 and I prefer to sit down with a cuppa and a piece of paper and read through a new piece of code, making notes on the paper as I go. In this case it was only a small unit. Most cases I just print longer function and/or procedures so I can digest them. Old habits die hard.....
  17. Hi Edwin, Just looking at adding spell checking to my Apps. D10.4.2 son to be D11. Win 32 Apps. No Unicode. You say you have modified it for Unicode, will it still work OK for ANSI? Which libhunspell.dll does it need/use? Regards & TIA, Ian
  18. Hi Team, Any idea why only 7 procedures/functions are being shown in the attached image when there are clearly many more?? Regards & TIA, Ian Screenshot_9.bmp
  19. Ian Branch

    Missing procedures/functions in lookup??

    Grrrrr!!! Checking through other Units/Projects I have found repeated instances of this happening where I have declared in-line variables. :-( Back to the old/original way of declaring them..
  20. Ian Branch

    Missing procedures/functions in lookup??

    Great Call Uwe, If I comment out this function.. function ValidEmail(const EmailAddress: string): Boolean; const EMAIL_REGEX = '^((?>[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])' + '[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)' + '(?>\.?[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x7f])' + '[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]' + '{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d))' + '{4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\' + '[\x01-\x7f])+)\])(?(angle)>)$'; var Emails: TStringList; begin Result := True; Emails := TStringList.Create; try Emails.Delimiter := ';'; Emails.StrictDelimiter := True; Emails.DelimitedText := EmailAddress; for var I := 0 to Emails.Count - 1 do if not TRegEx.IsMatch(Emails[I], EMAIL_REGEX) then begin Result := False; Break; end; finally Emails.Free; end; // end; Then all the procedures/functions show. Through a process of trial and error I found that if I change the code to the following.. function ValidEmail(const EmailAddress: string): Boolean; const EMAIL_REGEX = '^((?>[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])' + '[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)' + '(?>\.?[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x7f])' + '[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]' + '{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d))' + '{4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\' + '[\x01-\x7f])+)\])(?(angle)>)$'; var Emails: TStringList; I: SmallInt; // <<<<<< Add this begin Result := True; Emails := TStringList.Create; try Emails.Delimiter := ';'; Emails.StrictDelimiter := True; Emails.DelimitedText := EmailAddress; for I := 0 to Emails.Count - 1 do // <<<<<<<<<<<< Change this.. if not TRegEx.IsMatch(Emails[I], EMAIL_REGEX) then begin Result := False; Break; end; finally Emails.Free; end; // end; No more issue.. This is in D10.4.2. I get the same in D11. :-( Regards and thanks again for the pointer... Ian
  21. Team, Happy New Year to ALL. Given the following example procedure.. procedure TMainForm.SendAPEmails(Sender: TObject); var iRecords: SmallInt; sConsumerEmail, sMsgSubject, sMessage, sManufacturer, sModel, sESN: string; sCompanyName, sContactName, sServiceEmail, sServiceEmailName, sCCEmailAddress: string; MailSender: TELMailSMTPBaseSender; Rslt: TResponse; // const sCannot: string = #13#10 + 'Cannot send AP Emails!'; begin // if Trim(TCompanyInfo.mscStillAPMsgName) = '' then begin MessageBeep(MB_ICONERROR); TaskMessageDlg('Awaiting Parts Message Status!', 'There is no "Still AP Message Name" specified in ... the Company table!' + sCannot, mtError, [mbOK], 0); EXIT; end; // try // LTI1.ShowBalloonHint('AP Emails...', 'Processing of today''s Awaiting Parts emails is commencing.'); // // Check if TCompanyInfo.mscStillAPMsgName is present in the Messages table. Messages.Filtered := False; Messages.Filter := 'MsgName = ' + QuotedStr(TCompanyInfo.mscStillAPMsgName); Messages.Filtered := True; Messages.Open; // if Messages.eof then begin Messages.Close; MessageBeep(MB_ICONERROR); TaskMessageDlg('Awaiting Parts Message Status!', '"Still AP Message Name" ' + TCompanyInfo.mscStillAPMsgName + ' not found in the Messages table!' + sCannot, mtError, [mbOK], 0); EXIT; end; // Messages.Close; // SendAPMsg.ParamByName('BusCode').AsString := TUsersData.msuBusCode; SendAPMsg.ParamByName('iAPUpdateDays').AsInteger := TCompanyInfo.micAPUpdateDays; SendAPMsg.Open; // iRecords := SendAPMsg.RecordCount; // if iRecords = 0 then EXIT; // if iRecords = 1 then sMessage := 'There is one Awaiting Parts Update email to be sent.' else sMessage := 'There are ' + IntToNumberText(iRecords) + ' Awaiting Parts Update emails to be sent.'; // TaskMessageDlg('Awaiting Parts Status!', sMessage, mtInformation, [mbOK], 0); // while not SendAPMsg.eof do begin // sJobNo := SendAPMsg.FieldByName('jobNo').AsString; sConsumerName := Trim(SendAPMsg.FieldByName('ConsumerName').AsString); sConsumerPhone := Trim(SendAPMsg.FieldByName('ConsumerPhoneNo').AsString); sCustomerRef := SendAPMsg.FieldByName('CustomerRef').AsString; sConsumerEmail := Trim(SendAPMsg.FieldByName('ConsumerEmail').AsString); sManufacturer := Trim(SendAPMsg.FieldByName('Manufacturer').AsString); sESN := Trim(SendAPMsg.FieldByName('ESN').AsString); sModel := Trim(SendAPMsg.FieldByName('Model').AsString); // sCompanyName := Trim(SendAPMsg.FieldByName('Name').AsString); sContactName := Trim(SendAPMsg.FieldByName('SvcContactName').AsString); sServiceEmail := Trim(SendAPMsg.FieldByName('ServiceEmail').AsString); sServiceEmailName := Trim(SendAPMsg.FieldByName('ServiceEmailName').AsString); sCCEmailAddress := Trim(SendAPMsg.FieldByName('CCEmailAddress').AsString); // if sConsumerEmail <> '' then begin // // if CheckBlackListEmails(sConsumerEmail) = True then // begin // // // SendAPMsg.Next; // // // Continue; // Do not do the rest of this While loop this time. // // // end; // MailSender := TELMailSMTPClientSender.Create; // try // Copy the current EurekaLog project settings: MailSender.Options := CurrentEurekaLogOptions; // // Set up send method {$IFDEF MailTest} // MailSender := SetMailTestParams(MailSender); // {$ELSE} // // Sender if Trim(TCompanyInfo.mscServiceEmailName) = '' then MailSender.Options.OverrideUserFullName := StrTokenAt(Trim(TCompanyInfo.mscServiceEmail), '@', 1) else MailSender.Options.OverrideUserFullName := Trim(TCompanyInfo.mscServiceEmailName); // MailSender.Options.SendSMTPClientFrom := Trim(TCompanyInfo.mscServiceEmail); // MailSender.Options.SendSMTPClientTarget := sConsumerEmail; // Recipient // {$ENDIF} // MailSender.Options.SendSMTPClientAdditionalHeaders := 'CC: ' + sCCEmailAddress + sCRLF + 'X-Priority: 1' + sCRLF + 'X-MSMail-Priority: Normal' + sCRLF + 'Importance: Normal' + sCRLF; // MailSender.Options.edoUseRealName := False; // MailSender.Options.CustomizedTexts[mtSendDialog_Caption] := 'Sending Awaiting Parts Update email to ' + MailSender.Options.SendSMTPClientTarget + '...'; // // Message Subject sMsgSubject := sCompanyName + '. Awaiting Parts Update advice for Job #: ' + sJobNo + '.'; // MailSender.Options.SendSMTPClientSubject := sMsgSubject; // Subject Text // // Message Body Messages.Filtered := False; Messages.Filter := 'MsgName = ' + QuotedStr(TCompanyInfo.mscStillAPMsgName); Messages.Filtered := True; Messages.Open; // sMessage := MessagesMsgText.AsString; // Messages.Close; // // sMessage variables manually set as Jobtickets is not open att. sMessage := ReplaceText(sMessage, '%JobNo%', sJobNo); sMessage := ReplaceText(sMessage, '%CustomerRef%', sCustomerRef); sMessage := ReplaceText(sMessage, '%CompanyName%', sCompanyName); sMessage := ReplaceText(sMessage, '%ContactName%', TCompanyInfo.mscCoyContactName); sMessage := ReplaceText(sMessage, '%ConsumerName%', sConsumerName); sMessage := ReplaceText(sMessage, '%SvcContactName%', TCompanyInfo.mscCoySvcContactName); sMessage := ReplaceText(sMessage, '%Position%', TCompanyInfo.mscCoySvcPosition); sMessage := ReplaceText(sMessage, '%Manufacturer%', sManufacturer); sMessage := ReplaceText(sMessage, '%IMEI%', sESN); sMessage := ReplaceText(sMessage, '%Model%', sModel); // MailSender.Options.SendSMTPClientMessage := sMessage; // MailSender.Options.SendSMTPClientAppendLogs := False; MailSender.Options.SendSMTPClientUseRealEMail := False; // // For visual dialog during sending: MailSender.ProgressIndicator := ProgressIndicator; FSendProgress := TSendDialogMSClassic.Create(Handle, MailSender.Options); // try // Actual send Rslt := MailSender.SendMessage; // finally FreeAndNil(FSendProgress); end; // if Failed(Ord(Rslt.SendResult)) then begin // LTD1.ExpandedText := Trim(Rslt.ErrorMessage); LTD1.Text := 'Oooops! Sending Awaiting Parts Update email for JT#' + sJobNo + ' failed.' + sCRLF + 'Click the expand button below to view the full error message.' + sCRLF + 'Awaiting Parts Update email sending will now exit.'; LTD1.Execute(Self.Handle); // SendAPMsg.Close; // EmailsLog.Open; EmailsLog.AppendRecord([now, 'AP Update', 'Sending Failed - Customer Awaiting Parts Update email to ' + sConsumerName + ' for Job #: ' + sJobNo + '.', MailSender.Options.SendSMTPClientTarget, TUsersData.msuUserID, StrToInt(sJobNo)]); EmailsLog.Close; // // Exit; // end else begin // {$IF Defined(ELogging) or Defined(Codesite)} LogMessage('Customer Awaiting Parts Update email sent to ' + sConsumerName + ' for Job #: ' + sJobNo + '.'); {$IFEND} // with APJobTickets do begin Open; Edit; FieldByName('DateSent').AsDateTime := now; Post; Close; end; // EmailsLog.Open; EmailsLog.AppendRecord([now, 'AP Update', 'Customer Awaiting Parts Update email sent to ' + sConsumerName + ' for Job #: ' + sJobNo + '.', MailSender.Options.SendSMTPClientTarget, TUsersData.msuUserID, StrToInt(sJobNo)]); EmailsLog.Close; // end; // SendAPMsg.Next; // finally FreeAndNil(MailSender); end; // /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // end else SendAPMsg.Next; // end; // End While. // LTI1.ShowBalloonHint('AP Emails...', 'Processing of today''s Awaiting Parts emails has completed.'); // finally // SendAPMsg.Close; // end; // end; How do I move/translate that over to a formless Unit please? I have several Print routines similar to this in the Main Form that I would like to put into their own Unit rather than in the Main Form. This is not something I have done before. Regards & TIA, Ian
  22. Ian Branch

    Move a Function or Procedure to a Unit??

    Definitely going this way... Tks.
  23. Ian Branch

    Loss of Datasouce??

    Hi Team, D10.4.2. Revisiting some large projects to update them, I have discovered that DB components have lost either their DataSource and/or their MasterSource. Anybody got any idea why/how this may have happened?? Now I have to go through each DB component, including ttables and tquerys to check their Data/Master Sources.. 😞 Regards & TIA, Ian
  24. Ian Branch

    Loss of Datasouce??

    Hi David, I have been able to do just that, but I am more concerned/interested in how/why it happened so I can take any necessary steps to prevent a repeat. Ian
  25. Ian Branch

    Move a Function or Procedure to a Unit??

    Hi David, That would be a reasonable/accurate statement. I can access the MainForm UI components from the Unit but I was hoping to make the Unit totally self-contained and NOT have any of them on the MainForm. For other reasons, not pertinent to this discussion, my intent can no longer be pursued. 😞 ATT I will be sticking with all the routines/procedures/UI in the MainForm. My thanks to all that have provided suggestions, instruction and guidance. Regards, Ian
×