---
--- odbcRowSource() features
---
odbcRowSource() is a fast alternative to using passthrough queries as the row source for list and combo boxes.  The reason it is so fast it because all queries go through ODBCDirect and bypass the Jet engine.  It also eliminates the problem of storing passwords in the connect strings of persistent queries (stored on disk).  Optionally, you can share the internal recordsets among controls that use the same SQL as their RowSource.  You can limit sharing to one form or share across the entire application.

Warning: do not attempt to read odbcRowSource.txt in notepad ;)  It's much easier when it's color coded.

---
--- Initial setup
---
'odbcRowSource' - Place the code in a module (probably best in a global module).

'odbcConn' - You must also have a odbcConn connection variable (again, best as a global variable.  You may want to set "Option Private Module" wherever you define this.

'makeOdbcConn()' - Provided to actually make the connection through an ODBCDirect workspace.  You will probably want to call 'makeOdbcConn()' from a login form.  

'devOdbcConn()' - Use this for as a quick start so you don't have to create a login form.  Change it to match your DSN, username and password, and then call it from 'Form_Load()' for your form.

---
--- Usage
---
To set up the list box or combo box, go to the control's properties and put in "odbcRowSource" for RowSourceType.  Put the SQL in RowSource (note, this will be sent as is to the back end, just like a passthrough query).  That's it!

If migrating from passthrough queries, use the SQL from the query in RowSource.

---
--- Customizing
---

You can share the internal recordsets among controls that use the same SQL as their RowSource.  You can limit sharing to one form or share across the entire application.  By default sharing is disabled.  If you want enable sharing, comment out this line (3#):

    keySQL = fld.Parent.Hwnd & fld.Name & keySQL

If for some reason you want to keep record sets separated by window, uncomment this line (#2):

    'keySQL = fld.Parent.Hwnd & keySQL

You can uncomment the "curious" line to get a message debug.printed when a recordset is used more than once.  Remember, you must be careful to refresh your forms when the data returned by the ODBC source may have changed.  When sharing is enabled, this could happen more often that you might expect.  In general, sharing is safe to use when the data is considered to be an application constant (for example, "Mr", "Mrs", "Ms", or state abbreviations).  It may be best to create another function called shared_odbcRowSource() with sharing enabled.  Or, you could add another parameter to specify sharing mode and make two wrapper functions (shared_..() and unique_..()).  Use these wrapper functions as the RowSourceType.

Error handling is very generic (like native list and combo boxes).  If an error occurs within odbcRowSource, it will either return nothing or "ERROR!".  You can disable "ERROR!" behavior by simply commenting the last line of odbcRowSource().  To get ODBC errors, uncomment the msgbox line (ie, "'Uncomment this if you want to display odbc errors").  

---
--- makeOdbcConn() notes
---
Use this to open a ODBC connection through an ODBCDirect workspace and set the odbcConn variable.  'odbcRowSource()' has not been tested in a Jet workspace and may not work as expected.  ODBCDirect is recommended over Jet because it is faster.

If Jet is to be used, uncomment the code block to initialize a ODBC connection through Jet.  This method will prevent the ODBC dialogue box from being displayed.  If you use passthrough queries also, the second commented code block will set the connect strings of every passthrough query.  It is recommended that you run clearODBCConnect() when your application closes to remove passwords.

---
--- devOdbcConn() notes
---
Use this during development.  Put it in 'Form_Load' to automatically reestablish an ODBC connection if it "pops".  This happens when you break running code during debugging.  If this happens, odbcRowSource() will return "ERROR!" in all controls using it.

---
--- odbcRowSource() notes
---
The main problem that you will encounter during development is odbcRowSource() returning "ERROR!" for everything.  This will happen when you break running code.  VBA "pops" or resets everything, including global variables (like odbcConn).  After you do this, your form is probably still open and will continue to call odbcRowSource() which cannot operate without a valid odbcConn.  To work around this it is advised to put devOdbcConn() in the Form_Load event for your form (remember to take it out before release!).  Then, whenever this happens, simply close and open your form (or switch to Design view and back to Form view).

Window handles (Hwnd) are used so that you can open multiple instances of forms and odbcRowSource() won't break.  

