title: Run-time Equivalent to Assign Local Data... for TClientDataSet and TSQLQuery
body: <p>The <em>TSQLQuery</em> class is unidirectional, so for it to be used as a source for a data-bound <em>TDBGrid</em>, a <em>TClientDataSet</em> needs to be linked between the <em>TSQLQuery</em> and the <em>TDataSource</em> that the <em>TDBGrid</em> is bound to.</p>
  
  <p>I can connect the <em>TSQLConnection</em> and make the <em>TSQLQuery</em> active at design-time, with specified params, and then I can right-click on the CDS and choose the "Assign Local Data..." option to have it grab the data from the <em>TSQLQuery</em>, which then appears in the <em>TDBGrid</em> via the linked <em>TDataSource</em>.</p>
  
  <p>The amount of time between choosing "Assign Local Data..." and the data actually appearing in the grid is very short, so I am looking for the way to replicate this at run-time.</p>
  
  <p>Supposedly, I can set the <strong>Data</strong> property of the CDS to the <strong>Data</strong> of the source, but a <em>TSQLQuery</em> has no Data property. There was a post about using a provider, but </p>
  
  <pre><code>DataSetProvider1.DataSet := SQLQuery1;
  ClientDataSet1.Data := DataSetProvider1.Data;
  </code></pre>
  
  <p>throws an access violation,</p>
  
  <p>I did implement the data copy by looping through the <em>TSQLQuery</em> and appending the records to the <em>TClientDataSet</em>, but that was a lot slower than the "Assign Local Data...".</p>
  
  <p>[Edit 1]</p>
  
  <p>All the components I need are hooked up at design-time, and I can make the <em>TSQLConnection</em> active, then the <em>TSQLQuery</em>, then the <em>TClientDataSet</em> and the <em>TDBGrid</em> displays the data from the parameterised query defined in the <em>TSQLQuery</em>.</p>
  
  <p>In the <strong>OnChange</strong> event of a <em>TComboBox</em>, I need to refresh the query using a different parameter and have the grid show the relevant results, so I <strong>Close</strong> the <em>TSQLQuery</em>, change the <strong>ParamByName</strong> value, <strong>Open</strong> the <em>TSQLQuery</em> and then call <strong>ClientDataSet1.Last</strong> to highlight the last row in the grid.</p>
  
  <p>That gives me a "Cannot perform this operation on a closed dataset" error, so I use </p>
  
  <pre><code>ClientDataSet1.Active := true;
  </code></pre>
  
  <p>but that throws an "Access Violation".</p>
  
  <p>All the examples I can find are all about dropping components onto a form, linking them together, and they work. Well, yes they do, but I need to change properties in code at run-time and still have it work, which it just refuses to do.</p>
  
  <p>This is really beginning to frustrate me.</p>
  
  <p>[Edit 2]</p>
  
  <p>So I followed the example on the Embarcadero site for building a VCL Forms dbExpress Database Application, substituting my database connection details for the Interbase one the example uses.</p>
  
  <p><a href="http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Building_a_VCL_Forms_dbExpress_Database_Application" rel="nofollow noreferrer">http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Building_a_VCL_Forms_dbExpress_Database_Application</a></p>
  
  <p>In the designer, everything looked fine and the grid was showing the results from the query, but when I went to run it using F9, I was getting an "Access Violation" thrown from within <em>TCustomClientDataSet.InternalCheck</em>.</p>