<?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>Search results for 'app:weblogs' matching tag 'excel'</title><link>http://msmvps.com/search/SearchResults.aspx?q=app:weblogs&amp;tag=excel&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tag 'excel'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Pride Dispensed, Pride Promised, And Pride To Go</title><link>http://msmvps.com/blogs/xldynamic/archive/2009/10/10/pride-dispensed-pride-promised-and-pride-to-go.aspx</link><pubDate>Sat, 10 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1731409</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;












 


  Normal


  0


  


  


  false


  false


  false


  


   


   


   


   


   


  


  MicrosoftInternetExplorer4


 





 


 








&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Just got back from London yesterday after the &lt;a href="http://msmvps.com/controlpanel/blogs/xldynamic/archive/2009/09/27/uk-excel-conference-october-2009.aspx"&gt;UK
Excel Conference&lt;/a&gt;.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;A successful couple of days I think, we had a large audience,
few no-shows, and a general good time. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;As this was organised mainly to avoid disappointing the many
wait-listed people from the previous, April, conference, the agenda was largely
the same as before. We had one new session on &amp;lsquo;Excel as a BI Tool&amp;rsquo;, which I
think that many delegates found enlightening; to see Excel being used as an
Enterprise reporting tool, querying huge amounts of data very quickly was an
eye-opener.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;It was good to see the presenters again, and we had a good first evening prior to the conference - at least until Roger persuaded me to have a pint of Timothy Taylor&amp;#39;s which was not nice, especially after the Pride!&lt;/p&gt;
&lt;p class="MsoNormal"&gt;As would be expected with an audience of circa 100 people,
we had a mixed bunch. There were some company men/women, some consultants; bankers,
auditors, and tax inspectors; a guy who works for Apple; we even had a pig
consultant &amp;ndash; who would have thought that a pig consultant is a big Excel user.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Another good dinner at Zsi-Zsi&amp;rsquo;s with some of the delegates;
a decent Chardonnay at Ha-Ha&amp;rsquo;s&amp;rsquo; on the last evening; a good meal at a most
unexpected looking Indian restaurant in Victoria that Simon, Andy and I went
to; and good hosting from Microsoft. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/3730.IMG_5F00_0244.JPG"&gt;&lt;img src="http://msmvps.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/3730.IMG_5F00_0244.JPG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;


 


 


  


  


  


  


  


  


  


  


  


  


  


  


 


 


 





 


&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;To cap it all, I missed the last train home because I was too busy talking with Simon, I got on the wrong tube line.&lt;br /&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item><item><title>Class Conscious </title><link>http://msmvps.com/blogs/xldynamic/archive/2009/10/02/class-conscious.aspx</link><pubDate>Fri, 02 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1729027</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;





&lt;/p&gt;
















 















  Normal















  0















  















  















  false















  false















  false















  















   















   















   















   















   















  















  MicrosoftInternetExplorer4















 































 















 
















&lt;p&gt;

&lt;/p&gt;

















&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;This is going to be the first in a series of items about &lt;b&gt;Code Generation&lt;/b&gt;, automatically
generating your code. I have posted a couple of times previously on this topic,
&lt;a href="http://msmvps.com/blogs/xldynamic/archive/2009/08/18/xml-is-such-a-pain.aspx"&gt;here&lt;/a&gt;
and &lt;a href="http://msmvps.com/blogs/xldynamic/archive/2009/08/24/autogen-ed-ribbon-code.aspx"&gt;here&lt;/a&gt;,
but I thought a series of posts would be useful, so here is the first. &lt;/p&gt;
&lt;h2&gt;The Last One&lt;/h2&gt;
&lt;p class="MsoNormal"&gt;I remember back in the 80s a UK company built a program
called &amp;lsquo;&lt;a href="http://www.tebbo.com/presshere/html/wf8104.htm"&gt;The Last One&lt;/a&gt;&amp;rsquo;,
its premise being that it was the last computer program because it would write
every program from thereon after. Now, after you have picked yourself up off of
the floor and stopped laughing, think about it somewhat objectively. Remember,
this was in the days of largely batch programs, they started at the beginning,
went through a file of instructions or updates, and reacted to each item
encountered. As such, with some very clear rules, it shouldn&amp;rsquo;t be too hard to
write a program to read those rules and then process the data files according
to those rules. Of course, it would all soon get messy, the types of rules are
infinite, and the types of data is also infinite, so some severe constraints
would have to be imposed, but wouldn&amp;rsquo;t a program that can handle multiple
applications, even if those applications have to adapt somewhat to that
program, be beneficial (of course, you could say this is exactly the same as
the &lt;a href="http://www.sap.com/index.epx"&gt;SAP&lt;/a&gt; paradigm, but please, let&amp;rsquo;s
not talk about SAP when I am feeling good). Event driven applications add a
whole new, more difficult dimension of course, but still&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Automate It&lt;/h2&gt;
&lt;p class="MsoNormal"&gt;I am a great fan of code generation, using it frequently,
and always look for further opportunities to use it. Why do I think it is so
good? There are many reasons:&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li class="MsoNormal"&gt;maintenance
     is reduced, make a small change and rerun and all code affected by that
     change will be re-generated&lt;/li&gt;
&lt;li class="MsoNormal"&gt;the
     quality is improved, all changes are re-generated, no need to remember
     what needs changing&lt;/li&gt;
&lt;li class="MsoNormal"&gt;the
     work is done in the more critical and interesting areas, in analysis and
     design.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;To me that third point is the most important. Code
