<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Excel Do, Dynamic Does : VBA, Excel 2007</title><link>http://msmvps.com/blogs/xldynamic/archive/tags/VBA/Excel+2007/default.aspx</link><description>Tags: VBA, Excel 2007</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>The Kid Grows Up</title><link>http://msmvps.com/blogs/xldynamic/archive/2010/03/03/more-sp-autogen.aspx</link><pubDate>Wed, 03 Mar 2010 12:41:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1760600</guid><dc:creator>Bob Phillips</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/xldynamic/rsscomments.aspx?PostID=1760600</wfw:commentRss><comments>http://msmvps.com/blogs/xldynamic/archive/2010/03/03/more-sp-autogen.aspx#comments</comments><description>&lt;p&gt;In a &lt;a href="http://msmvps.com/blogs/xldynamic/archive/2010/02/19/sumproduct-isn-t-the-only-sp-kid-in-town.aspx#1760291"&gt;previous post&lt;/a&gt;, I talked about building stored procedures (SPs)in an Access database, and calling the same from Excel using ADO.
&lt;/p&gt;
&lt;p&gt;As I mentioned in that post, I am not a fan of the Access GUI. Whilst GUIs can be okay for doing some simple testing, checking whether something works or, I find it far easier to build a script when I need  to do similar things over and over (such as building all of the SPs for an application). I am an inveterate scripter (see &lt;a href="http://msmvps.com/blogs/xldynamic/archive/2009/08/24/autogen-ed-ribbon-code.aspx"&gt;Autogen&amp;rsquo;ed Ribbon Code&lt;/a&gt; and &lt;a href="http://msmvps.com/blogs/xldynamic/archive/2009/08/18/xml-is-such-a-pain.aspx"&gt;XML Is Such A Pain&lt;/a&gt;); rather than build the stored procedures using the Access GUI, I much prefer to build a script file that can be rerun at any time. This is very much in line with my preferences to autogen as much as possible, and also with me development methodology, where I prefer to allocate design time before ploughing into the functional code.
&lt;/p&gt;
&lt;p&gt;In the post mentioned above, I said that &amp;hellip; &lt;i&gt;you can remove all of the inline SQL from your applications, create a separate SP creator app that creates the SPs, have better structured code, and more maintainable. This post will cover such a creator app&lt;/i&gt;.
&lt;/p&gt;
&lt;p&gt;In this app, I have a script file that defines all of the SPs, and the application just reads that file and builds the SPs defined therein. I have used an INI  file as my SP definition file; I like the flexibility of INI files, the format does not have to be too rigid, and they are easily segmented, and easily read (via code).
&lt;/p&gt;
&lt;p&gt;The format of my file is as follows&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;1[spb_App]&lt;br /&gt;
&amp;nbsp;2&lt;br /&gt;
&amp;nbsp;3&amp;nbsp;&amp;nbsp;&amp;nbsp;[spb_DB]&lt;br /&gt;
&amp;nbsp;4&lt;br /&gt;
&amp;nbsp;5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DBType=Access ;could be SQL Server or any other DB&lt;br /&gt;
&amp;nbsp;6&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DBPath=C:\MyDatabases\&lt;br /&gt;
&amp;nbsp;7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DBName=MyDB.mdb&lt;br /&gt;
&amp;nbsp;8&lt;br /&gt;
&amp;nbsp;9&amp;nbsp;&amp;nbsp;&amp;nbsp;[spb_Stored_Procs]&lt;br /&gt;
10&lt;br /&gt;
11&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TypeCount=7&lt;br /&gt;
12&lt;br /&gt;
13&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I001=Get&lt;br /&gt;
14&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I002=Check&lt;br /&gt;
15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I003=Insert&lt;br /&gt;
16&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I004=List&lt;br /&gt;
17&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I005=Query&lt;br /&gt;
18&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I006=Table&lt;br /&gt;
19&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I007=Update&lt;br /&gt;
20&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I008=Delete&lt;br /&gt;
21&lt;br /&gt;
22;-----------------------&lt;br /&gt;
23; Get Stored Procedures&lt;br /&gt;
24;-----------------------&lt;br /&gt;
25&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[spb_SP_Get]&lt;br /&gt;
26&lt;br /&gt;
27&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SPCount=7&lt;br /&gt;
28&lt;br /&gt;
29;spGetCompanyGoals&lt;br /&gt;
30&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[spb_SP_Get_001]&lt;br /&gt;
31&lt;br /&gt;
32&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SPName=spGetCompanyGoals&lt;br /&gt;
33&lt;br /&gt;
34&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[spb_SP_Get_001_Parameters]&lt;br /&gt;
35&lt;br /&gt;
36&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ParameterCount=1&lt;br /&gt;
37&lt;br /&gt;
38&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[spb_SP_Get_003_Parameters_001]&lt;br /&gt;
39&lt;br /&gt;
40&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ParamName=prmLoginID&lt;br /&gt;
41&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ParamDataType=VarChar
(50)&lt;br /&gt;
42&lt;br /&gt;
43&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[spb_SP_Get_001_SQL]&lt;br /&gt;
44&lt;br /&gt;
45&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SQLLineCount=4&lt;br /&gt;
46 &lt;br /&gt;
47&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Line001=SELECT
SUM(SalesGoal) AS &amp;#39;Company Sales Goal&amp;#39;, &lt;br /&gt;
48&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Line002=&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SUM(BonusGoal) AS &amp;#39;Company Bonus Goal&amp;#39;&lt;br /&gt;
49&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Line003=FROM
refUsers &lt;br /&gt;
50&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Line004=WHERE LoginID
= prmLoginId;&lt;br /&gt;
51etc.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Line 1 isn&amp;rsquo;t actually used, it is just for completeness.
&lt;/p&gt;
&lt;p&gt;Lines 3-7 define the database, the type and location. Note that the type is to allow for building SPs in different databases, although we will just discuss Access.
&lt;/p&gt;
&lt;p&gt;Lines 9-20 define the SP categories, I do this so as to break up the SPs and keep them grouped, for easier maintenance. The Type (Get, Check, etc.)  is used as part of the section id for the SP details, as in lines 20, 30, 34, and 38.
&lt;/p&gt;
&lt;p&gt;Line 27 defines how many SPs are in that group, used as a loop index in the code.
&lt;/p&gt;
&lt;p&gt;Line 32 is the SP name, used in the code to Drop the SP then Create it anew.
&lt;/p&gt;
&lt;p&gt;Lines 34-41 defines the parameters. As you can see, there is a &lt;i&gt;&lt;b&gt;ParameterCount &lt;/b&gt;&lt;/i&gt;specifying how many parameters the SP uses. A definition for each parameter, if applicable, follows, with an incrementing suffix index so that the app can extract each in turn.
&lt;/p&gt;
&lt;p&gt;Lines 43-50 define the SP code, with a &lt;i&gt;&lt;b&gt;SQLLineCount &lt;/b&gt;&lt;/i&gt;defining how many lines of SQL are within the SP. In the example above, the SP is very simple, but of course SPs of any complexity can be built.
&lt;/p&gt;
&lt;p&gt;Lines 29-50 are repeated for each SP within that category.
&lt;/p&gt;
&lt;p&gt;Lines 22-50 are repeated for each category of SPs.
&lt;/p&gt;
&lt;p&gt;The category names are not relevant, it can be any name and any number, as long as the sections match up.

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Care has to be taken that the definitions are consistent, the category id is correct, the SP index is carried through, the parameter name in the parameter definition is the same as the parameter in the SQL code., and so on.

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The &lt;b&gt;SP Builder&lt;/b&gt; addin can be downloaded from &lt;a href="http://www.xldynamic.com/downloads/SP%20Builder.zip"&gt;here&lt;/a&gt;. It is unprotected, so the code can be examined, updated as you see fit.
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
I use this technique for all of my databases, so I have a script file for each, and can easily recreate the database code. As I mentioned, by creating a script file it helps in better design, thinking about the code required rather than diving into the GUI and building as required.
This technique could be extended to creating the database, building the tables etc. I have a separate app for this, but have not combined them as I find myself creating the SPs far more often than the database, I find it more convenient to keep as separate applications.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1760600" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/xldynamic/archive/tags/Excel/default.aspx">Excel</category><category domain="http://msmvps.com/blogs/xldynamic/archive/tags/Autogen/default.aspx">Autogen</category><category domain="http://msmvps.com/blogs/xldynamic/archive/tags/VBA/default.aspx">VBA</category><category domain="http://msmvps.com/blogs/xldynamic/archive/tags/Excel+2007/default.aspx">Excel 2007</category><category domain="http://msmvps.com/blogs/xldynamic/archive/tags/Stored+Procedures/default.aspx">Stored Procedures</category><category domain="http://msmvps.com/blogs/xldynamic/archive/tags/SPs/default.aspx">SPs</category></item></channel></rss>