Jump to content

Ian Branch

Members
  • Content Count

    1352
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by Ian Branch

  1. Hi Team, D11. I am playing with TFDMemTable. I have the following line of code... FDMemTable1.CopyDataSet(Company, [coStructure, coAppend]); Company is previously filtered so there is only one record 'visible'. How can I tell how much memory has been used as a result of just this code/action please? Regards & TIA, Ian
  2. Hi Team, I am cleaning up some exception handling in some old code. The code goes something like the following.. if E:ErrorCode = xx then doshomething else if E:ErrorCode = yy then dosomethingelse ... .. else TaskMessageDlg('Errormessage!', E.Message, mtError, [mbOK], 0); If using MadExcept or EurekaLog, is the following proper/acceptable?? if E:ErrorCode = xx then doshomething else if E:ErrorCode = yy then dosomethingelse ... .. else raise; to let MadExcept or EurekaLog process the unhandled exception(s)?? Regards & TIA, Ian
  3. Ian Branch

    Cleaning up some Exception handling...

    So. The short answer is No. Raise has to be within the exception block. That was all I need to know. What I can do is replace this.. else TaskMessageDlg('Errormessage!', E.Message, mtError, [mbOK], 0); end; // end else TaskMessageDlg('Error message!', E.Message, mtError, [mbOK], 0); // end; with this.. else Action := daFail; end; // end else Action := daFail; // end; The solution I was ultimately after. Thank you for your contributions. Ian
  4. Ian Branch

    Cleaning up some Exception handling...

    Hi Team, I do appreciate your inputs. I thought I was keeping it simple and asking a simple question... Oh well. OK. Here is the full code sequence....Users is a TTable. procedure TMainForm.UsersEditError(DataSet: TDataSet; E: EDatabaseError; var Action: TDataAction); begin // _EditError(Action, E, DataSet); // end; procedure TMainForm._EditError(out Action: TDataAction; E: EDatabaseError; DataSet: TDataSet); var sMessage: string; begin // sMessage := 'The record you are trying to edit in the ' + DataSet.Name + ' table '; // Action := daAbort; // if (E is EEDBError) then begin // case EEDBError(E).ErrorCode of EDB_ERROR_LOCKROW: if TaskMessageDlg('Locked record!', sMessage + ' is currently locked, do you want to try to edit this record again?', mtWarning, [mbYes, mbNo], 0) = mrYes then Action := daRetry; EDB_ERROR_ROWDELETED: begin TaskMessageDlg('Deleted record!', sMessage + ' has been deleted since it was last retrieved', mtError, [mbOK], 0); DataSet.Refresh; end; EDB_ERROR_ROWMODIFIED: begin TaskMessageDlg('Modified record!', sMessage + ' has been modified since it was last retrieved, the record will now be refreshed', mtWarning, [mbOK], 0); DataSet.Refresh; Action := daRetry; end; else TaskMessageDlg('Errormessage!', E.Message, mtError, [mbOK], 0); end; // end else TaskMessageDlg('Error message!', E.Message, mtError, [mbOK], 0); // end; Why have I gone this route? This way I can use one _EditError procedure for all TTable or TQuery EditErrors. My basic question is - Is it safe/correct/appropriate to replace the last two 'TaskMessageDlg(...' with 'raise;' to pass whatever the unhandled exception is to MadExcept or EurekaLog? Regards, Ian
  5. Ian Branch

    Cleaning up some Exception handling...

    Hi joaodanet2018, Thank you for your input. My example above was extremely simplified and was specifically enquiring if the use of raise in this context was correct. The actual code is handling the common issues and giving the User an opportunity to correct their mistakes, however there are always the exceptions, pun intended, that aren't accounted for. MadExcept & EurekaLog allow you to capture details of this exceptions and look at root cause with the objective of eliminating or mitigating them. Ian
  6. Ian Branch

    Can I assign an alias????

    Hi Team, Let's say I have two units in the App. Unit1 & Unit 2 where Unit1 is the main unit and Unit2 is a datamodule with a ttable, MyTable, on it. Is it possible to create an alias for the datamodule/ttable? i.e. instead of having to type 'Unit2.Mytable.FieldByName......' when calling it from Unit1, instead, something like 'U2MT.FieldByName.....'? Would save a hell of a lot of typing... :-) Or, is there an alternative?? Whilst I have been specific here in regards to the units/components, I can see additional usage if the ability exists. Regards & TIA, Ian
  7. Ian Branch

    Can I assign an alias????

    Hi Pat, Ahhh. Now I see/understand. Thank you for the clarification. Much Appreciated. Thank you to all contributors. So, there is no such thing as a freebee. What, if any, is the penalty for this construct? Regards, Ian
  8. Ian Branch

    Can I assign an alias????

    Hi All, Sorry, you are doing things that are over my head. 😞 I'm sure what you are telling me is quite correct, but I'm afraid I don't understand how to apply them to my scenario. That is my knowledge deficiency. I really would appreciate it if you could explain in terms of my Unit1/Unit2/TTable example. Then perhaps I can relate it to what you have above and reach an understanding. Regards, Ian
  9. Ian Branch

    Procedure out parameter question..

    Ah Ha! Excellent. Thank you.
  10. Hi Team, Given the following TTable.EditError(DataSet:TDataSet; E: EDatabaseError; var Action: TDataAction); If I now feed the parameters to a second procedure via.. _EditError(Action, E, DataSet); Given that _EditError is defined as.. procedure _EditError(out Action: TDataAction; E: EDatabaseError; DataSet: TDataSet); And in _EditError, Action may be set to daRetry or daAbort.. Will the Action be passed back up to the TTable.EditError or do I need to make the 'out Action: TDataAction;' in the _EditError definition a var?? Regards & TIA, Ian
  11. Ian Branch

    docwiki.embarcadero.com is not working

    Maybe they are updating it for Delphi 11.1?? Says he with a hopeful thought...
  12. Ian Branch

    wuppdi Welcome Page for Delphi 10.4?

    @Daniel In this case silence is not golden... 😞
  13. Ian Branch

    Thought for the Day stopped working..

    Hi Team, D10.4.2, Indy as distributed with D10.4.2. I implemented this code many moons ago and it was working fine. It may have been with Indy10 via GitHub. // HTTP := TIdHTTP.Create; try try interim := HTTP.Get('http://quotes4all.net'); // ChopStart := pos(StartQuote, interim); // if ChopStart > 1 then begin // ChopEnd := PosEx(EndQuote, interim, ChopStart + 1); // if ChopEnd > ChopStart then begin // interim := Copy(interim, ChopStart, ChopEnd - ChopStart); InCmnd := False; for Cntr := 1 to Length(interim) do begin if interim[Cntr] = '<' then InCmnd := True else if interim[Cntr] = '>' then InCmnd := False else if not InCmnd then Quote := Quote + interim[Cntr]; end; // TaskMessageDlg('Thought for the Day...', Quote, mtInformation, [mbOK], 0); // end; end; finally FreeAndNil(HTTP); // .Free; lThoughtForTheDay := True; end; // except on E: Exception do begin if E.ClassName = 'EIdConnClosedGracefully' then begin // ShowMessage('Unable to access Thought for the Day at this time.'); // EXIT; end else begin // ShowMessage('Exception class name = ' + E.ClassName); ShowMessage('Exception message = ' + E.message); // end; end; // end At a time not that long ago I had to reinstall everything. !@#$%^& Windows.. Before I go through the pain of removing the distributed Indy and re-installing Indy10, is this my issue? This doesn't work under the distributed Indy?? Regards & TIA, Ian
  14. Ian Branch

    Thought for the Day stopped working..

    Dave - Oh so true. Thanks Remy, Yes that now works. But, I have to consider, it has been not working for X time and no User has reported/mentioned it, which suggests they don't really care for it. I prefer to get rid of code if isn't being used or provides no value. I will ponder my navel for a bit and probably end up removing the functionality. Having said that, I am glad it is working again. 🙂 Regards & Tks, Ian
  15. Ian Branch

    Thought for the Day stopped working..

    Apologies Remy, My head has been elsewhere with other more pressing operational issues. :-( I have since discovered by examining 'interim' that the page structure in http://quotes4all.net has changed. That is why the routine is no longer working. FYI - const StartQuote = '<span class="quote">'; EndQuote = '</span>'; The functionality was a nice to have, dare I say a novelty piece, so no loss if I take it away. Apologies for wasting your time. Regards, Ian
  16. Hi Team, I have the following construct.. unit CompanyData; interface { mlXX = memory logical - Boolean miXX = memory integer = Integer msXX = memory string = String mXuXX = User data. mXcXX = Company data. } type TCompanyData = class class var // mscRecordEditInsertMessage: string; // mlcApplicationGlobalEmails: Boolean; // mlcSendSurveyEmails: Boolean; micSendSurveyDays: Integer; mlcPartsBinNoCompulsory: Boolean; mlcSendAPEmails: Boolean; micAPUpdateDays: SmallInt; micACUpdateDays: SmallInt; micACUpdateLimit: SmallInt; mlcSendDailyReportEmails: Boolean; mlcSendWeeklyReportEmails: Boolean; mlcSendMonthlyReportEmails: Boolean; mscSurveysEmailAddress: string; mscStillAPMsgName: string; mscStillACMessageName: string; ... ... end; Each variable represents a field in the Company TTable. Is there a simple mechanism in Delphi by which I can populate these variables directly from the TTable? Or, do I have to iterate through the fields and assign the value of each field to the variable?? If I have to iterate, is it best to do that in the Class Constructor?? i.e. Something like.. ... ... ... // class constructor Create; // end; /// ///////////////////////////////////////////////////////////////////////////////// implementation class constructor TCompanyData.Create; var i: smallint; begin // For i = 0 to Company.FieldCount do begin TCompanyData[i].AsVariant := Company.Fields[i].AsVariant; Next i; end; // end; Regards & TIA, Ian
  17. Ian Branch

    Fill Class Variables from a table row??

    Thanks FredS
  18. Ian Branch

    Thought for the Day stopped working..

    Hi Remy, Thank you for your feedback. I found the code over 18 months ago, implemented it as is and it worked fine. I have had no reason to re-visit it until now when I discovered it wasn't working. What it used to do is scrape a thought for the day from the indicated web site and display it in the TaskMessageDialog to the User. After your comments, this is now the full function code but it still doesn't retrieve a Thought for the Day. 😞 function OnAfterShow: Boolean; var HTTP: TIdHTTP; Quote: string; interim: string; ChopStart: Integer; ChopEnd: Integer; InCmnd: Boolean; Cntr: Integer; begin // Result := True; // if MainForm.DBWReg.ReadBool('ThoughtForTheDay', 'ShowAtStart', True) then begin // try HTTP := TIdHTTP.Create; try interim := HTTP.Get('http://quotes4all.net'); // ChopStart := pos(StartQuote, interim); if ChopStart > 1 then begin ChopEnd := PosEx(EndQuote, interim, ChopStart + 1); if ChopEnd > ChopStart then begin interim := Copy(interim, ChopStart, ChopEnd - ChopStart); InCmnd := False; for Cntr := 1 to Length(interim) do begin if interim[Cntr] = '<' then InCmnd := True else if interim[Cntr] = '>' then InCmnd := False else if not InCmnd then Quote := Quote + interim[Cntr]; end; TaskMessageDlg('Thought for the Day...', Quote, mtError, [mbOK], 0); end; end; finally FreeAndNil(HTTP); // .Free; end; // except // on E: EIdConnClosedGracefully do begin // ShowMessage('Unable to access Thought for the Day at this time.'); // EXIT; end; on E: Exception do begin // ShowMessage('Exception class name = ' + E.ClassName); ShowMessage('Exception message = ' + E.message); // end; // end; // end; // end; It is of course not impossible that http://quotes4all.net has changed and therefore the code is no longer applicable. I don't know. I am more than open to any alternative means to the same end. Can you point me to some appropriate code/example?? Regards & TIA, Ian
  19. Ian Branch

    Fill Class Variables from a table row??

    Hi Uwe, Something changed under-the-hood from D10.4 to D11. All working fine now in both D10.4 & D11. Thanks for the quick fix. Regards, Ian
  20. Ian Branch

    Fill Class Variables from a table row??

    Hi Uwe, Yes, there could be a field with a Null. I made the change. I still get an " Invalid class typecast." error and this.. To validate your theory I put some text into the Null field. Now it works fine, with and without the code change. Does the handling of Null need to be elsewhere?? There are other NULL fields in the record but they don't seem to affect it. With a Null in the field it works fine in D10.4.2 but not D11. Update - I changes this code.. procedure TDataSetHelper.TDataSetRecord<T>.TFieldMapping.LoadFromField(var Target: T); begin FRTTIField.SetValue(GetPointer(Target), TValue.FromVariant(FField.Value)); end; To this.. procedure TDataSetHelper.TDataSetRecord<T>.TFieldMapping.LoadFromField(var Target: T); var val: TValue; begin if FField.IsNull then val := TValue.Empty else val := TValue.FromVariant(FField.Value); FRTTIField.SetValue(GetPointer(Target), val); end; And it seems to be working. I will do some more testing tomorrow and advise. Regards, Ian
  21. Hi Team, Is there a way to make formatting for a section of code stick rather than being reformatted by the Formatter?? e.g. Keep this... result := Function(param1, param2, param3, param4); Rather than doing this.. result := Function(param1, param2, param3, param4); When the Formatter is invoked... I'd like to do this for clarity/readability. Regards & TIA, Ian
  22. Ian Branch

    Fill Class Variables from a table row??

    Hi @Uwe Raabe Just came across an issue. The DataSetHelper LoadFromField works fine with my Data in D10.4.2. Unfortunately I am getting an " Invalid class typecast." error for the same code/data in D11 at line 454. It is happening on a couple of Apps. This may be an ANSI v UniCode issue that I haven't correctly set in D11 as yet but I thought I would give you a heads-up. I have not embraced UniCode as my main Customers are still on Win 7 32Bit. :-( Regards, Ian
  23. Hi Team, I need to be able to detect and return true or false, if an integer number is in a delimited string of numbers.. i.e. If the integer is say 47, and the delimited number string is '12;94;128;3;127,147', then it would return False. If the integer is say 47, and the delimited number string is '12;94;128;3;127,47', then it would return True. If the integer is say 47, and the delimited number string is '12;147;128;3;127,47', then it would return True. Your thoughts/suggestions appreciated. Regards & TIA, Ian
  24. Ian Branch

    Is a number in a string of numbers??

    Hi Team, Thank you for your further suggestions. I am now going with Uwe's suggestion. Uwe - I like simple. 0x9000FFFF - regular expressions scare me, like pointers... ;-) Atilla - Thank you for the pointers. Regards & Tks again, Ian
×