generation makes you think about the application requirements and how they should be implemented, something you should do by right, but something that
cannot be avoided or done half-heartedly when using&lt;span&gt;&amp;nbsp; &lt;/span&gt;code generation. As the design is so
critical, and as I find it more interesting than cutting code, this suits me
perfectly.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The greatest exponent of code generation that I am aware of
is &lt;a href="http://msmvps.com/controlpanel/blogs/kathleen/default.aspx"&gt;Kathleen Dollard&lt;/a&gt;.
Her book, &lt;a href="http://www.amazon.co.uk/Code-Generation-Microsoft-Kathleen-Dollard/dp/1590591372"&gt;Code
Generation in Microsft .NET&lt;/a&gt;, is the definitive work on the subject, a
remarkably comprehensive work that provide end-to-end solutions using
XSLT-based code generation based upon a series of templates. As she says &amp;hellip; &lt;i&gt;Code generation will turbo-charge your
development cycles by offering speed, reusability, agility, and consistency&lt;/i&gt;.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Whilst this is a remarkable piece of work, I think that many
might find it daunting, even off-putting. The solution is comprehensive, but it
is based upon .NET and XML, and dare I say, can even been too purist for the
tyros amongst us. For this reason, I will address code generation from a much
simpler starting point, show how you can use code generation today using Excel,
and build upon it over the next few weeks,&lt;/p&gt;
&lt;h2&gt;Excel &amp;amp; Code Generation&lt;/h2&gt;
&lt;p class="MsoNormal"&gt;What I have described so far are full-blown applications,
with their attendant complexity, which might discourage you from going any
further. &lt;span&gt;&amp;nbsp;&lt;/span&gt;But let&amp;rsquo;s step back a bit, and
think about ways in which we can generate code in small doses. Later items will
go further, but we can show immediate benefits. In these examples, we will use
Excel as the code generating engine. Excel is a superb tool for this, as it is
with so many other things, with the grid for our data input, and VBA to handle
any complex code generating algorithms. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;You may not be aware of it, but maybe you are already using
Excel to do code generation. If you ever have a list in Excel, and use formulas
and functions to create some more descriptive text that you cut and paste into
a code module, that is a simple form of code generation.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Let&amp;rsquo;s take a simple example. I use class modules a lot, and
I find that creating properties is a pain, you need to define a private
variable where the actual value is stored, and then Get and Let properties so
that the property can be read from and written to in the class (that is assuming two
things, your property is read/write, they may not all be so; that you don&amp;rsquo;t
use Public variables for read/write properties &amp;ndash; I don&amp;rsquo;t, I always declare Get
and Let).&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Using code generation, all we need are two pieces of
information, the property name and its data type. If we want to cater for some
properties being read only, we need a third denoting the access mode.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;So, we can create a spreadsheet with 3 columns&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:36pt;text-indent:-18pt;"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;column A - property name &amp;ndash; free format text&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:36pt;text-indent:-18pt;"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;column B - data type &amp;ndash; Long, Double, String,
Boolean, Range (should suffice for now) &amp;ndash; an ideal candidate for a data
validation list&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:36pt;text-indent:-18pt;"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;column&lt;span&gt;&amp;nbsp; &lt;/span&gt;C
- access mode &amp;ndash; R, W, or RW &amp;ndash; again another dv list&lt;/p&gt;
&lt;p class="MsoNormal"&gt;It would be wise to add a fourth, column D, derived column,
that takes the property name and replaces any spaces with _, and removes any
special characters, as this will be used in the class.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;With a few simple formulae, we can easily generate all 3
elements of the property that the class needs, &lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:36pt;text-indent:-18pt;"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Private
Variable&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;=&amp;quot;Private m_&amp;quot;&amp;amp;D2&amp;amp;&amp;quot; As &amp;quot;&amp;amp;D2&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:36pt;text-indent:-18pt;"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Read
Property&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;=IF(ISNUMBER(SEARCH(&amp;quot;R&amp;quot;,$C2)),&lt;br /&gt;
&amp;quot;Public Property Get &amp;quot;&amp;amp;$D2&amp;amp;&amp;quot;() As &amp;quot;
&amp;amp;$B2&amp;amp;CHAR(10)&amp;amp;&lt;br /&gt;
&amp;quot;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;quot;&amp;amp;$D2&amp;amp;&amp;quot; =
m_&amp;quot;&amp;amp;$D2&amp;amp;CHAR(10)&amp;amp;&amp;quot;End Property&amp;quot;,&lt;br /&gt;
&amp;quot;&amp;quot;)&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Write Property&lt;/b&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:12pt;font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;=IF(ISNUMBER(SEARCH(&amp;quot;W&amp;quot;,$C2)),&lt;br /&gt;
&amp;quot;Public Property Let &amp;quot;&amp;amp;$D2&amp;amp;&amp;quot;() As &amp;quot;
&amp;amp;$B2&amp;amp;CHAR(10)&amp;amp;&lt;br /&gt;
&amp;quot;&amp;nbsp;&amp;nbsp; m_ &amp;quot;&amp;amp;$D2&amp;amp;&amp;quot; =
&amp;quot;&amp;amp;$D2&amp;amp;CHAR(10)&amp;amp;&amp;quot;End Property&amp;quot;,&lt;br /&gt;
&amp;quot;&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:12pt;font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Correction&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:12pt;font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;=IF(ISNUMBER(SEARCH(&amp;quot;W&amp;quot;,$C2)),&lt;br /&gt;
&amp;quot;Public Property Let &amp;quot;&amp;amp;$D2&amp;amp;&amp;quot;(ByVal val As &amp;quot;
&amp;amp;$B2&amp;amp;&amp;quot;)&amp;quot;&amp;amp;CHAR(10)&amp;amp;&lt;br /&gt;
&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_&amp;quot;&amp;amp;$D2&amp;amp;&amp;quot; =
val&amp;quot;&amp;amp;CHAR(10)&amp;amp;&amp;quot;End Property&amp;quot;,&lt;br /&gt;
&amp;quot;&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;

&lt;br /&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;That is all there is to it. Create a list of properties with
their attributes, and Excel generates the class code for you, all you need to
do is cut and paste it into the class module.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Next time, we will show how to use VBA to write back this
data into the class code, after all, one of the primary aims of code generation
is to save us from the boring bits. We will also look at&lt;span&gt;&amp;nbsp; &lt;/span&gt;a slightly more complex generation.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;

&lt;span style="font-size:11pt;font-family:Arial;"&gt;For
RSS subscribers, this code is attached.&lt;/span&gt;&lt;/p&gt;</description></item><item><title>xldynamic Returns</title><link>http://msmvps.com/blogs/xldynamic/archive/2009/09/28/xldynamic-returns.aspx</link><pubDate>Mon, 28 Sep 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1727853</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;













 







  Normal







  0







  







  







  false







  false







  false







  







   







   







   







   







   







  







  MicrosoftInternetExplorer4







 















 







 





















&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript" src="http://www.retweet.com/static/retweets.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;I have a website &lt;a href="http://www.xldynamic.com/"&gt;http://www.xldynamic.com/&lt;/a&gt;
which tries to provide some useful Excel information, different to the many
other Exel websites. This site includes what is probably the most useful
SUMPRODUCT discussion on the web.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Around about August 2008, my host provider, 123-reg.co.uk,
started to tear down my site on or around the 20th of every month, due to
exceeding my bandwidth limit (I admit, until then I had not been aware I had a
limit). I was confused as to why this should happen, my site was popular, but
was never one of the most frequented sites, and I had no new material to tempt
anyone. Unfortunately, seeking clarification from 123-reg was a frustrating
exercise, I was just bounced back with cut-and-pasted responses that did little
to address my actual question.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;So, when my renewal came up, I was looking to be off. I
found a new provider, and wanted to move my site across. Again, 123-reg were
just as unhelpful in transferring my domain as they had been in helping me to
understand the problems, so it has taken a while.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;All of this is a long preamble to saying my site is back in
operation, and it looks as it did before. It is my hope and intention to give
it a refresh when the time allows, make it more dynamic, and to add some new
content, but for now I am just happy for it to be back up.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;One thing I have managed to do is to update the SUMPRODUCT
page. This page has been split into two parts, the first part deals with the
mechanics of SUMPRODUCT, how it works, and considerations of this, whilst the
second part has all of the examples. In addition, the first part has 3 new
sections:&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:36pt;text-indent:-18pt;"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Conditional Counting And Summing in VBA &amp;ndash; using SUMPRODUCT
in VBA&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:36pt;text-indent:-18pt;"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;SUMPRODUCT and Excel 2007 &amp;ndash; the implications of
COUNTIFS and SUMIFS on SUMPRODUCT&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:36pt;text-indent:-18pt;"&gt;&lt;span&gt;&lt;span&gt;-&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;-x-system-font:none;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Performance considerations &amp;ndash; of using SUMPRODUCT&lt;/p&gt;
&lt;p class="MsoNormal"&gt;This page is going to get another overhaul soon, but in the
meantime I hope that these changes are useful.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;I would just add that my new host provider &lt;a href="http://www.orcsweb.com/"&gt;orcsWeb&lt;/a&gt;, has been immeasurably better in
providing technical support. So far, it seems to be a great service.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item><item><title>Shreds And Patches</title><link>http://msmvps.com/blogs/xldynamic/archive/2009/09/27/uk-excel-conference-october-2009.aspx</link><pubDate>Sun, 27 Sep 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1727556</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;&amp;quot;Man
is physically as well as metaphysically a thing of shreds and patches,
borrowed unequally from good and bad ancestors, and a misfit from the start&amp;quot; (Ralph Waldo Emerson)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;A number of us British Excel&amp;rsquo;ers (I nearly said English, Roger would never forgive me) have been holding Excel conferences for a few years. It had been a paid event, but there was no such event in 2008 as the  2007 event was not well enough attended. In 2009, we decided to try something different, and make the event free! Naturally, interest was high, and at the conference (held at Microsoft&amp;rsquo;s Victoria Street offices) we had over 100 delegates each day, and had to wait-list another 100+. Because of the fantastic interest, and the general good reception to the first event, we have decided to hold a second conference in October, offering first choice to those wait-listed at the March event.
&lt;/p&gt;
&lt;p&gt;Conferences are great opportunities for like minded saddos like us to get together and talk about the things our partners just pretend to be interested in. Microsoft have very generously provided a room with all of the presentation facilities needed, and provide coffee and lunch on both days. This support from Microsoft is what makes it possible to hold a free event, conference facilities are very expensive, and to have a central London location is fantastic.Again, many thanks to Microsoft, and the UK MVP leads, Vicki Collins and Akim Boukhelif, for their help in setting this all up.&lt;/p&gt;
&lt;p&gt;The conference is free, but of course the  cost of accommodation and meals, outside of the lunch and coffees provided during the event, are the delegate&amp;#39;s responsibility. This applies to the presenters as well, we are not subsidised by Microsoft or anyone else (of course, if any corporation wishes to do so ...) , we bear our own costs. We like these events; we like the socialising and meeting Excel colleagues that we may know virtually but have not yet met in person, and of course, talking Excel over a beer in the evening is no bad thing.
&lt;/p&gt;
&lt;p&gt;As socialising, or to use that hideous term, networking,  is an important facet of these event, we will be organising a group meal (again at own expense) on the Wednesday evening so that we can carry on great conversations that develop throughout these days.
&lt;/p&gt;
&lt;p&gt;The details of the event are:
&lt;/p&gt;
&lt;h3&gt;&lt;b&gt;&lt;span style="color:cornflowerblue;"&gt;Microsoft London (Cardinal Place)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;
&lt;span style="color:cornflowerblue;"&gt;100 Victoria Street
&lt;/span&gt;&lt;br /&gt;
&lt;span style="color:cornflowerblue;"&gt;London SW1E 5JL
&lt;/span&gt;&lt;br /&gt;
&lt;span style="color:cornflowerblue;"&gt;Tel: 0870 60 10 100&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The agenda is below &lt;/p&gt;
&lt;h3&gt;&lt;span style="color:cornflowerblue;"&gt;Agenda Wednesday 7th October  2009&lt;/span&gt;&lt;/h3&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;&lt;b&gt;Time&lt;/b&gt;&lt;/td&gt;
&lt;td style="width:132px;"&gt;&lt;b&gt;Event&lt;/b&gt;&lt;/td&gt;
&lt;td style="width:263px;"&gt;&lt;b&gt;Speaker&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;9:15am - 9:45am&lt;/td&gt;
&lt;td style="width:263px;"&gt;Registration &amp;amp; Coffee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;9:45am - 10:00am &lt;/td&gt;
&lt;td class="style1" style="width:263px;"&gt;&lt;span style="text-decoration:underline;"&gt;Welcome and Housekeeping&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;Nick Hodge&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;10:00am - 10:45am&lt;/td&gt;
&lt;td class="style1" style="width:263px;"&gt;&lt;span style="text-decoration:underline;"&gt;Working Smart with the Excel Grid&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;Simon Murphy&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;10:45am - 11:45am&lt;/td&gt;
&lt;td style="width:263px;"&gt;&lt;span style="text-decoration:underline;"&gt;I&lt;span class="style1"&gt;ntermediate Functions&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;Bob Phillips&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;11:45am - 12:15pm&lt;/td&gt;
&lt;td style="width:263px;"&gt;Coffee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;12:15pm - 1:15pm&lt;/td&gt;
&lt;td class="style1" style="width:263px;"&gt;&lt;span style="text-decoration:underline;"&gt;What&amp;#39;s in a Name?&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;Charles Williams&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;1:15pm - 2:00pm&lt;/td&gt;
&lt;td style="width:263px;"&gt;Lunch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;2:00pm - 2:45pm&lt;/td&gt;
&lt;td class="style1" style="width:263px;"&gt;&lt;span style="text-decoration:underline;"&gt;Excel as an Enterprise BI Tool&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;Carl Mackinder&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;2:45pm - 3:30pm&lt;/td&gt;
&lt;td class="style1" style="width:263px;"&gt;&lt;span style="text-decoration:underline;"&gt;Tips and Tricks in Charting&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;Andy Pope&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;3:30pm - 4:00pm&lt;/td&gt;
&lt;td style="width:263px;"&gt;Tea &amp;amp; Coffee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;4:00pm - 5:00pm&lt;/td&gt;
&lt;td class="style1" style="width:263px;"&gt;&lt;span style="text-decoration:underline;"&gt;Pivot Tables&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;Roger Govier&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;5:00pm - 5:30pm&lt;/td&gt;
&lt;td class="style1" style="width:263px;"&gt;&lt;span style="text-decoration:underline;"&gt;Pre- submitted Q&amp;amp;A&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;All&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:143px;"&gt;5:30pm &amp;ndash; Late&lt;/td&gt;
&lt;td style="width:263px;"&gt;Drinks, Dinner and Socialising&lt;/td&gt;
&lt;td&gt;All (Inc Delegates)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style="color:cornflowerblue;"&gt;Agenda Thursday 8th October  2009&lt;/span&gt;&lt;/h3&gt;
&lt;table class="style2" style="width:685px;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;&lt;b&gt;Time&lt;/b&gt;&lt;/td&gt;
&lt;td style="width:248px;"&gt;&lt;b&gt;Event&lt;/b&gt;&lt;/td&gt;
&lt;td style="width:250px;"&gt;&lt;b&gt;Speaker&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;8:30am - 9:00am&lt;/td&gt;
&lt;td style="width:248px;"&gt;Registration &amp;amp; Coffee&lt;/td&gt;
&lt;td style="width:250px;"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;9:00am - 9:15am&lt;/td&gt;
&lt;td style="width:248px;"&gt;&lt;span style="text-decoration:underline;"&gt;Welcome and Housekeeping&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1" style="width:250px;"&gt;&lt;span style="text-decoration:underline;"&gt;Nick Hodge&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;9:15am - 10:00am&lt;/td&gt;
&lt;td class="style1" style="width:248px;"&gt;&lt;span style="text-decoration:underline;"&gt;Data Exchange&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1" style="width:250px;"&gt;&lt;span style="text-decoration:underline;"&gt;Nick Hodge&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;10:00am - 11:00am&lt;/td&gt;
&lt;td class="style1" style="width:248px;"&gt;&lt;span style="text-decoration:underline;"&gt;VBA - It&amp;#39;s in Everyone&amp;#39;s Reach&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1" style="width:250px;"&gt;&lt;span style="text-decoration:underline;"&gt;Simon Murphy&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;11:00am - 11:30am&lt;/td&gt;
&lt;td style="width:248px;"&gt;Coffee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;11:30am - 12:45pm&lt;/td&gt;
&lt;td style="width:248px;"&gt;&lt;span style="text-decoration:underline;"&gt;&lt;span class="style1"&gt;Information - Visualising Data In 
Excel&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1" style="width:250px;"&gt;&lt;span style="text-decoration:underline;"&gt;Andy Pope &amp;amp; Bob Phillips&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;12:45pm - 1:30pm&lt;/td&gt;
&lt;td style="width:248px;"&gt;Lunch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;1:30pm - 2:15pm&lt;/td&gt;
&lt;td style="width:248px;"&gt;&lt;span style="text-decoration:underline;"&gt;Arrays and Array Functions&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1" style="width:250px;"&gt;&lt;span style="text-decoration:underline;"&gt;Bob Phillips&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;2:15pm - 3:15pm&lt;/td&gt;
&lt;td class="style1" style="width:248px;"&gt;&lt;span style="text-decoration:underline;"&gt;Speeding up Excel&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1" style="width:250px;"&gt;&lt;span style="text-decoration:underline;"&gt;Charles Williams&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;3:15pm - 3:45pm&lt;/td&gt;
&lt;td style="width:248px;"&gt;Tea &amp;amp; Coffee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;3:45pm - 4:30pm&lt;/td&gt;
&lt;td class="style1" style="width:248px;"&gt;&lt;span style="text-decoration:underline;"&gt;Pre-submitted Q&amp;amp;A&lt;/span&gt;&lt;/td&gt;
&lt;td class="style1" style="width:250px;"&gt;&lt;span style="text-decoration:underline;"&gt;All&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="width:150px;"&gt;4:30pm&lt;/td&gt;
&lt;td style="width:248px;"&gt;Close&lt;/td&gt;
&lt;td style="width:250px;"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope to see you there.&lt;/p&gt;</description></item><item><title>Ribbons - Gain Without The Pain</title><link>http://msmvps.com/blogs/xldynamic/archive/2009/09/09/ribbons-without-the-pain.aspx</link><pubDate>Wed, 09 Sep 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1721906</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;
























































































 












































  Normal












































  0












































  












































  












































  false












































  false












































  false












































  












































   












































   












































   












































   












































   












































  












































  MicrosoftInternetExplorer4












































 

























































































 












































 




















































































&lt;/p&gt;
&lt;p class="MsoNormal"&gt;If you are in the habit of building or customising Excel 2007
Ribbons, there is an indispensable new tool that has just hit the market. &lt;b&gt;Andy
Pope&lt;/b&gt; has released his RibbonX Visual Designer, which can be found &lt;a href="http://www.andypope.info/vba/ribboneditor.htm"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;I have blogged &lt;a href="http://msmvps.com/controlpanel/blogs/xldynamic/archive/2009/08/18/xml-is-such-a-pain.aspx"&gt;previously&lt;/a&gt;
about how I find cutting XML tedious, and the inadequate tools available, so
this is a more than useful addition to make ribbon design and coding simpler. It provides a
GUI to facilitate the Ribbon build, simple point and click rather than the tedious
line coding. The big advantage of this approach is that you can see the hierarchy
of your ribbon, and visualise what it will finally look like. To make it even
better, there is a preview option, which will build a workbook and inject the
XML so that you can ACTUALLY SEE what it will look like.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The tool adds a group to the Developer ribbon tab (so make
sure that you make this visible)&lt;/p&gt;
&lt;p class="MsoNormal"&gt;












































 












































 












































  












































  












































  












































  












































  












































  












































  












































  












































  












































  












































  












































  












































 












































 












































 

























































































 












































&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/6470.RVD-Ribbon.png"&gt;&lt;/a&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/3731.RVD-Ribbon.png"&gt;&lt;img src="http://msmvps.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/3731.RVD-Ribbon.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;and here is a screenshot of the designer, with a few example controls added.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;












































 












































&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/3731.RVD-Designer.png"&gt;&lt;/a&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/5807.RVD-Designer.png"&gt;&lt;img src="http://msmvps.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/5807.RVD-Designer.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In addition, you can load an existing workbook, and amend
its ribbon. It has many other goodies which I won&amp;rsquo;t list here, check out the
link above to read about them all.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;As I said, a great tool, and at a good price - free!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item><item><title>Conditional Formatting In Excel 2007 - Chav or Mini?</title><link>http://msmvps.com/blogs/xldynamic/archive/2009/09/08/conditional-formatting-in-excel-2007-chav-or-mini.aspx</link><pubDate>Tue, 08 Sep 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1721544</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;Yesterday I had an incredibly frustrating time.

&lt;/p&gt;
&lt;p&gt;I was updating my RibbonX Autogen routine to handle more types of controls. This is driven from a worksheet, some columns of which are generated, some of which depend upon user input. So being a helpful sort of guy, I have decided to shade the input cells as a visual aid. But in some circumstances, an input cell may not be required (for instance, a group does not require an image, so suggesting that it does by shading is a tad misleading). Being the helpful sort that I alluded to earlier, I decided that I would use conditional formatting, to test those conditions, and remove the shading where appropriate. Which is where I came up against the MS designers, who seem to me to live in a land far from reality, totally unaware of what people really do.

&lt;/p&gt;
&lt;p&gt;Okay, we all know that conditional formatting was limited, 3 conditions was never enough, and that the CF dialog was rubbish, but why didn&amp;#39;t they just address those issues? Why re-design the whole way it works? Don&amp;#39;t MS realise that evolution is just as valid an approach as revolution, change the things that really requirie changing first, see how it gets used, and then gradually build upon that improve. In other words, let the real users have some influence.&lt;/p&gt;
&lt;p&gt;The first problem that I came across was the new behaviour whereby if you create a condition, and then paste the format of another cell over the top, another cell that also has CF, the target cell adds those format conditions. No options, you can&amp;#39;t say you don&amp;#39;t want to add, it just does it. Of course, unless you are aware of this, you may find your cells reacting to a differenet condition, and you then start wondering why the CF no longer works.

&lt;/p&gt;
&lt;p&gt;Next, I added some CF conditions to a number of rows over 2 columns. That was fine until I decided that I wanted one of the columns to have an extra test in the condition. So I selected the cells in that column, and edited the rule to include the new test. Lo and behold, the other column also adopted these tests. When you set conditional formatting on a range, Excel remembers which cells are using that rule, and so change the rule in any cell and they all get the change. Again, no choice that I can see, I can&amp;#39;t tell it what I want, I get what MS decide because MS knows best. In the end the only solution that I could find was by deleting the formatting on both columns and then recreating singly on each.

&lt;/p&gt;
&lt;p&gt;And of course, when you are in a cell that was part of a range that has been conditionally formatted, the formula is no longer adjusted to that cell as it was it previous versions of Excel, it shows the actual formula you applied. So I am in P15, and in the rule I see the formula =OR($A3=&amp;quot;break&amp;quot;,$B3,AND($A3=&amp;quot;&amp;quot;,$M3&amp;lt;&amp;gt;&amp;quot;&amp;quot;)). The first time I encountered this it really threw me. What possible purpose can this change serve? I cannot see it.

&lt;/p&gt;
&lt;p&gt;Add to all of this rubbish the new, glitzy, childish icon sets, the fact that the formula box still defaults to input (so you have to F2 to actually use it), the fact that the dialog is not resizeable in order to better view your formula; I can only conclude that this is another very bad user dialog. &lt;/p&gt;
&lt;p&gt;Considering that Excel 2007 was supposed to be simpler to use, and remove some of the mysteries of Excel, I think the designers of Conditional Formatting in Excel 2007 have failed abysmally. As seems to be the way with MS and Excel, too much effort was spent on adding unnecessary and distracting glitz, and very little on real usability.&lt;/p&gt;</description></item><item><title>Autogen’ed Ribbon Code</title><link>http://msmvps.com/blogs/xldynamic/archive/2009/08/24/autogen-ed-ribbon-code.aspx</link><pubDate>Mon, 24 Aug 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1717882</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;







 

  Normal

  0

  

  

  false

  false

  false

  

   

   

   

   

   

  

  MicrosoftInternetExplorer4

 



 

 







&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In a previous post, &lt;a target="_self" title="XML Is Such A Pain" 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;, I showed the technique that I use to
simplify the creation of XML code for custom ribbons.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;This is a handy technique, as it means that creating the XML
is very simple, it is more or less a cut-and-paste job, and I spend very little
time thereafter&lt;span&gt;&amp;nbsp; &lt;/span&gt;with the XML, which I
like as the tools for XML in Excel 2007 are not great.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;As much as I like this technique, it still requires a lot of
VBA code. Whilst VBA is a great deal easier as a development tool than anything
we have with XML, there are many areas where errors can creep in, both
compilation and runtime errors.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In the old world of commandbars, I used a table driven
method of generating the commandbars. It is possible to use a similar technique
with Excel 2007, many such have been demonstrated.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;I prefer to generate the code, from a similar setup table. This
way I can generate all of the code components; it only needs to be run when
anything changes; and I can view the code that is generated. I like code
generation.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In the technique that I will demonstrate here, I generate
all of the required code from the setup table&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li class="MsoNormal"&gt;the
     ribbon XML&lt;/li&gt;
&lt;li class="MsoNormal"&gt;the
     VBA callback procedures&lt;/li&gt;
&lt;li class="MsoNormal"&gt;VBA
     constants used in the callback procedures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;In addition, the VBA code is automatically inserted into the
target workbook. As of yet, the XML is not automatically added as the workbook
is open at the time, but it should be possible to extend the technique to write
the XML file.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;As in the previous post, all of the code shown here relates
to the following custom ribbon tab.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:12pt;font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/5381.Ribbon-Demo.png"&gt;&lt;img src="http://msmvps.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/5381.Ribbon-Demo.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In that earlier post, you can view all of the XML and VBA
code, so it will not be repeated here, but rather this post will cover the
generation of that code. The autogeneration code here only caters for button
controls, but it can easily be extended for other controls such as menus,
toggles, and so on.&lt;/p&gt;
&lt;h2&gt;Autogen Setup Table&lt;/h2&gt;
&lt;p class="MsoNormal"&gt;The table used to drive the autogeneration is structured as
follows:&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li class="MsoNormal"&gt;Type
     &amp;ndash; a simple Data Validation list of tab, group, separator, or button&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Tag
     &amp;ndash; an id for the control that is used to generate unique control ids&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Tag
     Upper - an upper case copy of Tag&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Group
     &amp;ndash; the Tag Upper value of the current group&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Separator
     &amp;ndash; the Tag Upper of the previous separator within this group (if
     applicable)&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Group/Sep/Tag
     &amp;ndash; concatenation of Group &amp;amp; Separator &amp;amp; Tag Upper&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal" style="margin-left:54pt;"&gt;&lt;b&gt;=SUBSTITUTE(D6&amp;amp;&amp;quot;_&amp;quot;&amp;amp;E6&amp;amp;&amp;quot;_&amp;quot;&amp;amp;C6,&amp;quot;__&amp;quot;,&amp;quot;_&amp;quot;)&lt;/b&gt;&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li class="MsoNormal"&gt;Control
     Id &amp;ndash; a derived id for this control&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal" style="margin-left:54pt;"&gt;&lt;b&gt;=IF(A3=&amp;quot;group&amp;quot;,&amp;quot;grp&amp;quot;,IF(A3=&amp;quot;button&amp;quot;,&amp;quot;btn&amp;quot;,IF(A3=&amp;quot;separator&amp;quot;,&amp;quot;sep&amp;quot;,A3)))&amp;amp;$B$2&amp;amp;IF(A3=&amp;quot;button&amp;quot;,PROPER(E3),&amp;quot;&amp;quot;)&amp;amp;B3&lt;/b&gt;&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li class="MsoNormal"&gt;Caption
     &amp;ndash; a value to assign as the control label&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Procedure
     &amp;ndash; the OnAction procedure name&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Image
     File &amp;ndash; the idMso of the required image&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Image
     Size &amp;ndash; a simple Data Validation list of small or large&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Screentip
     &amp;ndash; a value to assign as the control screentip &lt;/li&gt;
&lt;li class="MsoNormal"&gt;Supertip
     &amp;ndash; a value to assign as the control supertip&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Keytip
     &amp;ndash; a value to assign as the control Keyttip&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;The example shown above consists of&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li class="MsoNormal"&gt;a
     tab control&lt;/li&gt;
&lt;li class="MsoNormal"&gt;a
     group control&lt;/li&gt;
&lt;li class="MsoNormal"&gt;two
     button controls within that group&lt;/li&gt;
&lt;li class="MsoNormal"&gt;a
     second group control&lt;/li&gt;
&lt;li class="MsoNormal"&gt;a
     third button control within the second group&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;The table for this example is shown below. I have transposed
it (columns to rows) in order to show it on this page, but that aside, you
should get the principle.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/6470.Ribbon-Table.png"&gt;&lt;img src="http://msmvps.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/6470.Ribbon-Table.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Autogen Overview&lt;/h2&gt;
&lt;p class="MsoNormal"&gt;The autogeneration works in the following way:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="MsoNormal"&gt;read the setup table and create a staging array
of details&lt;/li&gt;
&lt;li class="MsoNormal"&gt;initialise the constants array, setting up on oversized array&lt;/li&gt;
&lt;li class="MsoNormal"&gt;initialise the output XML array with the
namespace etc.&lt;/li&gt;
&lt;li class="MsoNormal"&gt;initialise the VBA code output arrays with
function signature (a public ribbon variable and an onLoad callback
procedure) &lt;/li&gt;
&lt;li class="MsoNormal"&gt;read the staging array and create items for each
line of XML code&lt;/li&gt;
&lt;li class="MsoNormal"&gt;create output arrays for
&lt;ul&gt;
&lt;li class="MsoNormal"&gt;procedure VBA code lines&lt;/li&gt;
&lt;li class="MsoNormal"&gt;label VBA code lines &lt;/li&gt;
&lt;li class="MsoNormal"&gt;image VBA code lines&lt;/li&gt;
&lt;li class="MsoNormal"&gt;image size VBA code lines&lt;/li&gt;
&lt;li class="MsoNormal"&gt;screentip VBA code lines &lt;/li&gt;
&lt;li class="MsoNormal"&gt;supertip VBA code lines &lt;/li&gt;
&lt;li class="MsoNormal"&gt;keytip VBA code lines &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class="MsoNormal"&gt;create constants arrays for
&lt;ul&gt;
&lt;li class="MsoNormal"&gt;procedure ids&lt;/li&gt;
&lt;li class="MsoNormal"&gt;label VBA ids &lt;/li&gt;
&lt;li class="MsoNormal"&gt;image ids&lt;/li&gt;
&lt;li class="MsoNormal"&gt;image size ids&lt;/li&gt;
&lt;li class="MsoNormal"&gt;screentip ids &lt;/li&gt;
&lt;li class="MsoNormal"&gt;supertip ids &lt;/li&gt;
&lt;li class="MsoNormal"&gt;keytip ids&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class="MsoNormal"&gt;finalise the output XML array with the closing tags, and write the array to a text file (this is an area to be improved) &lt;/li&gt;
&lt;li class="MsoNormal"&gt;finalise the global constants output arrays by resizing the arrays to the appropriate size and write the arrays to a code module&lt;/li&gt;
&lt;li class="MsoNormal"&gt;finalise the VBA code output arrays by adding closing function statements, resizing the arrays, and write the arrays to a code module&lt;/li&gt;
&lt;li class="MsoNormal"&gt;write a procedure to the code module to invalidate the ribbon&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;In its present release, the XML code is written to a text
file. It needs to be copied to the custom UI file, either by unzipping the
file, then opening the customUI.xml file and replacing the XML within there, or by
using the CustomUI editor to replace the XML. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;There is nothing particularly illuminating in this code, it
is a very straight-forward loop, depending entirely upon the setup table being
correctly formatted. It should be noted that some control types do not create
all of the array data, for instance a separator does not create constants or
VBA code, tabs do not create image code and so on.&lt;/p&gt;
&lt;h2&gt;Considerations&lt;/h2&gt;
&lt;p class="MsoNormal"&gt;As this technique writes VBA code on the fly, trusted access
to VBA has to be granted, but this is only required in the development
environment, if a workbook that this technique is applied to is given to a
colleague, that colleague does not to grant trusted access. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;This was a relatively simple project to build, there were
not many problems encountered. The oddest involved the image size. In the XML,
the image size is normal or large, so you would naturally assume that the value
to be assigned in the callback procedure was normal or large. My original
attempt at the code assigned these values, but the images always showed as
normal size, I couldn&amp;rsquo;t get large images. Finally, I contacted &lt;a href="http://www.execlguru.ca/"&gt;Ken Puls&lt;/a&gt; a co-author on the &lt;a href="http://www.amazon.com/RibbonX-Customizing-Office-2007-Ribbon/dp/0470191112/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1251114672&amp;amp;sr=8-1"&gt;RibbonX&lt;/a&gt;
book, which was and is my main reference in working with the Ribbon. Ken&amp;rsquo;s book
seemed to suggest that normal and large was the correct values to use in the
callback procedures, but he also found that this wasn&amp;rsquo;t working. Luckily he
found the values to use, which are 0 and 1. Ken has blogged this bug &lt;a href="http://www.excelguru.ca/blog/2009/08/04/using-getsize-with-ribbonx-buttons/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Code Writing Code&lt;/h2&gt;
&lt;p class="MsoNormal"&gt;The code that writes the VBA code on the fly is given below.
There is not much code as there is no decision logic required in this code, the
setup code creates complete output lines, apart from a test as to whether the
code is to be written new or appended.&lt;/p&gt;
&lt;pre&gt;Option Explicit&lt;br /&gt;Option Private Module&lt;br /&gt;&lt;br /&gt;Public Enum ModuleTypes&lt;br /&gt;    vbext_ct_StdModule = 1&lt;br /&gt;    vbext_ct_ClassModule = 2&lt;br /&gt;    vbext_ct_MSForm = 3&lt;br /&gt;End Enum&lt;br /&gt;&lt;br /&gt;Public Function WriteCode( _&lt;br /&gt;    ByVal CodeArray As Variant, _&lt;br /&gt;    ByVal Module As String, _&lt;br /&gt;    Optional ByVal Append As Boolean)&lt;br /&gt;Dim mpModule As Object&lt;br /&gt;Dim mpInsertLine As Long&lt;br /&gt;Dim i As Long&lt;br /&gt;    &lt;br /&gt;    On Error Resume Next&lt;br /&gt;    Set mpModule = ActiveWorkbook.VBProject.VBComponents(Module)&lt;br /&gt;    On Error GoTo 0&lt;br /&gt;&lt;br /&gt;    If Not Append Then&lt;br /&gt;    &lt;br /&gt;        If Not mpModule Is Nothing Then ActiveWorkbook.VBProject.VBComponents.Remove mpModule&lt;br /&gt;        Set mpModule = ActiveWorkbook.VBProject.VBComponents.Add(vbext_ct_StdModule)&lt;br /&gt;        mpModule.Name = Module&lt;br /&gt;        &lt;br /&gt;        mpModule.CodeModule.InsertLines 1, _       &lt;br /&gt;                    &amp;quot;&amp;#39;== Generated Cube Formula Module &amp;quot; &amp;amp; _&lt;br /&gt;                    Format(Date, &amp;quot;dd mmm yyyy&amp;quot;) &amp;amp; &amp;quot; &amp;quot; &amp;amp; Format(Time(), &amp;quot;hh:mm:ss&amp;quot;) &amp;amp; _&lt;br /&gt;                    &amp;quot; By &amp;quot; &amp;amp; Environ(&amp;quot;UserName&amp;quot;) &amp;amp; _&lt;br /&gt;                    &amp;quot; on &amp;quot; &amp;amp; Environ(&amp;quot;ComputerName&amp;quot;) &amp;amp; vbCrLf &amp;amp; _&lt;br /&gt;                    &amp;quot;&amp;#39;== &amp;quot; &amp;amp; vbCrLf &amp;amp; _&lt;br /&gt;                &amp;quot; &amp;quot;&lt;br /&gt;    End If&lt;br /&gt;    &lt;br /&gt;    With mpModule.CodeModule&lt;br /&gt;        &lt;br /&gt;        mpInsertLine = .CountOfLines + 2&lt;br /&gt;        For i = LBound(CodeArray) To UBound(CodeArray)&lt;br /&gt;        &lt;br /&gt;            .InsertLines mpInsertLine, CodeArray(i)&lt;br /&gt;            mpInsertLine = mpInsertLine + 1&lt;br /&gt;        Next i&lt;br /&gt;    End With&lt;br /&gt;    &lt;br /&gt;End Function&lt;br /&gt;&lt;/pre&gt;
&lt;h2&gt;Example File&lt;/h2&gt;
&lt;p class="MsoNormal"&gt;For RSS subscribers, you can download a zip file containing
the Autogen addin, and the example file shown above.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item><item><title>XML Is Such A Pain</title><link>http://msmvps.com/blogs/xldynamic/archive/2009/08/18/xml-is-such-a-pain.aspx</link><pubDate>Tue, 18 Aug 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1716443</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;





















 















  Normal















  0















  















  















  false















  false















  false















  















   















   















   















   















   















  















  MicrosoftInternetExplorer4















 































 















 



































&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;Creating a custom ribbon tab in Excel 2007 is a well known technique by now, and relatively easy to achieve.&lt;span&gt;&amp;nbsp; &lt;/span&gt;I will not go into the
details here, there are many examples scattered across the web, I would suggest Ron de Bruin&amp;rsquo;s pages at &lt;a href="http://www.rondebruin.nl/ribbon.htm"&gt;http://www.rondebruin.nl/ribbon.htm&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;The biggest pain for me with custom ribbon code is the XML. As an example, to create a custom ribbon tab such as this&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://msmvps.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/xldynamic/Aug/0511.Ribbon%20Demo.png" style="max-width:550px;" border="0" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;requires the following XML code&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;customUI xmlns=&amp;quot;http://schemas.microsoft.com/office/2006/01/customui&amp;quot; onLoad=&amp;quot;rxDemoRibbonOnLoad&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;ribbon startFromScratch=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;tabs&amp;gt;&lt;br /&gt;            &amp;lt;tab id=&amp;quot;tabDemo&amp;quot; getLabel=&amp;quot;Ribbon Demo&amp;quot; insertAfterMso=&amp;quot;TabHome&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;                &amp;lt;group id=&amp;quot;grpDemoGroup1&amp;quot; getLabel=&amp;quot;Formatting Group&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;                    &amp;lt;button id=&amp;quot;btnDemoButton1&amp;quot; &lt;br /&gt;                        label=&amp;quot;Currency&amp;quot; &lt;br /&gt;                        image=&amp;quot;DollarSign&amp;quot; &lt;br /&gt;                        imageSize=&amp;quot;Large&amp;quot; &lt;br /&gt;                        screentip=&amp;quot;Button 1&amp;quot; &lt;br /&gt;                        superTip=&amp;quot;Format activecell as currency&amp;quot;&lt;br /&gt;                        keytip=&amp;quot;&amp;quot; &lt;br /&gt;                        onAction=&amp;quot;procButton1&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;                    &amp;lt;button id=&amp;quot;btnDemoButton2&amp;quot; &lt;br /&gt;                        label=&amp;quot;Percentage&amp;quot; &lt;br /&gt;                        image=&amp;quot;PercentSign&amp;quot; &lt;br /&gt;                        imageSize=&amp;quot;Large&amp;quot; &lt;br /&gt;                        screentip=&amp;quot;Button 2&amp;quot;&lt;br /&gt;                        supertip=&amp;quot;Format activecell as percent&amp;quot; &lt;br /&gt;                        keytip=&amp;quot;&amp;quot; &lt;br /&gt;                        onAction=&amp;quot;procButton2&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;/group&amp;gt;&lt;br /&gt;&lt;br /&gt;                &amp;lt;group id=&amp;quot;Text Group&amp;quot; getLabel=&amp;quot;rxDemoGetLabel&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;                    &amp;lt;button id=&amp;quot;btnDemoButton3&amp;quot; &lt;br /&gt;                        label=&amp;quot;Text Wrap&amp;quot; &lt;br /&gt;                        getImage=&amp;quot;WrapText&amp;quot; &lt;br /&gt;                        getSize=&amp;quot;Large&amp;quot; &lt;br /&gt;                        getScreentip=&amp;quot;Button 3&amp;quot; &lt;br /&gt;                        getSupertip=&amp;quot;Format activecell with text wrap&amp;quot;&lt;br /&gt;                        getKeytip=&amp;quot;&amp;quot; &lt;br /&gt;                        onAction=&amp;quot; procButton &amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;/group&amp;gt;&lt;br /&gt;            &amp;lt;/tab&amp;gt;&lt;br /&gt;        &amp;lt;/tabs&amp;gt;&lt;br /&gt;    &amp;lt;/ribbon&amp;gt;&lt;br /&gt;&amp;lt;/customUI&amp;gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;I have used all of the attributes in this example for the buttons, as I prefer to be explicit, not leave to defaults.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;So far, this piece of XML is not too bad. But I find the maintenance of this XML extremely tedious, adding more controls and/or changing any of the attributes of these controls can be long winded and extremely error prone. The tools for creating and maintaining the XML are very limited, the best is the CustomUI Editor, but this suffers from having no recent used file list, and has an irritating habit of moving the changed line to the bottom of the window (whoever thought that was a good idea?). Maintaining the XML involves switching between the CustomUI Editor and Excel 2007, and you have to close down the Excel file in between.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;Because of this, I have adopted the practice of not putting any of the values within the XML, but rather I use callback code to set the values. As an example, instead a line such as&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;label=&amp;quot;Text Wrap&amp;quot;&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;I would setup the XML as follows&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;getLabel=&amp;quot;rxDemoGetLabel&amp;quot;&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;and within my Excel file I would have a procedure that loads that label, such as&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;Public Function rxDemoGetLabel(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;tabDemo&amp;quot;:                    returnedVal = &amp;quot;Ribbon Demo&amp;quot;&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;
I do this for all labels, and the other attributes Image, ImageSize and so on (onAction has to be a callback of course).
Using this technique, the XML code now looks like&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;customUI xmlns=&amp;quot;http://schemas.microsoft.com/office/2006/01/customui&amp;quot; onLoad=&amp;quot;rxDemoRibbonOnLoad&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;ribbon startFromScratch=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;tabs&amp;gt;&lt;br /&gt;            &amp;lt;tab id=&amp;quot;tabDemo&amp;quot; getLabel=&amp;quot;rxDemoGetLabel&amp;quot; insertAfterMso=&amp;quot;TabHome&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;                &amp;lt;group id=&amp;quot;grpDemoGroup1&amp;quot; getLabel=&amp;quot; rxDemoGetLabel &amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;                    &amp;lt;button id=&amp;quot;btnDemoButton1&amp;quot; &lt;br /&gt;                        getLabel=&amp;quot;rxDemoGetLabel&amp;quot; &lt;br /&gt;                        getImage=&amp;quot;rxDemoGetImage&amp;quot; &lt;br /&gt;                        getSize=&amp;quot;rxDemoGetImageSize&amp;quot; &lt;br /&gt;                        getScreentip=&amp;quot;rxDemoGetScreenTip&amp;quot; &lt;br /&gt;                        getKeytip=&amp;quot;rxDemoGetKeyTip&amp;quot; &lt;br /&gt;                        onAction=&amp;quot;rxDemoGetAction&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;                    &amp;lt;button id=&amp;quot;btnDemoButton2&amp;quot; &lt;br /&gt;                        getLabel=&amp;quot;rxDemoGetLabel&amp;quot; &lt;br /&gt;                        getImage=&amp;quot;rxDemoGetImage&amp;quot; &lt;br /&gt;                        getSize=&amp;quot;rxDemoGetImageSize&amp;quot; &lt;br /&gt;                        getScreentip=&amp;quot;rxDemoGetScreenTip&amp;quot; &lt;br /&gt;                        getKeytip=&amp;quot;rxDemoGetKeyTip&amp;quot; &lt;br /&gt;                        onAction=&amp;quot;rxDemoGetAction&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;/group&amp;gt;&lt;br /&gt;&lt;br /&gt;                &amp;lt;group id=&amp;quot;grpDemoGroup2&amp;quot; getLabel=&amp;quot;rxDemoGetLabel&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;                    &amp;lt;button id=&amp;quot;btnDemoButton3&amp;quot; &lt;br /&gt;                        getLabel=&amp;quot;rxDemoGetLabel&amp;quot; &lt;br /&gt;                        getImage=&amp;quot;rxDemoGetImage&amp;quot; &lt;br /&gt;                        getSize=&amp;quot;rxDemoGetImageSize&amp;quot; &lt;br /&gt;                        getScreentip=&amp;quot;rxDemoGetScreenTip&amp;quot; &lt;br /&gt;                        getKeytip=&amp;quot;rxDemoGetKeyTip&amp;quot; &lt;br /&gt;                        onAction=&amp;quot;rxDemoGetAction&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;/group&amp;gt;&lt;br /&gt;            &amp;lt;/tab&amp;gt;&lt;br /&gt;        &amp;lt;/tabs&amp;gt;&lt;br /&gt;    &amp;lt;/ribbon&amp;gt;&lt;br /&gt;&amp;lt;/customUI&amp;gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;This means that I need to change the XML code far less frequently, if I wish to change a label it is all done in code, and so on. Adding a new button or group requires adding to the XML, but the additional code would be very similar to the existing code, just the control type and its id need specific values, so the maintenance is very simple.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;This does mean that we need code to set the attribute values. In the rxDemoGetLabel example above, the tab&amp;rsquo;s label is assigned. As we have more controls with more labels assigned, we need more code to manage them, but this is simple extra case statements. For example&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;Public Function rxDemoGetLabel(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;tabDemo&amp;quot;:                    returnedVal = &amp;quot;Ribbon Demo&amp;quot;&lt;br /&gt;        Case &amp;quot;grpDemoGroup1&amp;quot;:      returnedVal = &amp;quot;Formatting Group&amp;quot;&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      returnedVal = &amp;quot;Currency&amp;quot;&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      returnedVal = &amp;quot;Percentage&amp;quot;&lt;br /&gt;        Case &amp;quot;grpDemoGroup2&amp;quot;:      returnedVal = &amp;quot;Text Group&amp;quot;&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      returnedVal = &amp;quot;Text Wrap&amp;quot;&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;As we can see, the code is very simple, very maintainable. The other callbacks would be very similar.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;One other thing that I do is to create a set of global constants for all of the values, again to make maintenance simpler. For the labels I would have the following set of constants&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;Global Const LABEL_DEMO As String = &amp;quot;Ribbon Demo&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP1_GROUP1 As String = &amp;quot;Formatting Group&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP1_BUTTON1 As String = &amp;quot;Currency&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP1_BUTTON2 As String = &amp;quot;Percentage&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP2_GROUP2 As String = &amp;quot;Text Group&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP2_BUTTON3 As String = &amp;quot;Text Wrap&amp;quot;&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;And the callback code
would be&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;Public Function rxDemoGetLabel(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;tabDemo&amp;quot;:                    returnedVal = LABEL_DEMO&lt;br /&gt;        Case &amp;quot;grpDemoGroup1&amp;quot;:      returnedVal = LABEL_GROUP1_GROUP1&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      returnedVal = LABEL_GROUP1_BUTTON1&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      returnedVal = LABEL_GROUP1_BUTTON2&lt;br /&gt;        Case &amp;quot;grpDemoGroup2&amp;quot;:      returnedVal = LABEL_GROUP2_GROUP2&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      returnedVal = LABEL_GROUP2_BUTTON3&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;I find this a lot
easier to setup, and much simpler to maintain. It does mean that I have to invalidate the ribbon so as to refresh the attributes, but this is done
on opening the file, and should not be noticeable. For info, this is the code I add to invalidate the ribbon&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;Public mgrxDemoIRibbonUI As IRibbonUI&lt;br /&gt;&lt;br /&gt;Public Function rxDemoRibbonOnLoad(ribbon As IRibbonUI)&lt;br /&gt;    Set mgrxDemoIRibbonUI = ribbon&lt;br /&gt;    Call RibbonSetup&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function RibbonSetup()&lt;br /&gt;    mgrxDemoIRibbonUI.Invalidate&lt;br /&gt;End Function&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;The full code for the constants is shown below&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;Option Explicit&lt;br /&gt;&lt;br /&gt;Global Const PROC_GROUP1_BUTTON1 As String = &amp;quot;procButton1&amp;quot;&lt;br /&gt;Global Const PROC_GROUP1_BUTTON2 As String = &amp;quot;procButton2&amp;quot;&lt;br /&gt;Global Const PROC_GROUP2_BUTTON3 As String = &amp;quot;procButton3&amp;quot;&lt;br /&gt;&lt;br /&gt;Global Const LABEL_DEMO As String = &amp;quot;Ribbon Demo&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP1_GROUP1 As String = &amp;quot;Formatting Group&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP1_BUTTON1 As String = &amp;quot;Currency&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP1_BUTTON2 As String = &amp;quot;Percentage&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP2_GROUP2 As String = &amp;quot;Text Group&amp;quot;&lt;br /&gt;Global Const LABEL_GROUP2_BUTTON3 As String = &amp;quot;Text Wrap&amp;quot;&lt;br /&gt;&lt;br /&gt;Global Const IMAGE_GROUP1_GROUP1 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const IMAGE_GROUP1_BUTTON1 As String = &amp;quot;DollarSign&amp;quot;&lt;br /&gt;Global Const IMAGE_GROUP1_BUTTON2 As String = &amp;quot;PercentSign&amp;quot;&lt;br /&gt;Global Const IMAGE_GROUP2_GROUP2 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const IMAGE_GROUP2_BUTTON3 As String = &amp;quot;WrapText&amp;quot;&lt;br /&gt;&lt;br /&gt;Global Const IMAGESIZE_GROUP1_GROUP1 As String = &amp;quot;0&amp;quot;&lt;br /&gt;Global Const IMAGESIZE_GROUP1_BUTTON1 As String = &amp;quot;1&amp;quot;&lt;br /&gt;Global Const IMAGESIZE_GROUP1_BUTTON2 As String = &amp;quot;1&amp;quot;&lt;br /&gt;Global Const IMAGESIZE_GROUP2_GROUP2 As String = &amp;quot;0&amp;quot;&lt;br /&gt;Global Const IMAGESIZE_GROUP2_BUTTON3 As String = &amp;quot;1&amp;quot;&lt;br /&gt;&lt;br /&gt;Global Const SCREENTIP_GROUP1_GROUP1 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const SCREENTIP_GROUP1_BUTTON1 As String = &amp;quot;Button1 &amp;quot;&lt;br /&gt;Global Const SCREENTIP_GROUP1_BUTTON2 As String = &amp;quot;Button 2&amp;quot;&lt;br /&gt;Global Const SCREENTIP_GROUP2_GROUP2 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const SCREENTIP_GROUP2_BUTTON3 As String = &amp;quot;Button 3&amp;quot;&lt;br /&gt;&lt;br /&gt;Global Const SUPERTIP_GROUP1_GROUP1 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const SUPERTIP_GROUP1_BUTTON1 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const SUPERTIP_GROUP1_BUTTON2 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const SUPERTIP_GROUP2_GROUP2 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const SUPERTIP_GROUP2_BUTTON3 As String = &amp;quot;&amp;quot;&lt;br /&gt;&lt;br /&gt;Global Const KEYTIP_GROUP1_GROUP1 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const KEYTIP_GROUP1_BUTTON1 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const KEYTIP_GROUP1_BUTTON2 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const KEYTIP_GROUP2_GROUP2 As String = &amp;quot;&amp;quot;&lt;br /&gt;Global Const KEYTIP_GROUP2_BUTTON3 As String = &amp;quot;&amp;quot;&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;and for the callback code&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;Option Explicit&lt;br /&gt;Option Private Module&lt;br /&gt;&lt;br /&gt;&amp;#39;-----------------------------------------------------------------&lt;br /&gt;&amp;#39; Publicly exposed callbacks&lt;br /&gt;&amp;#39;-----------------------------------------------------------------&lt;br /&gt;&amp;#39; No values are set in the XML apart from ids, all labels, images,&lt;br /&gt;&amp;#39; tooltips and actions are assigned in the callback code&lt;br /&gt;&amp;#39;-----------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Public mgrxDemoIRibbonUI As IRibbonUI&lt;br /&gt;&lt;br /&gt;Public Function rxDemoRibbonOnLoad(ribbon As IRibbonUI)&lt;br /&gt;    Set mgrxDemoIRibbonUI = ribbon&lt;br /&gt;    Call RibbonSetup&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function rxDemoGetAction(control As IRibbonControl)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      Application.Run PROC_GROUP1_BUTTON1&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      Application.Run PROC_GROUP1_BUTTON2&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      Application.Run PROC_GROUP2_BUTTON3&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function rxDemoGetLabel(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;tabDemo&amp;quot;:                    returnedVal = LABEL_DEMO&lt;br /&gt;        Case &amp;quot;grpDemoGroup1&amp;quot;:      returnedVal = LABEL_GROUP1_GROUP1&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      returnedVal = LABEL_GROUP1_BUTTON1&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      returnedVal = LABEL_GROUP1_BUTTON2&lt;br /&gt;        Case &amp;quot;grpDemoGroup2&amp;quot;:      returnedVal = LABEL_GROUP2_GROUP2&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      returnedVal = LABEL_GROUP2_BUTTON3&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function rxDemoGetImage(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      returnedVal = IMAGE_GROUP1_BUTTON1&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      returnedVal = IMAGE_GROUP1_BUTTON2&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      returnedVal = IMAGE_GROUP2_BUTTON3&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function rxDemoGetImageSize(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      returnedVal = IMAGESIZE_GROUP1_BUTTON1&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      returnedVal = IMAGESIZE_GROUP1_BUTTON2&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      returnedVal = IMAGESIZE_GROUP2_BUTTON3&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function rxDemoGetScreentip(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;grpDemoGroup1&amp;quot;:      returnedVal = SCREENTIP_GROUP1_GROUP1&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      returnedVal = SCREENTIP_GROUP1_BUTTON1&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      returnedVal = SCREENTIP_GROUP1_BUTTON2&lt;br /&gt;        Case &amp;quot;grpDemoGroup2&amp;quot;:      returnedVal = SCREENTIP_GROUP2_GROUP2&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      returnedVal = SCREENTIP_GROUP2_BUTTON3&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function rxDemoGetSupertip(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;grpDemoGroup1&amp;quot;:      returnedVal = SUPERTIP_GROUP1_GROUP1&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      returnedVal = SUPERTIP_GROUP1_BUTTON1&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      returnedVal = SUPERTIP_GROUP1_BUTTON2&lt;br /&gt;        Case &amp;quot;grpDemoGroup2&amp;quot;:      returnedVal = SUPERTIP_GROUP2_GROUP2&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      returnedVal = SUPERTIP_GROUP2_BUTTON3&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function rxDemoGetKeytip(control As IRibbonControl, ByRef returnedVal)&lt;br /&gt;    Select Case control.Id&lt;br /&gt;        Case &amp;quot;grpDemoGroup1&amp;quot;:      returnedVal = KEYTIP_GROUP1_GROUP1&lt;br /&gt;        Case &amp;quot;btnDemoButton1&amp;quot;:      returnedVal = KEYTIP_GROUP1_BUTTON1&lt;br /&gt;        Case &amp;quot;btnDemoButton2&amp;quot;:      returnedVal = KEYTIP_GROUP1_BUTTON2&lt;br /&gt;        Case &amp;quot;grpDemoGroup2&amp;quot;:      returnedVal = KEYTIP_GROUP2_GROUP2&lt;br /&gt;        Case &amp;quot;btnDemoButton3&amp;quot;:      returnedVal = KEYTIP_GROUP2_BUTTON3&lt;br /&gt;    End Select&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function RibbonSetup()&lt;br /&gt;    mgrxDemoIRibbonUI.Invalidate&lt;br /&gt;End Function&lt;br /&gt;&lt;/pre&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;I think you can see this is a simpler method than holding the attribute values in the XML, all of the working code is in one place, and it makes for easier setup and maintenance.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;This overall approach requires the setting of all of the values for the global constants and the code. In a future post I will describe how I have automated this.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item><item><title>Using Linq with Microsoft Word and Excel</title><link>http://msmvps.com/blogs/deborahk/archive/2009/08/14/using-linq-with-microsoft-word-and-excel.aspx</link><pubDate>Fri, 14 Aug 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1715753</guid><dc:creator>DeborahK</dc:creator><description>&lt;p&gt;Some of the collections in the Microsoft Office object models implement IEnumerable. The IEnumerable interface provides the ability to perform a for/each against the collection. With .NET 3.5, a Cast extension method of IEnumerable allows you to work with these collections using Linq.&lt;/p&gt;  &lt;h2&gt;Microsoft Word&lt;/h2&gt;  &lt;p&gt;For example, say you want to bind the set of open Word document names in a ComboBox.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Add to the top of the code file     &lt;br /&gt;using Word = Microsoft.Office.Interop.Word;      &lt;br /&gt;      &lt;br /&gt;// Add to a subroutine      &lt;br /&gt;Word.Application Wd;      &lt;br /&gt;Word.Document doc;      &lt;br /&gt;Word.Document doc2;      &lt;br /&gt;object missingValue = Missing.Value; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Start Word and get Application object     &lt;br /&gt;Wd = new Word.Application(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Define documents     &lt;br /&gt;doc = Wd.Documents.Add(ref missingValue,ref missingValue,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ref missingValue,ref missingValue );      &lt;br /&gt;doc2 = Wd.Documents.Add(ref missingValue, ref missingValue,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ref missingValue, ref missingValue); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Use Linq to access the document names.     &lt;br /&gt;var query = from d in Wd.Documents.Cast&amp;lt;Word.Document&amp;gt;()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select d.Name;      &lt;br /&gt;comboBox1.DataSource = query.ToList(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Or use Lambda expressions     &lt;br /&gt;var query2 = Wd.Documents.Cast&amp;lt;Word.Document&amp;gt;().Select(d=&amp;gt; d.Name);      &lt;br /&gt;comboBox1.DataSource = query2.ToList(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Close     &lt;br /&gt;doc.Close(ref missingValue, ref missingValue, ref missingValue);      &lt;br /&gt;doc = null;      &lt;br /&gt;doc2.Close(ref missingValue, ref missingValue, ref missingValue);      &lt;br /&gt;doc2 = null;      &lt;br /&gt;Wd.Quit(ref missingValue, ref missingValue, ref missingValue); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Clean up     &lt;br /&gt;// NOTE: When in release mode, this does the trick      &lt;br /&gt;GC.WaitForPendingFinalizers();      &lt;br /&gt;GC.Collect();      &lt;br /&gt;GC.WaitForPendingFinalizers();      &lt;br /&gt;GC.Collect() ;&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Add to the top of the code file     &lt;br /&gt;Imports Word = Microsoft.Office.Interop.Word&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Add to a subroutine     &lt;br /&gt;Dim Wd As Word.Application      &lt;br /&gt;Dim doc As Word.Document      &lt;br /&gt;Dim doc2 As Word.Document      &lt;br /&gt;      &lt;br /&gt;&amp;#39; Start Word and get Application object      &lt;br /&gt;Wd = New Word.Application&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Define documents     &lt;br /&gt;doc = Wd.Documents.Add      &lt;br /&gt;doc2 = Wd.Documents.Add &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Use Linq to access the document names.     &lt;br /&gt;Dim query = From d In Wd.Documents.Cast(Of Word.Document)() _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select d.Name      &lt;br /&gt;ComboBox1.DataSource = query.ToList &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Or use Lambda expressions     &lt;br /&gt;Dim query2 = Wd.Documents.Cast(Of Word.Document) _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(Function(d) d.Name)      &lt;br /&gt;ComboBox1.DataSource = query2.ToList &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Close     &lt;br /&gt;doc.Close()      &lt;br /&gt;doc = Nothing      &lt;br /&gt;doc2.Close()      &lt;br /&gt;doc2 = Nothing      &lt;br /&gt;Wd.Quit() &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Clean up     &lt;br /&gt;&amp;#39; NOTE: When in release mode, this does the trick      &lt;br /&gt;GC.WaitForPendingFinalizers()      &lt;br /&gt;GC.Collect()      &lt;br /&gt;GC.WaitForPendingFinalizers()      &lt;br /&gt;GC.Collect()&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In both of these examples, the code starts Word, creates two Word documents, uses either Linq or a Lambda expression to define a query and then binds the resulting set of document names to a Combo Box.&lt;/p&gt;  &lt;p&gt;Notice the missingValue variable in the C# code that is not in the VB code. VB supports default parameters, but C# does not. So any time a parameter is defined for a Word method, C# must provide it. VB will use the default parameter values.&lt;/p&gt;  &lt;p&gt;NOTE: A new feature in C# 4.0 (Visual Studio 2010) allows for default parameters in C# as well, dramatically simplifying the C# code that interacts with Word or Excel.&lt;/p&gt;  &lt;p&gt;As another example, the following code retrieves all of the words from the defined Word document.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt; &lt;font color="#65402e" face="Consolas"&gt;var query = from w in doc.Words.Cast&amp;lt;Word.Range&amp;gt;()   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select w.Text;    &lt;br /&gt;comboBox1.DataSource = query.ToList();&lt;/font&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim query = From w In doc.Words.Cast(Of Word.Range)() _     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select w.Text      &lt;br /&gt;ComboBox1.DataSource = query3.ToList&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This code retrieves all of the words in the document defined by the doc variable. Instead of selecting the list of words, you could use any Linq feature such as finding only a specific set of words that match a criteria or counting the number of occurrences of a given word.&lt;/p&gt;  &lt;h2&gt;Microsoft Excel&lt;/h2&gt;  &lt;p&gt;This technique works with Excel as well. Say you want to bind the list of spreadsheets in an Excel workbook.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Add to the top of the code file     &lt;br /&gt;using Excel = Microsoft.Office.Interop.Excel;      &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Add to a subroutine     &lt;br /&gt;Excel.Application oXL;      &lt;br /&gt;Excel.Workbook oWB;      &lt;br /&gt;Excel.Worksheet oSheet;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Start Excel and get Application object.     &lt;br /&gt;oXL = new Excel.Application(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Get a new workbook.     &lt;br /&gt;oWB = oXL.Workbooks.Add(Missing.Value); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Get the active sheet and change its name     &lt;br /&gt;oSheet = (Excel.Worksheet)oWB.ActiveSheet ;      &lt;br /&gt;oSheet.Name = &amp;quot;Test&amp;quot;;      &lt;br /&gt;      &lt;br /&gt;// Use Linq to access the spreadsheet names.      &lt;br /&gt;var query = from s in oXL.Worksheets.Cast&amp;lt;Excel.Worksheet&amp;gt;()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select s.Name;      &lt;br /&gt;comboBox1.DataSource = query.ToList(); &lt;/font&gt;&lt;/p&gt; &lt;font color="#65402e" face="Consolas"&gt;// Or use Lambda expressions.   &lt;br /&gt;var query2 = oXL.Worksheets.Cast&amp;lt;Excel.Worksheet&amp;gt;()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .select(s =&amp;gt; s.Name);    &lt;br /&gt;comboBox1.DataSource = query2.ToList(); &lt;/font&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Close     &lt;br /&gt;oSheet = null;      &lt;br /&gt;oWB.Close(Missing.Value, Missing.Value, Missing.Value);      &lt;br /&gt;oWB = null;      &lt;br /&gt;oXL.Quit(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Clean up     &lt;br /&gt;// NOTE: When in release mode, this does the trick      &lt;br /&gt;GC.WaitForPendingFinalizers();      &lt;br /&gt;GC.Collect();      &lt;br /&gt;GC.WaitForPendingFinalizers();      &lt;br /&gt;GC.Collect();&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Add to the top of the code file     &lt;br /&gt;Imports Excel = Microsoft.Office.Interop.Excel &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Add to a subroutine     &lt;br /&gt;Dim oXL As Excel.Application      &lt;br /&gt;Dim oWB As Excel.Workbook      &lt;br /&gt;Dim oSheet As Excel.Worksheet      &lt;br /&gt;      &lt;br /&gt;&amp;#39; Start Excel and get Application object.      &lt;br /&gt;oXL = New Excel.Application      &lt;br /&gt;      &lt;br /&gt;&amp;#39; Get a new workbook.      &lt;br /&gt;oWB = oXL.Workbooks.Add      &lt;br /&gt;      &lt;br /&gt;&amp;#39; Get the active sheet and change its name      &lt;br /&gt;oSheet = DirectCast(oWB.ActiveSheet, Excel.Worksheet)      &lt;br /&gt;oSheet.Name = &amp;quot;Test&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Use Linq to access the spreadsheet names.     &lt;br /&gt;Dim query = From s In oXL.Worksheets.Cast(Of Excel.Worksheet)() _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select s.Name      &lt;br /&gt;ComboBox1.DataSource = query.ToList      &lt;br /&gt;      &lt;br /&gt;&amp;#39; Or use Lambda expressions      &lt;br /&gt;Dim query2 = oXL.Worksheets.Cast(Of Excel.Worksheet) _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(Function(s) s.Name)      &lt;br /&gt;ComboBox1.DataSource = query2.ToList&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Close     &lt;br /&gt;oSheet = Nothing      &lt;br /&gt;oWB.Close()      &lt;br /&gt;oWB = Nothing      &lt;br /&gt;oXL.Quit()      &lt;br /&gt;      &lt;br /&gt;&amp;#39; Clean up      &lt;br /&gt;&amp;#39; NOTE: When in release mode, this does the trick      &lt;br /&gt;GC.WaitForPendingFinalizers()      &lt;br /&gt;GC.Collect()      &lt;br /&gt;GC.WaitForPendingFinalizers()      &lt;br /&gt;GC.Collect()&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In both examples, the code starts Excel, changes the name of the active sheet, uses either Linq or a Lambda expression to define a query and then binds the resulting set of sheet names to a Combo Box.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>The End Of VBA</title><link>http://msmvps.com/blogs/xldynamic/archive/2009/08/14/the-end-of-vba.aspx</link><pubDate>Fri, 14 Aug 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1715568</guid><dc:creator>bobphillips</dc:creator><description>&lt;p&gt;The title was just to get your attention, it really should be entitled something along the lines of &amp;ldquo;What Made VBA The Success It Is Today?&amp;rsquo;, as this post is more about what VBA is and isn&amp;#39;t, albeit somewhat precipitated by the thought that VBA must be close to its end game.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I recently saw a thread in a forum where one of the responses was along the lines that &amp;quot;VBA was not designed for programmers - i.e. MS dumbed down requirements ...&amp;quot;. I found this to be a very facile argument and said so in my response. I won&amp;#39;t bother retracing that thread here, but I thought it raises an interesting question.&lt;br /&gt;&lt;br /&gt;When MicroSoft introduced VBA into Office, just what was their objective, how did they envisage its use, and what concessions did they make in their implementation? BTW, although it was introduced into Office, I will concentrate solely on Excel, for obvious reasons.&lt;br /&gt;&lt;br /&gt;Although Excel already had a macro language, these were not the easiest to use, and so, for whatever reason that it was done, introducing VBA into Excel 97 was a masterstroke, it opened all sorts of possibilities to Excel users. Like all projects, I am sure that MS&amp;#39; implementation of VBA had some key must-do objectives, some secondary should do objectives, and some nice to haves; some of those objectives would be customer focussed (such as giving users a simpler development tool), some would be MS focussed (for example, as it was a superset of VB, they would probably want to keep it as closely aligned to VB as is possible, controlling development and maintenance costs). And like all projects, the timeframes and the budgets would be balanced, large enough to suggest that a great product was achievable within the projects&amp;nbsp; goals, but not so large that everything was easy and achievable - that is just the way of the world.&lt;br /&gt;&lt;br /&gt;I have no inside knowledge, but I would think that when MS decided to give the world VBA, they were not looking at IT shops, they were specifically looking to give real users extra capability. They probably anticipated macros that formatted worksheets, shunted data around a sheet/book, all of the standard, simple one-off macro solutions. I very much doubt that they anticipated quite how its usage would take-off, how Excel especially has morphed into a development platform capable of running highly complex applications. &lt;/p&gt;
&lt;p&gt;The sheer creativity and inventiveness displayed in VBA is staggering. In Excel alone, there have been some amazing development, from the simple to the hugely complex. We have seen&amp;nbsp; a whole gamut of solutions, for example&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; simple, but highly effective, tools that make using Excel functions simpler, such as Rob Bovey&amp;#39;s &lt;a target="_blank" title="Chart Labeller" href="http://www.appspro.com/Utilities/ChartLabeler.htm"&gt;Chart Labeller &lt;/a&gt;&lt;/li&gt;
&lt;li&gt; tools that extend Excel&amp;#39;s native functionality and help spreadsheet users to use Excel more efficiently, such as Jan Karel Pieterse&amp;#39;s &lt;a target="_blank" title="NameManager" href="http://www.jkp-ads.com/OfficeMarketPlaceNM-EN.asp"&gt;NameManager &lt;/a&gt;&lt;/li&gt;
&lt;li&gt; true developer tools for spreadsheet users that help better spreadsheet development, such as Charles Williams &lt;a target="_blank" title="FastExcel" href="http://www.decisionmodels.com/fastexcel.htm"&gt;FastExcel &lt;/a&gt;&lt;/li&gt;
&lt;li&gt; some incredible tools that do things previously thought not possible, many such examples but a classic is Stephen Bullen&amp;#39;s &lt;a target="_blank" title="PastePicture" href="http://www.oaltd.co.uk/Excel/Default.htm"&gt;PastePicture &lt;/a&gt;&lt;/li&gt;
&lt;li&gt; giving us back functions that we used to have, such as Andy Pope&amp;#39;s &lt;a target="_blank" title="Pattern Filler" href="http://www.andypope.info/charts/patternfills.htm"&gt;Pattern Filler&lt;/a&gt; utility in Excel 2007 &lt;/li&gt;
&lt;li&gt; database applications where Excel is providing a presentation and data management layer, and a database, Access or SQL Server, maintains the data and provides the richness of a relational database&lt;/li&gt;
&lt;li&gt; ETL applications where Excel harvests data from disparate sources to provide a composite picture, using tables, charts, dashboards etc.&lt;/li&gt;
&lt;li&gt; end-to-end data capture, data management, and reporting applications using multiple technologies and multiple layers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;What is even more impressive is that these solution have often been produced by one man outfits, no big IT departments to support the developer here, and often by developers that are mainly business users, people who would never claim to be coders (one of the best Sparklines implementations I have seen was by a guy who made no claim to being a coder, indeed he said that he built this implementation to help develop his VBA skills).&lt;br /&gt;&lt;br /&gt;Did MS envisage all of this when they were looking to add VBA? Maybe, but somehow I doubt it. As I said previously, users building macros to automate a few tasks, formatting, capturing data, and so on, is a far more realistically envisaged deployment, presumably they felt that just bringing VB into the Office apps would be a lot simpler for users to get to grips with. If they had envisaged all of this use, I would have hoped that they would have been far more ambitious in their objectives, but I don&amp;#39;t believe this so it is a sterile argument for me.&lt;br /&gt;&lt;br /&gt;As I mentioned above, VBA would have been a project, and as such, it would have been subject to typical project constraints. This must have meant that, throughout the course of the project, implementation decisions would have had to be made. Some of these decisions probably resulted in cutting or constraining some of the functionality that was originally envisaged. I am sure this would have been done for all of the right reasons, and that the VBA developers and project leaders would have justified it in their minds, always taking into consideration what they knew or thought at that time. Sitting here in 2009, we might argue that some of those constraints were ill-advised, but that is hindsight, and it is certainly worlds away from saying that MS dumbed down VBA.&lt;br /&gt;&lt;br /&gt;Sure there are some things that are better in VB than they are in VB6.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; forms are better in VB, you have a built-in menu facility, and control arrays, but both of these can be emulated in VBA, with varying degrees of success and completeness&lt;/li&gt;
&lt;li&gt; you can create stand-alone executables in VB6, but not in VBA - this is true but when VBA was introduced I am sure this was not even a consideration, without being able to foresee the types of addins deployed today and the security issues that have manifested, it seems impossible to think back then that this was necessary or even desirable&lt;/li&gt;
&lt;li&gt; packaging and deploying - again, VBA is by default packaged within its host container application, targeted at individual users, how could MS have envisaged this need, and anyway, there are many good third party tools that provide this capability&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;Some things are simpler in VBA, working with Excel for example in Excel, by virtue of its implementation, just as some things are harder by virtue of its implementation.&lt;br /&gt;&lt;br /&gt;Acknowledging some things are easier in VB is a completely different matter from saying that MS dumbed down VBA. I no more believe that MS deliberately dumbed down VBA than I believe that many of the techniques that have been developed over the years to make Excel such a versatile development platform were deliberately introduced by MS, it is just consequences of the original implementation.&lt;br /&gt;&lt;br /&gt;To me, this is a relevant topic today as we stand on the brink of moving, either willingly or not so willingly, to the .Net world. It originally struck me that MS were not prepared to make any concessions to the world of VBA and the millions of users that have built solutions using VBA. My impression was that they were trying to dig their heels in and say that it is .Net in the future or nothing. I believe that attitude has changed somewhat, not enough yet, but at least they concede that these users have to be accommodated or else they just will not, or cannot, upgrade. The interesting thing will be to look back in 5 years time and reflect on what we think that MS have and have not done well in introducing .Net into Office. I for one feel that we are on the brink of a much better experience with .Net, and am cautiously looking forward to it.&lt;br /&gt;&lt;br /&gt;In the meantime, let us all celebrate VBA, the way it has been stretched, bent and moulded over the years by the thousands of real users who just wanted to be able to do something, and do it today; by talented Excel developers like those mentioned above, and by all of the &amp;#39;novice users&amp;#39; who have dared to try and do something in Excel and VBA that helped them to work faster, less, and/or better. Of course, there have been some horror stories along the way, I have seen a few myself, but there have been many successes. Excel has not become the de-facto application development platform that it is today (what other desktop application could have a book like &lt;a target="_blank" title="PED" href="http://www.oaltd.co.uk/ProExcelDev/Default.htm"&gt;PED&lt;/a&gt; written about it?) because MS dumbed down VBA, but because Excel has an incredible function set, and VBA has exposed that function set to all manner of users, and it is they that have shown the world just what is possible.&lt;/p&gt;</description></item></channel></rss>