{"id":3164,"date":"2014-03-17T17:44:59","date_gmt":"2014-03-17T17:44:59","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/03\/17\/delphi-change-field-to-calculated-field-at-runtime-is-this-a-good-practice-collection-of-common-programming-errors-2\/"},"modified":"2014-03-17T17:44:59","modified_gmt":"2014-03-17T17:44:59","slug":"delphi-change-field-to-calculated-field-at-runtime-is-this-a-good-practice-collection-of-common-programming-errors-2","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/03\/17\/delphi-change-field-to-calculated-field-at-runtime-is-this-a-good-practice-collection-of-common-programming-errors-2\/","title":{"rendered":"Delphi &#8211; Change field to calculated field at runtime. Is this a good practice?-Collection of common programming errors"},"content":{"rendered":"<p>Did anyone notice this bit of code?<\/p>\n<pre><code>procedure TSampleForm.btnOpenClick(Sender: TObject);\nbegin\n if dsSample.Active then\n   dsSample.Close;\n dsSample.SQL.text:='select id,state,oldstate,\"\" as txtState,\"\" as txtOldState from states where active=1';\n dsSample.Open;\nend;\n<\/code><\/pre>\n<p>He&#8217;s not changing a Database Field to a Calculated Field&#8230;He&#8217;s changing a Non Existent Field to a Calculated Field. He knows the field type&#8230;it&#8217;s going to be a string&#8230;So is it a big deal&#8230;No&#8230;Is it a hack&#8230;Yes&#8230;You can do the same thing in SQL with Cast&#8230;Matter of fact I&#8217;ve never really seen a reason to use Calculated Fields&#8230;I can usually do the same thing easier in the SQL.<\/p>\n<p>I added more information after a bit more digging on why not to do either&#8230;<\/p>\n<p>sabri.arslan code&#8230;to create the Fields&#8230;from the FieldList&#8230;also has problems as missing setting up keys and handling heirchy fields.<\/p>\n<pre><code>dmp:=DataSet.FieldDefs.Items[i].FieldClass.Create(self);\n<\/code><\/pre>\n<p>Then we have Francois&#8230;<\/p>\n<pre><code>if you call the none hacked code you get this...\n  for I := 0 to MyQuery.FieldDefList.Count - 1 do\n    with MyQuery.FieldDefList[I] do\n      if (DataType  ftUnknown) and not (DataType in ObjectFieldTypes) and\n        not ((faHiddenCol in Attributes) and not MyQuery.FIeldDefs.HiddenFields) then\n        CreateField(Self, nil, MyQuery.FieldDefList.Strings[I]);\n<\/code><\/pre>\n<p>umm&#8230;missing SetKeyFields will this cause unforseen behavior? Also if your ObjectView property is set to True&#8230;your Dataset will not behave properly for hierarchiacally fields&#8230;It looks to be safer to just call the Hack to CreateFields than to use his code&#8230;other than you must be positive that your dataset component never calls this code&#8230;<\/p>\n<p>CreateField calls CreateFieldComponent and you get Result := FieldClassType.Create(Owner) for your TField<\/p>\n<p>Taken from the Borland help of TFieldDef &#8220;A field definition has a corresponding TField object, but not all TField objects have a corresponding field definition. For example, calculated fields do not have field definition objects.&#8221;<\/p>\n<p>So I ask you&#8230;are you positive your not introducing unknown behavior by creating the CalculatedField on the fly? Are you positive that the Fields haven&#8217;t been created yet or won&#8217;t be created later? (There&#8217;s a bug in sabri.arslan code because he does the open\/after open&#8230;He&#8217;s overwritting the original TFields&#8230;, I don&#8217;t see why we need to recreate the TField&#8217;s for the already opened dataset)<\/p>\n<p>So what happens when CreateFields is called by the dataset(The BDE and ADO do this on InternalOpen and check to make sure that their are no values in Fields&#8230;do all the Dataset components do it this way? They don&#8217;t have to). What happens to the Fields that you have already created&#8230;are they overwritten? I didn&#8217;t see any code in the TDataset or TFieldDef that checked if the TField had already been created for the coorsponding TFieldDef other than a check to DefaultFields(if Fields has a value).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Did anyone notice this bit of code? procedure TSampleForm.btnOpenClick(Sender: TObject); begin if dsSample.Active then dsSample.Close; dsSample.SQL.text:=&#8217;select id,state,oldstate,&#8221;&#8221; as txtState,&#8221;&#8221; as txtOldState from states where active=1&#8242;; dsSample.Open; end; He&#8217;s not changing a Database Field to a Calculated Field&#8230;He&#8217;s changing a Non Existent Field to a Calculated Field. He knows the field type&#8230;it&#8217;s going to be a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3164","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/3164","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=3164"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/3164\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=3164"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=3164"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=3164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}