 <?xml-stylesheet type="text/css" href="https://www.esdm.co.uk/Data/style/rss1.css" ?> <?xml-stylesheet type="text/xsl" href="https://www.esdm.co.uk/Data/style/rss1.xsl" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
  <channel>
    <title>The knowledge base blog</title>
    <link>https://www.esdm.co.uk/knowledge</link>
    <description />
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>mojoPortal Blog Module</generator>
    <language>en-GB</language>
    <ttl>120</ttl>
    <atom:link href="https://www.esdm.co.uk/Blog/RSS.aspx?p=138~108~11" rel="self" type="application/rss+xml" />
    <itunes:owner />
    <itunes:explicit>no</itunes:explicit>
    <item>
      <title>How to link SQL Server / RDBMS tables into MS Access without a DSN</title>
      <description><![CDATA[<p>Linking tables from RDBMS like SQL Server into an Access front end doesn't need an ODBC DSN to be configured, it can be done with a one-liner. I’m just posting this here because I keep having to look it up and can never&nbsp;find it.<br />
This example is for SQL Server; change the driver for other databases. Run this from the immediate window or a macro (adjust server, table names and credentials to suit):</p>

<p><font face="Courier New">docmd.TransferDatabase acLink, "ODBC","ODBC;DRIVER=SQL Server;SERVER=myServer\myInstanceIfNeeded;DATABASE=myDatabaseName;Trusted_connection=yes;", acTable,"myTableName","myTableName",False,True</font></p>

<p>The final parameter ensures that login credentials are stored.</p>

<p>Of course our&nbsp;production applications&nbsp;like HBSMR and PACS manage&nbsp;database connections&nbsp;in a more sophisticated manner, with the ability to switch databases and define which tables/views are attached in one operation, but the above technique can be useful where MS Access is being used for&nbsp;quick querying/editing/reporting operations.</p>
<br /><a href='https://www.esdm.co.uk/how-to-link-sql-server--rdbms-tables-into-ms-access-without-a-dsn'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/how-to-link-sql-server--rdbms-tables-into-ms-access-without-a-dsn'>...</a>]]></description>
      <link>https://www.esdm.co.uk/how-to-link-sql-server--rdbms-tables-into-ms-access-without-a-dsn</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/how-to-link-sql-server--rdbms-tables-into-ms-access-without-a-dsn</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/how-to-link-sql-server--rdbms-tables-into-ms-access-without-a-dsn</guid>
      <pubDate>Thu, 30 Mar 2017 18:24:00 GMT</pubDate>
    </item>
    <item>
      <title>How to do a typeahead incremental search control in Microsoft Access</title>
      <description><![CDATA[<p>When a user needs to find an existing record or value by typing something in a box, it is well recognized that a <a href="http://en.wikipedia.org/wiki/Incremental_search" target="_blank">"typeahead" or incremental search</a> is a powerful and user-friendly solution.</p>

<p>Of course MS Access has featured combo boxes (drop-down lists) with “auto expand” capabilities since time began; here’s an example where I’ve typed “pen” into the control and it has automatically selected the first matching value:</p>

<p><img alt="Standard Auto Expand in an Access combo box" border="0" height="281" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_140.png" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Standard Auto Expand in an Access combo box" width="415" /></p>

<p>(The list can be opened by clicking on the down arrow, or by hitting F4 - one of the many keyboard shortcuts that nobody knows - or in code with the dropdown method).</p>

<p>This is fine for most situations, but there are cases where the auto-expanding combo box falls down:</p>

<ul>
	<li>Very long lists (like many hundreds or thousands of rows in the drop-down): firstly this can be a performance problem, putting significant load on network and database whenever a user uses the control, secondly very long lists are not user-friendly, and worst of all the auto expand can just stop working or give strange results; in a system I was working on with SQL Server data storage, one combo with &gt;4000 rows would frequently fail to find values in the list when the user started typing.</li>
	<li>Lists where the user may not know the starting text (e.g. trying to find Southampton in a list that includes it as City of Southampton).</li>
	<li>Situations where we want to give the user an easy way of selecting multiple items. Not the main focus of this post, but it does provide much of a solution if you need it.</li>
</ul>

<p>This post describes a way of providing a nice user experience in these situations.</p>

<p>In the first simple example implementation the user is looking for the record for one of our clients based on knowing the unusual first name of a member of staff there. In this case the dropdown opens when the user has typed “bri”, showing lots of rows of people called “Bridges” etc, then when the user adds a “t” the list looks like this:</p>

<p><img alt="Incremental search in an Access combo box" border="0" height="147" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_141.png" style="border: 0px currentColor; border-image: none; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Incremental search in an Access combo box" width="589" /></p>

<p>On selecting a row, the form updates to show the full record for the selected client.</p>

<p>An implementation like this starts with an unbound combo box, making sure its Auto Expand property is set to No. You will ultimately need to clear the Row Source, but it makes design easier to start with a row source for the dropdown that closely resembles the final version. Typically this might be a table with a primary key value that will be hidden (e.g. an ID), and a visible descriptive field (e.g. a Name). Other properties can be set to suit requirements, so perhaps (following this simple example) Column Count = 2, Column Widths “0cm;10 cm” and List Width “10cm”. Keep Limit To List set to “Yes”. When you have a combo box that is behaving nicely with a Row Source, switch back to design view and remove the Row Source. Leave the Row Source Type set to “Table/Query”.</p>

<p>Now we need to add some code to make it work. First we add a handler for the On Key Down event, like this:</p>

<p><code><samp>Private Sub Combo0_KeyDown(KeyCode As Integer, Shift As Integer)<br />
&nbsp; If KeyCode = 8 Or KeyCode = 17 Or KeyCode = 32 Or KeyCode = 46 Or KeyCode &gt; 47 Then<br />
&nbsp;&nbsp;&nbsp; Me.TimerInterval = 300<br />
&nbsp; End If<br />
End Sub</samp></code></p>

<p>This will make the form do something 300 milliseconds later if the pressed key is one we like, i.e. one that changes the contents of the control in a way that should affect the search. 8 is Backspace, 32 is Spacebar, 46 is Del so we need them. 17 is CTRL and can arrive if the user pastes with CTRL+V or cuts with CTRL+X. Most keycodes over 47 are characters.</p>

<p>See the bottom of this post for an extension to make this handle mouse and ribbon-based paste operations.</p>

<p>Why 300 milliseconds? Make it whatever you like, but I found that is a reasonable amount of time to wait before executing the search if a user has clicked into the control and started typing. Any longer and the user feels like they are having to hang around, any faster and it searches before they’ve had time to enter the characters they are confident about. Note that if the user presses more than one key, for example by typing “Rob”, each will set the form’s timer interval, which re-starts the timer and so defers the resulting action until 300 milliseconds after the last key press. So the 300 really defines the length of pause after hitting any one key.</p>

<p>At this point the observant will be wondering why we are using the Key Down event and not the Key Up event. Well I started off by using Key Up event, but I found that it simply does not fire if the user selects some of the entered text and removes it with the Del key; however using the Key Down event does need extra care, because when it fires the contents of the control have <em>not yet changed to reflect the key press</em>.</p>

<p>Now we need some code on the form’s Timer event.</p>

<p><code><samp>Private Sub Form_Timer()<br />
&nbsp;&nbsp;&nbsp; TimerInterval = 0<br />
&nbsp;&nbsp;&nbsp; SearchByName Combo0<font style="background-color: rgb(255, 255, 0);">.Text</font><br />
End Sub</samp></code></p>

<p>In this case we first switch off the timer, then pass the text that is now in the control into a method that will execute the search. Because we are harvesting the search value now, and not in the Key Down event, we get the value after all key presses have completed. Note that we do have to use the .Text property, and not the .Value property (which is the default if we just pass me!Combo0 as a string).</p>

<p>Now we need to process the search. In this simple example we have a private method in the form’s code-behind:</p>

<p><code><samp>Private Sub SearchByName(SearchString As String)<br />
Dim qryDef As QueryDef<br />
&nbsp; If Len(SearchString) &gt;= 2 Then<br />
&nbsp;&nbsp;&nbsp; Set qryDef = CurrentDb.QueryDefs("qryNameSearch")<br />
&nbsp;&nbsp;&nbsp; qryDef.Parameters("NameSearch") = SearchString<br />
&nbsp;&nbsp;&nbsp; Set Combo0.Recordset = qryDef.OpenRecordset<br />
&nbsp;&nbsp;&nbsp; Set qryDef = Nothing<br />
&nbsp;&nbsp;&nbsp; If Combo0.Recordset.RecordCount &gt; 0 Then Combo0.Dropdown<br />
&nbsp; Else<br />
&nbsp;&nbsp;&nbsp; Set Combo0.Recordset = Nothing<br />
&nbsp; End If<br />
End Sub</samp></code></p>

<p>This relies on a saved parameter query, which in the example above might be something like:</p>

<p><code><samp>PARAMETERS NameSearch Text ( 255 );<br />
SELECT Staff.ID, Staff.LastName<br />
FROM Staff<br />
WHERE Staff.LastName Like [NameSearch] &amp; '*';</samp></code></p>

<p>or if you want to find matches when the user enters characters from the middle of the name as well:</p>

<p><code><samp>WHERE Staff.LastName Like '*' &amp; [NameSearch] &amp; '*';</samp></code></p>

<p>And of course the query can be adapted to return more advanced expressions, as in the screenshot above, and executing the search however best suits the data. And the SQL could be inline if you don’t want a saved query. Or it could be a SQL Server stored procedure, or even a called to a web service that is converted to a recordset on return, etc etc.</p>

<p>If we are in a data entry form where the value always exists in the list, that’s it, job done. If the value may not exist (see the example below) we need to give the user a way of entering data. If the control is being used to navigate to a record, then we need to do something when the user selects a value using a handler on the control’s After Update event, such as:</p>

<p><code><samp>Private Sub Combo0_AfterUpdate()</samp></code></p>

<p><code><samp>&nbsp;&nbsp;&nbsp; If Combo0 &gt; "" Then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; … do something …<br />
&nbsp;&nbsp;&nbsp; End If</samp></code></p>

<p><code><samp>End Sub</samp></code></p>

<p>Moving on from this simple example, it’s also possible to show the list of values in a separate control that is made visible when a search finds rows. In the example below (from home!) I’ve used a list box, setting it’s record source in similar fashion to the above combo box. I prefer the look and feel of this approach, and it would also allow the user to select more than one row which could be useful in some situations. The example below is a form used for taking entries to fell races. A large proportion of runners have entered before, so it saves a lot of time to fetch and confirm their previous details rather than starting from scratch. On the other hand, lots of people share the same names, particularly in South Wales(!), so we need to see quite a lot of information to confirm a match.<br />
When the user enters two or more characters of the surname, a list appears. On selecting a row, the remaining details are automatically filled in (in the parts of the form hidden by the list in this image). If a match is not found, the user has a simple data entry form to enter a new competitor.</p>

<p><img alt="Incremental search in Access using a list box" border="0" height="412" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_142.png" style="border: 0px currentColor; border-image: none; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Incremental search in Access using a list box" width="640" /></p>

<p>In this case our search method looks like this, to show or hide the list:</p>

<p><code><samp>If Len(RunnerSearch.Text) &gt;= 2 Then<br />
&nbsp; Set qryDef = CurrentDb.QueryDefs("RegistrationFormNameSearchQry")<br />
&nbsp; qryDef.Parameters("NameSearch") = RunnerSearch.Text<br />
&nbsp; Set lstRunnerPicker.Recordset = qryDef.OpenRecordset<br />
&nbsp; Set qryDef = Nothing<br />
&nbsp; lstRunnerPicker.Height = 567 * 4.9 ' 567 twips per cm<br />
&nbsp; lstRunnerPicker_Label.Height 567 * 4.9<br />
&nbsp; lstRunnerPicker.Visible = True<br />
Else<br />
&nbsp; lstRunnerPicker.Visible = False<br />
End If</samp></code></p>

<p>I hope someone finds this helpful. I’m sure these approaches can be refined and improved in all kinds of ways, so feedback welcome.</p>

<h5>UPDATE @ 4th December 2016</h5>

<p>When checking&nbsp;out comments from Rick Wiker below,&nbsp;I noticed my code above doesn't detect right-click &gt; Paste, or Paste using the ribbon tool. I find this is easily solved using the On Change event, eg:</p>

<p><code>Private Sub <font face="Courier New">RunnerSearch</font>_Change()<br />
&nbsp; If Me.TimerInterval = 0 Then<br />
&nbsp;&nbsp;&nbsp; Me.TimerInterval = 300<br />
&nbsp; End If<br />
End Sub</code></p>

<p>The condition is probably not needed -&nbsp;I just used it to be specific about when this was happening (i.e. when the KeyDown event has not already set the timer). This seems to work for a text box search control for both mouse and ribbon-based pasting. I've not yet tested this approach with a combo, and haven't spotted any negative side effects. Feel free to comment!</p>
<br /><a href='https://www.esdm.co.uk/how-to-do-a-typeahead-incremental-search-control-in-microsoft-access'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/how-to-do-a-typeahead-incremental-search-control-in-microsoft-access'>...</a>]]></description>
      <link>https://www.esdm.co.uk/how-to-do-a-typeahead-incremental-search-control-in-microsoft-access</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/how-to-do-a-typeahead-incremental-search-control-in-microsoft-access</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/how-to-do-a-typeahead-incremental-search-control-in-microsoft-access</guid>
      <pubDate>Sun, 11 Jan 2015 16:53:00 GMT</pubDate>
    </item>
    <item>
      <title>Handling different character encodings when importing tabular data from CSV</title>
      <description><![CDATA[<p>I’ve been fixing some minor issues with the utility in HBSMR that imports data from the <a href="http://finds.org.uk/" target="_blank">Portable Antiquities Scheme</a>. One issue was that some characters were mojibaked during the import, for example this text:</p> <blockquote> <p>A Medieval copper alloy fragment of an ornate horse harness pendant (12th – 14th century). The pendant has an integral loop for suspension set at 90º to the pendant.</p></blockquote> <p>was being imported as </p> <blockquote> <p>A Medieval copper alloy fragment of an ornate horse harness pendant (12th â€“ 14th century).&nbsp; The pendant has an integral loop for suspension set at 90Âº to the pendant.&nbsp; </p></blockquote> <p>The user first selects the records they are interested in from the PAS database, and save this data to a local CSV file. The utility in HBSMR prompts for the location of the file and then imports the data into a temporary holding table using the Microsoft.Jet.OLEDB.4.0 provider. By default this assumes the incoming data is ANSI, whereas in fact the downloaded CSV files are encoded as “UTF-8 without BOM” (Unicode).</p> <p>Our code is along these lines:</p><pre class="csharpcode">  schemaINI = CreateSchemaIni(PASFileName)
  <span class="kwrd">Set</span> db = CurrentDb()
  strConn = <span class="str">"[Text;FMT=Delimited;HDR=Yes;DATABASE="</span> &amp; Left$(PASFileName, InStrRev(PASFileName, <span class="str">"\"</span>) - 1) &amp; <span class="str">";].["</span> &amp; Right$(PASFileName, Len(PASFileName) - InStrRev(PASFileName, <span class="str">"\"</span>)) &amp; <span class="str">"]"</span>
  db.Execute <span class="str">"SELECT * INTO "</span> &amp; cPASDataTabName &amp; <span class="str">" FROM "</span> &amp; strConn, dbFailOnError</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>The solution lay in the CreateSchemaIni function. This creates a file called schema.ini in the same folder as the incoming file, which is used by the text file driver to help read the file correctly (<a title="Schema.ini File (Text File Driver) documentation" href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms709353(v=vs.85).aspx" target="_blank">as described here</a>). Note however that while that documentation page says the character set can be set to either ANSI or OEM, in fact it can be set to other code page identifiers as well (I don’t know how many are supported however).</p>
<p>I needed to add a line to this function to specify the character set, as shown in bold here, where 65001 is the appropriate code for “UTF-8 without BOM”:</p><pre class="csharpcode">  Open strPath &amp; <span class="str">"Schema.ini"</span> <span class="kwrd">For</span> Output <span class="kwrd">As</span> #1
  Print #1, <span class="str">"["</span> &amp; strFile &amp; <span class="str">"]"</span>
  Print #1, <span class="str">"ColNameHeader=True"</span>
  Print #1, <span class="str">"Format=CSVDelimited"</span>
  <strong>Print #1, <span class="str">"CharacterSet=65001"</span></strong></pre><pre class="csharpcode"><span class="str">etc etc</span></pre><pre class="csharpcode"><span class="str"></span></pre>
<p>Now the data imports correctly. Note: although we’re working in MS Access here, the same will apply if using the Microsoft.Jet.OLEDB.4.0 provider to read text files into .Net.</p><br /><a href='https://www.esdm.co.uk/handling-different-character-encodings-when-importing-tabular-data-from-csv'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/handling-different-character-encodings-when-importing-tabular-data-from-csv'>...</a>]]></description>
      <link>https://www.esdm.co.uk/handling-different-character-encodings-when-importing-tabular-data-from-csv</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/handling-different-character-encodings-when-importing-tabular-data-from-csv</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/handling-different-character-encodings-when-importing-tabular-data-from-csv</guid>
      <pubDate>Mon, 24 Sep 2012 11:47:25 GMT</pubDate>
    </item>
    <item>
      <title>Windows updates break MS Common Controls Tree Control</title>
      <description><![CDATA[<p>This is a replacement blog-post, based on our developing understanding of the problem and users' experiences. It appears that the update that disrupts the operation of 'tree' controls&nbsp;in HBSMR v3 and v4 is Security Update MS12-060. Symptoms include inability to select items in a tree or, in the case of v3, an inability to add new MonTypes, Components etc. The problem relates to the version and registration of mscomctl.ocx</p>

<p>Microsoft has now published guidance on how to resolve this issue. Please see:</p>

<p><a href="http://support.microsoft.com/kb/2748410">http://support.microsoft.com/kb/2748410</a></p>

<p>&nbsp;</p>

<p>&nbsp;</p>
<br /><a href='https://www.esdm.co.uk/windows-updates-break-ms-common-controls-tree-control'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/windows-updates-break-ms-common-controls-tree-control'>...</a>]]></description>
      <link>https://www.esdm.co.uk/windows-updates-break-ms-common-controls-tree-control</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/windows-updates-break-ms-common-controls-tree-control</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/windows-updates-break-ms-common-controls-tree-control</guid>
      <pubDate>Thu, 16 Aug 2012 08:42:00 GMT</pubDate>
    </item>
    <item>
      <title>Adding files to a SharePoint document list with MS Access – how to add new files</title>
      <description><![CDATA[<p>MS Access can be a nice interface onto SharePoint. We’ve been implementing this for a client, allowing files and metadata that are managed in HBSMR (Access UI onto SQL Server database) to be synchronised with a SharePoint site (public interface onto some of the data).</p> <p>For users working in HBSMR, we are providing tools to add a new file to SharePoint, update the metadata for an existing file, and delete a file.</p> <p>However, we ran into trouble with adding new files, and thought it worth writing up the solution because it is clear that others have encountered the same problem without any solutions being posted on the web.</p> <p>We are adding the file by moving it into the WebDAV folder for the SharePoint list (e.g. \\sharePointserver\archaeology\reports). This automatically creates a record in the List, with several fields populated. We then want to update the new record with custom metadata, things like who wrote the report, copyright statement, etc. So how do we get hold of the new record that has been automatically created? The unique piece of information we have is the file name, so we do a lookup into the table to fetch the ID for the record that describes our file. We’ve not yet fully bottomed out the best way of doing this, given potential complications with illegal characters in filenames etc., but for the moment we are looking for the list folder and filename in one of the automatically-populated metadata fields in the SharePoint table.</p> <p>We found that we could not “see” the new record initially. After some experimenting we found that to see the new record required either a) requerying a form that was bound to the table, or b) open and closing the table (programmatically).</p> <p>But that’s where the trouble really started. We could find the new record, and move to it in an editable recordset (DAO), however whenever we tried to update it we got a 3314 error: You must enter a value in the ‘Name’ field. The “Name” field is a non-negotiable field in a document list, and it reveals itself as a hyperlink to the file (when viewed on the SharePoint web interface or in the linked MS Access table. We tried inserting every variation of hyperlink and filename we could think of, but no change. Meanwhile we were sure all along this should be a field that SharePoint itself populated; yet although we could see all the other auto metadata fields, this one was always NULL after the refresh.</p> <p>Paul M spotted the solution – we observed that when we watched the same list in the browser interface, and refreshed after adding the new file, the list refreshed the Name column with a valid hyperlink. Yet we could not see this in Access. So we tried a more violent refresh – instead of simply re-opening the table, we tried deleting it and re-linking it – yes! the hyperlink appeared for the new record.</p> <p>After some more experimenting we found that it is sufficient to refresh the link programmatically, along these lines:</p> <p>dim td as tabledef, db as database</p> <p>set db = CurrentDb</p> <p>set td = db.TableDefs(“MySharePointTableName”)</p> <p>td.RefreshLink</p> <p>etc (clean up, the find new record)</p> <p>After that we can see not only the new record, but the hyperlink Name field is populated. We can then edit all the other fields, and we do not need to touch the Name field at all.</p><br /><a href='https://www.esdm.co.uk/adding-files-to-a-sharepoint-document-list-with-ms-access'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/adding-files-to-a-sharepoint-document-list-with-ms-access'>...</a>]]></description>
      <link>https://www.esdm.co.uk/adding-files-to-a-sharepoint-document-list-with-ms-access</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/adding-files-to-a-sharepoint-document-list-with-ms-access</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/adding-files-to-a-sharepoint-document-list-with-ms-access</guid>
      <pubDate>Wed, 01 Feb 2012 20:22:34 GMT</pubDate>
    </item>
    <item>
      <title>MS Access DAO recordset + SQL Server: how to get the ID of a newly inserted record</title>
      <description><![CDATA[<p>Sometimes when inserting records programmatically you want to create a parent record first, then add records into related tables where the Foreign Key is on an autonumber field. Therefore you need to know the new primary key value for the new parent records.&nbsp; When using DAO against a SQL Server table, a recordset behaves slightly differently from MDB/ACCDB tables. Here’s the easiest way to get the ID of a newly inserted record.</p>

<div class="csharpcode">
<pre>
<span class="lnum">   1:  </span><span class="kwrd">Dim</span> rs <span class="kwrd">As</span> Recordset, newID <span class="kwrd">As</span> <span class="kwrd">Long</span></pre>

<pre>
<span class="lnum">   2:  </span></pre>

<pre>
<span class="lnum">   3:  </span>…</pre>

<pre>
<span class="lnum">   4:  </span></pre>

<pre>
<span class="lnum">   5:  </span><span class="kwrd">Set</span> rs = CurrentDb.OpenRecordset(<span class="str">"Memory"</span>, dbOpenDynaset, dbSeeChanges)</pre>

<pre>
<span class="lnum">   6:  </span></pre>

<pre>
<span class="lnum">   7:  </span>rs.AddNew</pre>

<pre>
<span class="lnum">   8:  </span>…populate fields</pre>

<pre>
<span class="lnum">   9:  </span>rs.Update</pre>

<pre>
<span class="lnum">  10:  </span></pre>

<pre>
<span class="lnum">  11:  </span><span class="rem">' the record has been committed, but the cursor has jumped to absoluteposition 1</span></pre>

<pre>
<span class="lnum">  12:  </span><span class="rem">' move to the new record and get the ID (my autonumber field is called ID)</span></pre>

<pre>
<span class="lnum">  13:  </span>rs.Move 0, rs.LastModified</pre>

<pre>
<span class="lnum">  14:  </span>newID = rs(<span class="str">"ID"</span>)</pre>

<pre>
<span class="lnum">  15:  </span><span class="rem">' now use this ID in creating related records</span></pre>

<pre>
<span class="lnum">  16:  </span></pre>

<pre>
<span class="lnum">  17:  </span>…</pre>
</div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<br /><a href='https://www.esdm.co.uk/ms-access-dao-recordset--sql-server-how-to-get-the-id-of-a-newly-inserted-record'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/ms-access-dao-recordset--sql-server-how-to-get-the-id-of-a-newly-inserted-record'>...</a>]]></description>
      <link>https://www.esdm.co.uk/ms-access-dao-recordset--sql-server-how-to-get-the-id-of-a-newly-inserted-record</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/ms-access-dao-recordset--sql-server-how-to-get-the-id-of-a-newly-inserted-record</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/ms-access-dao-recordset--sql-server-how-to-get-the-id-of-a-newly-inserted-record</guid>
      <pubDate>Fri, 23 Dec 2011 16:09:00 GMT</pubDate>
    </item>
    <item>
      <title>How to prevent MS Access truncation or mangling of expressions over 255 characters in length</title>
      <description><![CDATA[<p>
	There’s a weakness in Access/JET that if a expression based on a memo field outputs a string longer than 255 characters, the result gets garbled <em>when used in a recordset</em>. This does not affect normal queries, forms or reports, unless they rely on a recordset (e.g. the expression uses a custom funciton that uses a recordset, or the whole expression is processed in a recordset).</p>
<p>
	I have tested this in Access 2010 and the problem remains.</p>
<p>
	One solution is&nbsp; to force Access to think of the output as a “memo” field by using a UNION onto a table with the problem column as a “MEMO” field in the table design (generally using an alias to achieve this).&nbsp; Here is an example to prevent truncation of a bibliographic reference in HBSMR, where we are pretending that the Mon.Descr field (MEMO) is the same as the calculated Reference from the second part (which is doing the actual work). Note that the first part says WHERE 1 = 0 so that it adds zero records to the output.</p>
<pre class="csharpcode">
<span class="kwrd">SELECT</span> MonUID, Prefref <span class="kwrd">as</span> SourceUID, prefref <span class="kwrd">as</span> [Number], <strong>Descr <span class="kwrd">as</span> Reference</strong>, easting <span class="kwrd">as</span> SourceNumSort </pre>
<pre class="csharpcode">
<span class="kwrd">FROM</span> Mon <span class="kwrd">WHERE</span> 1 = 0

<span class="kwrd">UNION</span> <span class="kwrd">ALL</span>

<span class="kwrd">SELECT</span> </pre>
<pre class="csharpcode">
MonSourceLink.MonUID, SourceTbl.SourceUID, IIf(IsNull([SourceNo]),"---",</pre>
<pre class="csharpcode">
IIf([SourceNo]&lt;&gt;GetNumeric([SourceNo]),[SourceNo],"&lt;" &amp; [sourceNo] &amp; "&gt;")) <span class="kwrd">AS</span> [Number],

Nz([SourceTypeLUT]![<span class="kwrd">Desc</span>],"(<span class="kwrd">No</span> record type)") &amp; </pre>
<pre class="csharpcode">
": " &amp; (IIf(IsNull([originator]),"",[originator] &amp; ". ") &amp; </pre>
<pre class="csharpcode">
IIf(IsNull([origdate]),"",[origdate] &amp; ". ") &amp; </pre>
<pre class="csharpcode">
IIf(([SourceTypeLUT].[SourceType]="PAR"),"<span class="str">'" &amp; [Title] &amp; "'</span> " &amp; "<span class="kwrd">in</span> " &amp; [Var1] &amp; </pre>
<pre class="csharpcode">
", pp " &amp; [Var2],(IIf(IsNull([title]),"",[title] &amp; ". ") &amp; </pre>
<pre class="csharpcode">
IIf(IsNull([var1]),"",[var1] &amp; ". ") &amp; IIf(IsNull([var2]),"",[var2] &amp; ". ") &amp; </pre>
<pre class="csharpcode">
IIf(IsNull([var3]),"",[var3] &amp; ". ")) &amp; [<span class="kwrd">Ref</span>] &amp; ". ")) <span class="kwrd">AS</span> Reference,

GetNumeric([SourceNo]) <span class="kwrd">AS</span> SourceNumSort 

<span class="kwrd">FROM</span> (MonSourceLink <span class="kwrd">LEFT</span> <span class="kwrd">JOIN</span> SourceTbl <span class="kwrd">ON</span> MonSourceLink.SourceUID = SourceTbl.SourceUID) </pre>
<pre class="csharpcode">
<span class="kwrd">LEFT</span> <span class="kwrd">JOIN</span> SourceTypeLUT <span class="kwrd">ON</span> SourceTbl.SourceType = SourceTypeLUT.SourceType 

<span class="kwrd">WHERE</span> MonSourceLink.MonUID="MWI20580";
</pre>
<p>
	However, this technique always produces a read-only recordset, so is only useful in some curcumstances.</p>
<p>
	More information on these pages:</p>
<ul>
	<li>
		<a href="http://www.everythingaccess.com/tutorials.asp?ID=Concatenated-fields-yield-garbage-in-recordset">http://www.everythingaccess.com/tutorials.asp?ID=Concatenated-fields-yield-garbage-in-recordset</a></li>
	<li>
		<a href="http://allenbrowne.com/ser-63.html">http://allenbrowne.com/ser-63.html</a></li>
</ul>
<p>
	&nbsp;</p>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<br /><a href='https://www.esdm.co.uk/how-to-prevent-ms-access-truncation-or-mangling-of-expressions-over-255-characters-in-length'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/how-to-prevent-ms-access-truncation-or-mangling-of-expressions-over-255-characters-in-length'>...</a>]]></description>
      <link>https://www.esdm.co.uk/how-to-prevent-ms-access-truncation-or-mangling-of-expressions-over-255-characters-in-length</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/how-to-prevent-ms-access-truncation-or-mangling-of-expressions-over-255-characters-in-length</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/how-to-prevent-ms-access-truncation-or-mangling-of-expressions-over-255-characters-in-length</guid>
      <pubDate>Mon, 05 Dec 2011 08:19:00 GMT</pubDate>
    </item>
    <item>
      <title>Some jottings on SQL Azure and GIS</title>
      <description><![CDATA[<p>I have set up a SQL Azure 90 day trial (as of 18th November) to test whether ArcSquirrel can work with Azure. This was prompted by an email from Robert Cheetham, CEO at Azavea, who is investigating cloud solutions for their Cicero product. Here are some notes about</p>

<ol>
	<li>setting up and accessing SQL Azure databases</li>
	<li>using SQL Azure with ArcGIS + ArcSquirrel and MapLink</li>
	<li>using SQL Azure with Quantum GIS and MapServer.</li>
</ol>

<h4>Azure Management Portal</h4>

<p>Although I’ve never set up any cloud services before (other than <a href="http://www.arvixe.com/" target="_blank" title="Arvixe web site">Arvixe web hosting</a>) it was incredibly easy to setup a trial SQL Azure subscription (“Windows Azure Platform Introductory Special”), create a database, and add some firewall rules to control access. I didn’t dig deep, but the “Management Portal” seems nice and simple:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_10.png"><img alt="Azure Management Portal" border="0" height="188" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_4.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Azure Management Portal" width="244" />&nbsp;</a></p>

<p>It helpfully tells you your connection string for ADO.Net, ODBC and PHP (passwords not included!):</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_8.png"><img alt="SQL Azure connection strings" border="0" height="180" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_3.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="SQL Azure connection strings" width="244" />&nbsp;</a></p>

<p>See this page for <a href="http://www.microsoft.com/windowsazure/offers/popup/popup.aspx?lang=en&amp;locale=en-gb&amp;offer=ms-azr-0018p&amp;no-rewrite=true" target="_blank" title="Details of the Windows Azure Platform Introductory Special">details of the Windows Azure Platform Introductory Special</a> including what you get for no charge and the pricing for the rest.</p>

<h4>MapLink, ArcSquirrel and Azure</h4>

<p>Hartmut connected up our MapLink to the database and pushed some spatial data into my Azure database from ArcGIS – 20,000 polygons took about 75 minutes.&nbsp; Hartmut had the layers drawing in ArcMAP, performing as well as in a normal SQL Server instance apparently, with only minor mods to our code to make the initial connection. However editing will not work without some more tweaks - MapLink and ArcSquirrel rely on some SQL metadata that is a little different on Azure.</p>

<h4>SQL Server Management Studio and MS Access</h4>

<p>Connecting with SSMS is simple, however you get reduced functionality – for example you cannot right-click &gt; edit top 200 records or anything, so quick edits of a small table need to be done with SQL or in MS Access or some other client. Fortunately connecting with MS Access (ODBC + SQL Native Client 10) is also simple, and&nbsp; the Azure database behaves just like a local SQL instance – remarkable querying speed (all things considered), though slower inserts (10,000 records took something like 15 minutes). NB you cannot directly link a spatial table into Access because it doesn’t recognize the geometry data type; but to update attributes you can link a view.</p>

<p>Also, in SSMS you get no designer tools, e.g. for creating a view; everything has to be done with T-SQL.</p>

<h4>SQL Azure Database Manager</h4>

<p>After writing the above I found the database manager in the Azure control panel, which has functionality similar to SSMS, including the ability to edit the tables*:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_12.png"><img alt="SQL Azure database manager" border="0" height="154" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_5.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="SQL Azure database manager" width="244" />&nbsp;</a></p>

<p>* spatial data types not supported for view or edit.</p>

<p>You get a designer for creating/modifying tables, but views and stored procedures are T-SQL only.</p>

<h4>MapServer, OGR and Azure</h4>

<p>Next I wanted to try serving the data through MapServer, and viewing/editing the data in Quantum GIS or MapInfo.&nbsp; MapServer and QGIS require the “geometry_columns” and “spatial_ref_sys” tables, and the easiest way to create these is to push some data in with ogr2ogr.</p>

<p>So I tried this from one of our London servers. I loaded a few hundred linear features, but got four errors like “INSERT command for new feature failed… incorrect syntax…”. On checking the results, a) while the geometries had loaded fine, all the attribute fields were NULL, and b) the spatial_ref_sys table was empty.&nbsp; I had four attribute fields, so my guess is that each syntax error was one field update across all records using a join on the incoming data.</p>

<p>Next I hooked up a MapServer WMS to my SQL Azure tables. MapServer had no trouble connecting to my Azure tables, but initially wouldn’t draw anything…&nbsp; on investigating I found that ogr2ogr had not correctly set the SRID of the geometries, so I had to update them “manually” with:</p>

<pre class="csharpcode">
<span class="kwrd">update</span> esdm_waters <span class="kwrd">set</span> ogr_geometry.STSrid = 4326</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>(which, incidentally, took 1 minute 52 seconds for 788 rows, demonstrating that updating an Azure database ain’t quick).</p>

<p>Clearly OGR needs a little work to do on SQL Azure support, but this was enough to get me going.</p>

<p>The WMS worked, so to challenge it a little more I set up another WMS onto a table with about 8000 sub-tidal habitat polygons, showing red in this OpenLayers map:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_2.png"><img alt="MapServer WMS from SQL Azure table" border="0" height="127" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="MapServer WMS from SQL Azure table" width="244" />&nbsp;</a></p>

<p>And here showing the rivers WMS as well (blue lines):</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_4.png"><img alt="MapServer WMS from SQL Azure table" border="0" height="127" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_1.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="MapServer WMS from SQL Azure table" width="244" />&nbsp;</a></p>

<p>Performance of these two layers was perfectly acceptable, though actually about 100% slower than the same WMS working from a local SQL Server 2008 Express instance. It would be interesting to see what it could do with MapServer also running on Azure.</p>

<p>I also tried a WFS – again, performance was acceptable though significantly slower than running with a local SQL instance (though I didn’t do strict comparisons).</p>

<h4>Quantum GIS and SQL Azure</h4>

<p>I found this really helpful blog post to get started: <a href="http://woostuff.wordpress.com/2011/03/13/opening-ms-sql-spatial-in-qgis/" title="http://woostuff.wordpress.com/2011/03/13/opening-ms-sql-spatial-in-qgis/">http://woostuff.wordpress.com/2011/03/13/opening-ms-sql-spatial-in-qgis/</a></p>

<p>Adding the layers requires some python script, but I’m sure someone will write a GUI plugin for QGIS soon.</p>

<p>First make sure you are running a version of QGIS that has GDAL/OGR 1.8 libraries – I’m on 1.7.0 which is OK.</p>

<p>Open the Plugins menu &gt; Python Console</p>

<p>and type in these two commands (modified for your data):</p>

<pre class="csharpcode">
uri = <span class="str">"MSSQL:server={serverName};database={databaseName};tables={tableName};trusted_connection=yes"</span>
qgis.utils.iface.addVectorLayer(uri,<span class="str">'{yourLayerNameHere}'</span>,<span class="str">'ogr'</span>)
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>In my case:</p>

<pre class="csharpcode">
uri = <span class="str">"MSSQL:server=tcp:a0awtn7gg9.database.windows.net;database=ArcSquirrel1;tables=esdm_waters;Uid=exegesis@a0awtn7gg9;Pwd=myPassword;"</span>
qgis.utils.iface.addVectorLayer(uri,<span class="rem">'Rivers','ogr')</span>
</pre>

<pre class="csharpcode">
Without any fuss my rivers dataset appeared:</pre>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_14.png"><img alt="SQL Azure table in Quantum GIS" border="0" height="237" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_6.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="SQL Azure table in Quantum GIS" width="244" />&nbsp;</a></p>

<p>And I can create and edit features and their attributes, here adding a test line off the Hebrides:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_16.png"><img alt="Editing SQL Azure features in QGIS" border="0" height="237" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_7.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Editing SQL Azure features in QGIS" width="244" />&nbsp;</a></p>

<p>And to prove it, here’s my new feature in OpenLayers…</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_18.png"><img alt="Edited features from QGIS and SQL Azure" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_8.png" style="margin: 0px; width: 244px; height: 127px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Edited features from QGIS and SQL Azure" />&nbsp;</a></p>

<p>And finally, here we have the habitat polygons (EPSG:27700) colour coded by habitat type, as well as the rivers (EPSG:4326), in QGIS. Polygon editing also worked fine, once I’d worked out why my new polygons kept vanishing (doh, classified symbols).</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_20.png"><img alt="SQL Azure polygons thematically mapped in QGIS" border="0" height="237" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_9.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="SQL Azure polygons thematically mapped in QGIS" width="244" />&nbsp;</a></p>

<p>Lots to think about, and I look forward to editing the same data with ArcGIS and ArcSquirrel soon…</p>
<br /><a href='https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis'>...</a>]]></description>
      <link>https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis</guid>
      <pubDate>Sat, 19 Nov 2011 11:42:00 GMT</pubDate>
    </item>
    <item>
      <title>How to query remote databases in MS Access</title>
      <description><![CDATA[<p>It is possible to point a query at a table in a remote database that is not linked to the current database; for example this would transfer the some of the fields from a remote copy of&nbsp;the Northwind database into a local version of the same table.</p>

<p><code>INSERT INTO Orders ( CustomerID, EmployeeID, OrderDate )</code></p>

<p><code>SELECT Orders.CustomerID, Orders.EmployeeID, Orders.OrderDate</code></p>

<p><code>FROM Orders IN 'C:\msoffice97\Office\Samples\Northwind.mdb';</code></p>
<br /><a href='https://www.esdm.co.uk/how-to-query-remote-databases-in-ms-access'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/how-to-query-remote-databases-in-ms-access'>...</a>]]></description>
      <link>https://www.esdm.co.uk/how-to-query-remote-databases-in-ms-access</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/how-to-query-remote-databases-in-ms-access</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/how-to-query-remote-databases-in-ms-access</guid>
      <pubDate>Wed, 07 Apr 2010 16:51:45 GMT</pubDate>
    </item>
    <item>
      <title>Setting up ODBC data sources on 64-bit Windows Server 2008 / Windows 7</title>
      <description><![CDATA[<p>Windows Server 2008 x64 and Windows 7 x64 have both 32 bit ODBC data sources and 64 bit ODBC data sources. They are managed separately. <p>Setting up a 32 bit ODBC connection in Windows Server 2008 x64. Start, Run, C:\Windows\SysWOW64\odbcad32.exe&nbsp; (and best create a shortcut to this). <p>To setup the 64 bit ODBC connection go to: Control Panel, Administrative Tools, Data Sources (ODBC). <p>For consistency you should setup a matching 32 and 64 bit connections. Otherwise you may run into the error "[Microsoft][ODBC Driver Manager] Data source name not found".</p><br /><a href='https://www.esdm.co.uk/setting-up-odbc-data-sources-on-64-bit-windows-server-2008--windows-7'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/setting-up-odbc-data-sources-on-64-bit-windows-server-2008--windows-7'>...</a>]]></description>
      <link>https://www.esdm.co.uk/setting-up-odbc-data-sources-on-64-bit-windows-server-2008--windows-7</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/setting-up-odbc-data-sources-on-64-bit-windows-server-2008--windows-7</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/setting-up-odbc-data-sources-on-64-bit-windows-server-2008--windows-7</guid>
      <pubDate>Wed, 30 Dec 2009 14:14:00 GMT</pubDate>
    </item>
  </channel>
</rss>