[AccessD] Upsize?

William Hindman wdhindman at bellsouth.net
Mon Dec 19 08:14:49 CST 2005


...ok ...I'm doubling the Tylenol ...you're making my neck ache with all 
these twists and turns :(

William
----- Original Message ----- 
From: "John Colby" <jwcolby at ColbyConsulting.com>
To: "'Access Developers discussion and problem solving'" 
<accessd at databaseadvisors.com>
Sent: Sunday, December 18, 2005 7:37 PM
Subject: Re: [AccessD] Upsize?


> What I don't understand Arthur is why you insist on using dedicated static
> functions?  You write a static function CurrentCountry(), CurrentRegion(),
> CurrentCity(), CurrentThis(), CurrentThat(), CurrentSomethingElse(). 
> Every
> time you need another CurrentSomething() you have to stop to construct 
> such
> a new function, you have potentially dozens (hundreds?  Thousands?
> Millions?) of such functions.
>
> I have ONE static function which I happen to call Fltr() but which you 
> could
> call Current() if that made your day.  Observe that the function has a
> static COLLECTION which can hold one or up to 32K values.  So my one
> function has replaced ALL of your CurrentXXX.  The only place where this
> might not be appropriate is if you need to run it a million times since my
> function will be about 3 times slower than yours, however where clauses
> evaluate the function one time and that is that.  Additionally I don't 
> have
> to stop and write a new function (wasting my client's time).  ;-)
>
> '
> 'Fltr takes two parameters, the filter name and the filter value.
> '
> 'The first syntax can be used to set the filter value:
> '
> 'fltr "MyFltr1", MyFltrValue
> '
> 'The filter lstrName is used as the key into the collection, i.e. when
> lvarValue
> 'is stored, it is stored with a key of lstrName.
> '
> 'The second syntax can be used to retrieve the value of the filter:
> '
> 'fltr("MyFltr1")
> '
> 'The fact that the second parameter is Optional allows us to check whether 
> a
> value
> 'has been passed in.  If no value is passed in, then the assumption is 
> that
> the filter
> 'is expecting to return a value.
> '
> 'Because the filter uses a collection internally to save the values, this
> single
> 'function can store up to 32K different filter values.
> '
> 'Because lvarValue is a variant, the value stored can be pretty much
> anything.
> 'In fact it is necessary to use ctl.VALUE if you want to store an 
> unchanging
> value
> 'from a control, since passing in a pointer to a control will then return
> the value
> 'of the control, which may change over time.
> '
> Public Function Fltr(lstrName As String, Optional lvarValue As Variant) As
> Variant
> On Error GoTo Err_Fltr
> Static mcolFilter As Collection
> Static blnFltrInitialized As Boolean
>
>    If Not blnFltrInitialized Then
>        Set mcolFilter = New Collection
>        blnFltrInitialized = True
>    End If
>    If IsMissing(lvarValue) Then
>        On Error Resume Next
>        Fltr = mcolFilter(lstrName)
>        If Err <> 0 Then
>            Fltr = Null
>        End If
>    Else
>        On Error Resume Next
>        mcolFilter.Remove lstrName
>        mcolFilter.Add lvarValue, lstrName
>        Fltr = lvarValue
>    End If
> Exit_Fltr:
> Exit Function
> Err_Fltr:
>        fwErr , , "Error in Function basFltrFunctions.Fltr"
>        Resume Exit_Fltr
>    Resume 0    '.FOR TROUBLESHOOTING
> End Function
>
>
> John W. Colby
> www.ColbyConsulting.com
>
> Contribute your unused CPU cycles to a good cause:
> http://folding.stanford.edu/
> -----Original Message-----
> From: accessd-bounces at databaseadvisors.com
> [mailto:accessd-bounces at databaseadvisors.com] On Behalf Of Arthur Fuller
> Sent: Sunday, December 18, 2005 2:01 PM
> To: 'Access Developers discussion and problem solving'
> Subject: Re: [AccessD] Upsize?
>
> As usual, JC is right. I would the following: search your front end for
> record and row sources that begin with the word "SELECT" and convert all
> instances to named queries before doing the upsize. Then these will 
> convert
> as well, without the converter giving them incomprehensible names.
> You may also have code that dynamically constructs SQL statements using 
> the
> values of form controls. This is harder to fix, but in general (depending 
> on
> your convention) the string in question is called strSQL or maybe sSQL or
> whatever. The way to locate this is to look for the command below the
> statement's construction: DoCmd.RunSQL <strSQL>. If you are serious about
> doing the conversion, then you want to isolate these instances, consider
> whether they can be converted to stored procedures -- and if so, convert
> them, and if not, tough luck; identify them as potential bottlenecks and
> proceed.
> <rant>
> There are a VERY few occasions in which dynamic SQL construction is
> required. In my experience, almost all occasions in which it is used are 
> due
> to the lack of analysis on the part of the programmer. A stored procedure 
> or
> table-UDF will execute much more quickly than its equivalent
> dynamically-constructed SQL statement, since there is no way that such a
> statement can be optimized.
> I have repeatedly encountered the objection that "I may or may not have
> parameters x, y and z, the user may have chosen only one or two". This
> objection is fallacious. The way to handle this possibility in a stored
> procedure is to compare the parameter to itself, as this snippet
> illustrates:
> SELECT * FROM myTable WHERE AccountNumber = @AccountNumber OR 
> @AccountNumber
> IS NULL You can perform this logic for any set of parameters that might be
> passed.
> If you don't believe me, try it.
> I am converting a colleague's app from MDB to SQL currently, and the MDB
> contains about 100 occurrences of this sort of code. A form has several
> controls on it, any combination of which might be used to create a filter.
> There are dozens and dozens of lines of code that anticipate that this one
> is null and the other two are not, etc. It is all silly, in both Access 
> and
> SQL.
> In SQL the simplest thing to do is to pass all the values of all the
> relevant controls as parameters to the stored procedure, and let it deal
> with nulls as outlined above. Dozens or hundreds of lines of code 
> disappear,
> replaced by one call to the stored procedure.
> In an MDB you need static functions to achieve the same, but that`s cool.
> Typically, you create a query that selects this and that from somewhere. 
> You
> can name it and save it, but the problem is that you cannot conveniently
> pass parameters to it. If you could, the code would reduce to one line
> approximately; but you cannot, so the most common practice is to 
> dynamically
> build an SQL statement and run it instead. Numerous lines of code 
> construct
> a statement then passed to DoCmd.RunSQL. This is nonsense, IMO.
> Let us suppose that a given query requires 3 parameters, any or all of 
> which
> might be passed. Let us call them Country, Region and Customer. Suppose 
> that
> the front lets the user select any combination of these controls, such 
> that
> Country only results in a list of every customer in that country, and so 
> on.
> Create a static function that gets or sets the value for each of these: 
> call
> them CurrentCountry, CurrentRegion and CurrentCustomer. Each of these is
> written to return a numeric value, either zero or greater than zero (which
> presumably references the PK of some other related table). Then write the
> query invoking these functions rather than addressing the particular form 
> of
> interest. Modify the query slightly so that at the end of the day it
> resembles this:
> SELECT * FROM somewhere
> WHERE
> Country = CurrentCountry() OR CurrentCountry() = 0 AND Region =
> CurrentRegion() OR CurrentRegion() = 0 AND City = CurrentCity() OR
> CurrentCity() = 0
> ---------------------
> I wrote this in Outlook, whose syntax checker does not extend to Access, 
> but
> I hope this illustrates my points:
> a) There is NO need to reference specific forms to obtain specific values 
> to
> plug into queries.
> b) By wasting your time constructing dynamic SQL queries, you make your 
> code
> tough to decipher and also bill the client for unnecessary hours.
> c) By creating the static functions to plug into your query, you enable 
> said
> query to be used in numerous situations. You can even run it from the 
> debug
> window with no forms open. Just call the static functions in Set mode then
> run the query. No need to open the form or report. You will see the 
> results
> immediately, and if they are wrong then fix the query not the form or
> report.
> d) on the chance that you might have to convert an MDB to SQL, queries
> written this way are easy to port. Static functions can`t be used in SQL 
> of
> course, but the query itself can be changed to refer to arguments in an
> equivalent stored proc or table UDF. Estimated conversion time: 1 minute 
> per
> instance.
> And finally, the more you do this, the better you will like it.
> </rant>
> Sorry for the length of the rant, but once I get started watch out! LOL.
> A.
>
> -- 
> AccessD mailing list
> AccessD at databaseadvisors.com
> http://databaseadvisors.com/mailman/listinfo/accessd
> Website: http://www.databaseadvisors.com
> 





More information about the AccessD mailing list