<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Grumpy Old Programmer</title>
	<atom:link href="http://grumpyop.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://grumpyop.wordpress.com</link>
	<description>He's old, he's a programmer and he's grumpy</description>
	<lastBuildDate>Sun, 29 Jan 2012 12:03:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='grumpyop.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Grumpy Old Programmer</title>
		<link>http://grumpyop.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://grumpyop.wordpress.com/osd.xml" title="Grumpy Old Programmer" />
	<atom:link rel='hub' href='http://grumpyop.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Split Me, Shape Me</title>
		<link>http://grumpyop.wordpress.com/2011/10/04/split-me-shape-me/</link>
		<comments>http://grumpyop.wordpress.com/2011/10/04/split-me-shape-me/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 10:07:21 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=858</guid>
		<description><![CDATA[in which we publish something we wrote a while back but forgot to post for reasons now lost in the mists of time While I&#8217;d love to be able to take credit for having thought of this myself, the truth is I can&#8217;t. I did clean up the code a fair bit, though, so any [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=858&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h6><em>in which we publish something we wrote a while back but forgot to post for reasons now lost in the mists of time</em></h6>
<p>While I&#8217;d love to be able to take credit for having thought of this myself, the truth is I can&#8217;t. I did clean up the code a fair bit, though, so any tidiness that particularly appeals is entirely down to me.</p>
<p>Reading <a href="http://chandoo.org/wp/2011/08/23/split-text-on-new-line-macro">this post</a> a while back, I leapt to post my CellSplit() function in the comments, then realised that I typically use it in conjunction with a rather more substantial macro, one that wasn&#8217;t going to sit well in someone else&#8217;s blog comments.</p>
<p>Here&#8217;s my CellSplit(), which is just a wrapper for the VBA Split() function:</p>
<p><pre class="brush: vb;">
Public Function CellSplit(celValue As String, delim As String) As Variant
    CellSplit = Split(celValue, delim)
End Function
</pre></p>
<p>On its own, it&#8217;s moderately useful, but unless you know how many parts your input string will split into, you&#8217;re going to be fooling about with range resizing. In these dark days there&#8217;s no time for fooling about &#8211; we need a tool to get that resizing down for us in One Click.</p>
<p><a href="http://grumpyop.files.wordpress.com/2011/10/xl_range_resize.png"><img class="alignnone size-full wp-image-875" title="xl_range_resize" src="http://grumpyop.files.wordpress.com/2011/10/xl_range_resize.png?w=630" alt=""   /></a></p>
<p>Enter a toolbar (sorry, RibbonX) button, assigned to the Range Resize Wizard&#8230;</p>
<p><pre class="brush: vb;">
Public Sub RangeResizeWizard()

Dim result As Variant
Dim fmla As String
Dim rng As range
Dim targetRows As Long
Dim targetCols As Long

On Error GoTo Catch

Set rng = Selection
If IsEmpty(rng) Then Exit Sub

If rng.HasArray Then
  Set rng = rng.CurrentArray
  fmla = rng.FormulaArray
ElseIf rng.rows.Count = 1 And rng.Columns.Count = 1 Then
  fmla = rng.Formula
Else
  Exit Sub
End If

result = Evaluate(fmla)

With rng
  .ClearContents
  If IsArray(result) Then
    If NumberOfDimensions(result) = 2 Then
      targetRows = UBound(result, 1) - LBound(result, 1) + 1
      targetCols = UBound(result, 2) - LBound(result, 2) + 1
    Else
      targetRows = 1
      targetCols = UBound(result, 1) - LBound(result, 1) + 1
    End If
    On Error GoTo RestoreFormula:
    .Resize(targetRows, targetCols).FormulaArray = fmla
    On Error GoTo Catch
  Else
    .Formula = fmla
  End If
End With

Finally:
  On Error GoTo 0
  Exit Sub

Catch:
  Debug.Print Err.Description
  Resume Finally

RestoreFormula:
  Debug.Print Err.Description
  rng.FormulaArray = fmla
  Resume Finally
End Sub

Function NumberOfDimensions(arr As Variant)

Dim dimensions As Long
Dim junk As Long

On Error GoTo FinalDimension

For dimensions = 1 To 60000
  junk = LBound(arr, dimensions)
Next
Exit Function

FinalDimension:
  NumberOfDimensions = dimensions - 1
End Function
</pre></p>
<p>Note that the array formula in question will be re-evaluated twice, once to determine the dimensions of the output array and again when the formula is pushed back into the new, perfectly-sized range. Further, the routine assumes you haven&#8217;t left anything important lying around where it can get overwritten. So it&#8217;s to be used with care, but if you spend much time with array formula, you&#8217;ll probably find it as useful as I do (if you haven&#8217;t already written it yourself).</p>
<p>Note further that it&#8217;s not really a &#8220;wizard&#8221; in the programming sense, in that it doesn&#8217;t do any of that walking-you-through-steps thing. It&#8217;s just a bit magic.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/858/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/858/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/858/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/858/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/858/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/858/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/858/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/858/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/858/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/858/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/858/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/858/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/858/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/858/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=858&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2011/10/04/split-me-shape-me/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2011/10/xl_range_resize.png" medium="image">
			<media:title type="html">xl_range_resize</media:title>
		</media:content>
	</item>
		<item>
		<title>My (Im)perfect Cousin?</title>
		<link>http://grumpyop.wordpress.com/2011/08/01/my-imperfect-cousin/</link>
		<comments>http://grumpyop.wordpress.com/2011/08/01/my-imperfect-cousin/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 11:52:52 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[just plain weird]]></category>
		<category><![CDATA[War Stories]]></category>
		<category><![CDATA[Wise Old Programmer]]></category>
		<category><![CDATA[inspiration]]></category>
		<category><![CDATA[methodologies]]></category>
		<category><![CDATA[miscellaneous]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=810</guid>
		<description><![CDATA[in which we start to worry about the source of our inspiration Mona Lisa Vito: So what&#8217;s your problem? Vinny Gambini: My problem is, I wanted to win my first case without any help from anybody. Lisa: Well, I guess that plan&#8217;s moot. Vinny: Yeah. Lisa: You know, this could be a sign of things [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=810&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h6><em>in which we start to worry about the source of our inspiration</em></h6>
<dl>
<dd><strong>Mona Lisa Vito</strong>: So what&#8217;s your problem?</dd>
<dd><strong>Vinny Gambini</strong>: My problem is, I wanted to win my first case without any help from anybody.</dd>
<dd><strong>Lisa</strong>: Well, I guess that plan&#8217;s moot.</dd>
<dd><strong>Vinny</strong>: Yeah.</dd>
<dd><strong>Lisa</strong>: You know, this could be a sign of things to come. You win all your cases, but with somebody else&#8217;s help. Right? You win case, after case, &#8211; and then afterwards, you have to go up somebody and you have to say- &#8220;<em>thank you</em>&#8220;! <em>Oh my God, what a fuckin&#8217; nightmare!</em></dd>
</dl>
<p><a href="http://grumpyop.files.wordpress.com/2011/04/vinny_mlvito.jpg"><img class="alignleft size-full wp-image-812" title="Our hero and his muse" src="http://grumpyop.files.wordpress.com/2011/04/vinny_mlvito.jpg?w=630" alt=""   /></a></p>
<hr />
<p>It is one of the all-time great movies, and netted <a href="http://www.imdb.com/name/nm0000673/">Marisa Tomei</a> an Oscar in the process. Yes it is. It really is<sup>1</sup>.</p>
<p>Not only that, but <a href="http://www.imdb.com/title/tt0104952/">My Cousin Vinny</a><sup>2</sup> throws up parallels in real life all the time. Yes it does. It really does<sup>3</sup>.</p>
<p>Why only recently, I was puzzling over the best (or least worst) way to implement a particularly nonsensical requirement for an intransigent client. After summarising the various unpalatable options in an email, a reply arrived from a generally unproductive source. The message content made it obvious that he&#8217;d somewhat missed the point but the conclusion he drew from that misunderstanding triggered a new thought process that gave us a new, even less, er, worser solution to our problem.</p>
<p>Sadly, my unwitting muse has moved on now, but he left his mark for all time<sup>4</sup> on our latest product. I suppose he should also take partial credit for the creation of a hitherto unknown development methodology: Powerpoint-Driven Development, but that&#8217;s a story for another day.</p>
<hr />
<p><sup>1</sup> All right, <a href="http://en.wiktionary.org/wiki/IMHO">IMHO</a><br />
<sup>2</sup> See also <a href="http://www.thedailycontributor.com/how-to-use-quotes-from-my-cousin-vinny-at-work.html">My Cousin Vinny At Work, application of quotes therefrom</a><br />
<sup>3</sup> <a href="http://en.wiktionary.org/wiki/your_mileage_may_vary">YMMV</a>.<br />
<sup>4</sup> Or at least until we have a better idea and change the whole damn thing</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/810/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/810/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/810/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/810/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/810/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/810/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/810/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/810/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/810/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/810/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/810/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/810/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/810/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/810/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=810&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2011/08/01/my-imperfect-cousin/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2011/04/vinny_mlvito.jpg" medium="image">
			<media:title type="html">Our hero and his muse</media:title>
		</media:content>
	</item>
		<item>
		<title>Pin Me Up, Pin Me Down</title>
		<link>http://grumpyop.wordpress.com/2011/04/27/pin-me-up-pin-me-down/</link>
		<comments>http://grumpyop.wordpress.com/2011/04/27/pin-me-up-pin-me-down/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 15:29:42 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[2007]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[useful]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=820</guid>
		<description><![CDATA[(in which we return to VBA for a Small But Useful macro-writing session) My friend Jens comes up with interesting questions. Even better, he doesn&#8217;t come up with them too often. Today&#8217;s poser refers to Excel 2007, a technological marvel that has only reached our work PCs relatively recently. Jens had discovered the Usefulness that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=820&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h6><em>(in which we return to VBA for a Small But Useful macro-writing session)</em></h6>
<p>My friend Jens comes up with interesting questions. Even better, he doesn&#8217;t come up with them <em>too</em> often.</p>
<p>Today&#8217;s poser refers to Excel 2007, a technological marvel that has only reached our work PCs relatively recently. Jens had discovered the Usefulness that is the &#8220;pin&#8221; tool on the &#8220;Recent Documents&#8221; list:</p>
<p><a href="http://grumpyop.files.wordpress.com/2011/04/excelfilemenu1.png"><img class="size-full wp-image-823 aligncenter" title="Before" src="http://grumpyop.files.wordpress.com/2011/04/excelfilemenu1.png?w=630" alt=""   /></a></p>
<p>So the pinned documents don&#8217;t go away, but they do move around on the list, rising up when used, drifting down as lesser workbooks are opened. What Jens wanted was to have his pinned files stay at the top. Or the bottom. Either, really, providing they hung around together.</p>
<p>We couldn&#8217;t find anything in Options, Advanced or otherwise, and some Googling didn&#8217;t turn up much of use<sup>1</sup> and at time of writing (admittedly not too long ago) I hadn&#8217;t got any useful feedback on <a href="http://stackoverflow.com/questions/5804347">Stackoverflow</a>. Time to apply a different set of talents.</p>
<p>Excel has <a href="http://msdn.microsoft.com/en-us/library/ys54s867.aspx">Application.RecentFiles</a>, which does pretty much what it suggests. Even better, the &#8220;.Add&#8221; method, when called with a file that&#8217;s already on the list, promotes that file to the top. If we could call that method for the pinned files, we&#8217;d be laughing. If we could identify them. It turns out we can.</p>
<p>Excel has to store the list somewhere so it can find it when restarting. Where do &#8220;modern&#8221; Windows programs store that kind of information? The registry<sup>2</sup>. Specifically, &#8220;HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\File MRU&#8221;, where MRU stands, most likely, for Most Recently Used. My registry has 50 entries here, probably reflecting that Advanced Excel Options allows me to display up to 50 documents, screen real estate permitting.</p>
<p><a href="http://grumpyop.files.wordpress.com/2011/04/excelshow50docs.png"><img class="size-full wp-image-824 aligncenter" title="ExcelShow50Docs" src="http://grumpyop.files.wordpress.com/2011/04/excelshow50docs.png?w=630" alt=""   /></a></p>
<p>So looking at the entries, we see that there&#8217;s one string for each of our MRU entries and that each string has some structure to it:</p>
<p><a href="http://grumpyop.files.wordpress.com/2011/04/excelfilemruregentries.png"><img class="size-full wp-image-825 aligncenter" title="ExcelFileMRURegEntries" src="http://grumpyop.files.wordpress.com/2011/04/excelfilemruregentries.png?w=630" alt=""   /></a></p>
<p>That first part: &#8220;[F00000001]&#8220;, is particularly interesting: the last digit is a &#8220;1&#8243; for all the files we&#8217;ve marked as pinned. So we can identify pinned files. All we need now is to be able to read the registry from VBA. We can&#8217;t use &#8220;GetSetting&#8221; because it&#8217;s limited in scope. More Googling and we discover that the Windows Scripting Host knows about registries so we add a reference to &#8220;Windows Script Host Object model&#8221; in order to be able to early-bind to WshShell.</p>
<p>So here&#8217;s the first attempt. Probably heaps of unhandled situations, but right now it works on my machine&#8230;</p>
<p><pre class="brush: vb;">
Public Sub PromotePinnedFiles()

Const KEY_ROOT = &quot;HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\File MRU\Item &quot;

Dim itemIndex As Long
Dim itemData As String
Dim itemPath As String

On Error Resume Next ' general-purpose error-ignoring

With New WshShell ' Or use CreateObject(&quot;WScript.Shell&quot;) if reference not set
 For itemIndex = 1 To 50 ' I think 50 is the most Excel will store
  itemData = .RegRead(KEY_ROOT &amp; itemIndex) ' get the item (ignoring errors if fewer than 50 present)
  If Len(itemData) &gt; 0 Then
   If InStr(itemData, &quot;*&quot;) &gt; 0 Then
    If Mid(itemData, 10, 1) = &quot;1&quot; Then
     itemPath = Mid(itemData, InStr(itemData, &quot;*&quot;) + 1)
     Application.RecentFiles.Add itemPath ' &quot;promotes&quot; the item to #1 in the list
    End If
   End If
  End If
 Next
End With

End Sub

</pre></p>
<p>The effect of which is this:</p>
<p><a href="http://grumpyop.files.wordpress.com/2011/04/excelfilemenu2.png"><img class="size-full wp-image-832 aligncenter" title="ExcelFileMenu2" src="http://grumpyop.files.wordpress.com/2011/04/excelfilemenu2.png?w=630" alt=""   /></a></p>
<p>It just remains to decide how best to package it for my learned colleague.</p>
<hr />
<p><sup>1</sup> Inevitably, there will be any number of comments telling me precisely where I should have looked.<br />
<sup>2</sup> Readers who answered &#8220;INI files&#8221; are invited to remove themselves to the back of the classroom, where the machines are still running Excel 3.0.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/820/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=820&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2011/04/27/pin-me-up-pin-me-down/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2011/04/excelfilemenu1.png" medium="image">
			<media:title type="html">Before</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2011/04/excelshow50docs.png" medium="image">
			<media:title type="html">ExcelShow50Docs</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2011/04/excelfilemruregentries.png" medium="image">
			<media:title type="html">ExcelFileMRURegEntries</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2011/04/excelfilemenu2.png" medium="image">
			<media:title type="html">ExcelFileMenu2</media:title>
		</media:content>
	</item>
		<item>
		<title>This Wheel Goes To Eleven</title>
		<link>http://grumpyop.wordpress.com/2011/03/25/this-wheel-goes-to-eleven/</link>
		<comments>http://grumpyop.wordpress.com/2011/03/25/this-wheel-goes-to-eleven/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 14:55:42 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[dotNET]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=784</guid>
		<description><![CDATA[(in which we make an unexpected connection regarding the D in SOLID and get all hot under the collar about it) Let&#8217;s not beat about the bush: I think I may have reinvented Dependency Injection. While it looks rather casual, stated like that, I&#8217;ve actually spent much of the last six months doing it. (Were [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=784&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h6><em>(in which we make an unexpected connection regarding the <a href="http://www.objectmentor.com/resources/articles/dip.pdf">D</a> in <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">SOLID</a> and get all hot under the collar about it)</em></h6>
<p>Let&#8217;s not beat about the bush: I think I may have reinvented <a href="http://en.wikipedia.org/wiki/Dependency_injection">Dependency Injection</a>. While it looks rather casual, stated like that, I&#8217;ve actually spent much of the last six months doing it. (Were you wondering? Well, that.)</p>
<p>I&#8217;ve been designing/building/testing/ripping apart/putting back together again a library/app/framework/tool thing that allows us to assemble an asset allocation algorithm for each of our ten or so products<sup>1</sup>, each of which may have been modified at various times since inception. It&#8217;s been interesting and not a little fun, plus I&#8217;ve been climbing the C# learning curve (through the three versions shipped since my last serious exposure) like <a href="http://www.bonington.com">Chris Bonnington</a> on amphetamines.</p>
<p>Our products are broadly similar but differ in detail in some places. So there&#8217;s <a href="http://grumpyop.files.wordpress.com/2011/01/productfeaturematrix.png"><img class="alignright size-full wp-image-787" title="ProductFeatureMatrix" src="http://grumpyop.files.wordpress.com/2011/01/productfeaturematrix.png?w=630" alt=""   /></a>lots of potential for reuse, but no real hierarchy (if you can see a hierarchy in the little chart here, trust me, it&#8217;s not real).</p>
<p>So Product A need features 1, 2 &amp; 3, in that order. B needs 1 &amp; 4, C 1, 3 &amp; 5, etc. What I came up with was to encapsulate each feature in a class, each class inheriting from a common interface. Call it IFeature or some such. At run-time, I can feed my program an XML file (or something less ghastly perhaps) that says which classes I need (and potentially the assemblies in which they may be found), applying the wonder that is <a href="http://msdn.microsoft.com/en-us/library/system.reflection.aspx">System.Reflection</a> to load the specified assembles and create instances of the classes I need, storing them in, for example, a List&lt;IFeature&gt;. To run my algorithm, all I need to do is call the method defined in my interface on each object in turn. A different product, or a new version of an existing one has a different specification and it Should <a href="http://c2.com/cgi/wiki?ItJustWorks">Just Work</a>.</p>
<p>It&#8217;s all very exciting.</p>
<p>So changing a single feature of an existing product means writing one new class that implements the standard interface and pointing the product definition at the library that contains the new class (which may &#8211; should &#8211; be different from those already in use).</p>
<p>The discerning reader may, er, discern that there are elements of <a href="http://www.dofactory.com/Patterns/PatternStrategy.aspx">Strategy</a> and <a href="http://www.dofactory.com/Patterns/PatternCommand.aspx">Command</a> patterns in here as well. Aren&#8217;t we modern?</p>
<p>While all this is very exciting (to me at least &#8211; a profound and disturbing symptom of work-life imbalance) it&#8217;s still not the end of the line. I&#8217;ve built functions and then chosen to access them serially, relying on carefully (or tricky &amp; tedious) XML definitions to dictate sequence. I&#8217;m thinking that I can go a long way further into declarative/functional territory, possibly gaining quite a bit. And there&#8217;s a whole world of <a href="http://www.dotnetspark.com/kb/1687-dynamic-object-c-sharp-40-tutorial--part.aspx">Dynamic</a> to be accessed plus Excel and C++ interfaces of varying degrees of sexiness to be devised .</p>
<p>More on much of that when I understand it well enough to say something.</p>
<hr />
<p><sup>1</sup> There are billions at stake, here, <em>billions</em> I tell you.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/784/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=784&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2011/03/25/this-wheel-goes-to-eleven/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2011/01/productfeaturematrix.png" medium="image">
			<media:title type="html">ProductFeatureMatrix</media:title>
		</media:content>
	</item>
		<item>
		<title>All You Wanna Do Is Jaw-Jaw</title>
		<link>http://grumpyop.wordpress.com/2011/01/26/789/</link>
		<comments>http://grumpyop.wordpress.com/2011/01/26/789/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 14:23:11 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=789</guid>
		<description><![CDATA[(in which we apply our face, at speed, to the brick wall of Enterprise IT Development Methodologies) I am, for my sins, embroiled in a Project with our IT people. I assume that some Holy Standards Manual1 somewhere must decree that in order to transition from stage 0.7.4.1.a to stage 0.7.4.1.b2 there is a requirement [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=789&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h6><em>(in which we apply our face, at speed, to the brick wall of Enterprise IT Development Methodologies)</em></h6>
<p>I am, for my sins, embroiled in a Project with our IT people. I assume that some Holy Standards Manual<sup>1</sup> somewhere must decree that in order to transition from stage 0.7.4.1.a to stage 0.7.4.1.b<sup>2</sup> there is a requirement to develop and publish a &#8220;Communication Plan&#8221;, such a document having also assaulted my inbox this week. That&#8217;s an <em>eight-slide</em> Powerpoint presentation, adorned with pithy quotes and charmingly apposite images. More Powerpointedness than I&#8217;ve personally produced in my life, for content that could adequately be summarised in a four-sentence email. Three, if you worked at it. Something like this:</p>
<ol>
<li>There will be a weekly meetings: on Thursdays at 1400 to review status and issues. <em>(There are a couple more, but they don&#8217;t have general applicability so let&#8217;s not bother everybody with those).</em></li>
<li>Everybody should talk to each other as often as necesary to ensure that lack of information does not hold up progress <em>(I&#8217;m paraphrasing wildly here, attempting to extract some sense from two ludicrously complicated diagrams)</em></li>
<li>Documents will be stored on the Sharepoint server that everybody already uses.</li>
<li>Communication will be in English except where everyone involved speaks German and no non-German speaker will need to read/listen.</li>
</ol>
<p>There. I did it in four without even trying that hard. Took about five minutes. No pictures though. Sorry about that.</p>
<hr />
<p><sup>1</sup> With no apparent irony, a document received this week declares that the Project is &#8220;following a strict Waterfall approach.&#8221;<br />
<sup>2</sup> The stages may be more fine-grained than that &#8211; I don&#8217;t know and I don&#8217;t want to know.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/789/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=789&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2011/01/26/789/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>
	</item>
		<item>
		<title>Ghosts in the Machines</title>
		<link>http://grumpyop.wordpress.com/2010/12/24/ghosts-in-the-machines/</link>
		<comments>http://grumpyop.wordpress.com/2010/12/24/ghosts-in-the-machines/#comments</comments>
		<pubDate>Fri, 24 Dec 2010 08:50:52 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[just plain weird]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=763</guid>
		<description><![CDATA[in which we consider the death of Social Networking? How Seasonal&#8230; The world is Socially Networked these days, or at least a seriously chunky proportion of the interwebular world is. I&#8217;ll admit to being present (to a greater, or more likely lesser extent) on Facebook, Friends Reunited, Twitter, LiveJournal and to having at least registered [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=763&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><em>in which we consider the death of Social Networking? How Seasonal&#8230;<br />
</em></p>
<p>The world is Socially Networked these days, or at least a seriously <a href="http://blog.facebook.com/blog.php?post=409753352130">chunky proportion</a> of the interwebular world is. I&#8217;ll admit to being present (to a greater, or more likely lesser extent) on <a href="http://facebook.com/">Facebook</a>, <a href="http://www.friendsreunited.co.uk">Friends Reunited</a>, <a href="http://twitter.com/#!/mikewoodhouse">Twitter</a>, <a href="http://www.livejournal.com">LiveJournal</a> and to having at least registered on a good few others.</p>
<p>Beyond those, there are places like WordPress, Stackoverflow (and sundry other StackExchange sites), Blogger, Opera, Google, Yahoo! etc etc <em>ad nauseam</em>. You&#8217;re reading this so it&#8217;s likely that you&#8217;re aware of most, if not all of this stuff.</p>
<p>As well as grumpy, I&#8217;m also old. Well, by the dictionary I appear to be in the first blush of <a href="http://www.thefreedictionary.com/middle-aged+man">middle-age</a>, but when you reach the stage in life when all your relatives from the previous generation have died and your peers are starting to shuffle off this mortal coil then you&#8217;re at least beginning to be aware &#8211; uncomfortably so &#8211; of mortality.</p>
<p>So right now I&#8217;m all over the Internet. But in fifty years it&#8217;s statistically almost certain that I won&#8217;t be actively contributing any more.</p>
<p>People die.<a href="http://www.jjchandler.com/tombstone/"><img class="alignright size-full wp-image-773" title="Honestly, you can find ANYthing on the web these days - make your own, why don't you?" src="http://grumpyop.files.wordpress.com/2010/12/250m_fb_users.png?w=630" alt=""   /></a></p>
<p>More pertinently to my musings here, people on Facebook die. Of the <a href="http://www.checkfacebook.com/">ten countries with the highest</a> estimated Facebook populations, assuming their age distributions are similar to the general population (obviously not, but stay with me) and that mortality rates as per the <a href="http://en.wikipedia.org/wiki/List_of_sovereign_states_and_dependent_territories_by_death_rate">2009 CIA World Factbook</a> can be applied, then we get this:</p>
<table border="0" cellspacing="0" cellpadding="0" width="269">
<col width="70"></col>
<col width="64"></col>
<col width="57"></col>
<col width="78"></col>
<tbody>
<tr>
<td width="70" height="16">Country</td>
<td width="64">FB Pop (m)</td>
<td width="57">Deaths/K</td>
<td width="78">FB deaths</td>
</tr>
<tr>
<td height="16">USA</td>
<td align="right">145.3</td>
<td align="right">8.38</td>
<td align="right">1,217,614</td>
</tr>
<tr>
<td height="16">Indonesia</td>
<td align="right">31.4</td>
<td align="right">6.26</td>
<td align="right">196,564</td>
</tr>
<tr>
<td height="16">UK</td>
<td align="right">28.8</td>
<td align="right">10.02</td>
<td align="right">288,576</td>
</tr>
<tr>
<td height="16">Turkey</td>
<td align="right">23.8</td>
<td align="right">6.10</td>
<td align="right">145,180</td>
</tr>
<tr>
<td height="16">France</td>
<td align="right">20.3</td>
<td align="right">8.56</td>
<td align="right">173,768</td>
</tr>
<tr>
<td height="16">Philippines</td>
<td align="right">18.8</td>
<td align="right">5.10</td>
<td align="right">95,880</td>
</tr>
<tr>
<td height="16">Mexico</td>
<td align="right">17.8</td>
<td align="right">4.80</td>
<td align="right">85,440</td>
</tr>
<tr>
<td height="16">Italy</td>
<td align="right">17.6</td>
<td align="right">10.72</td>
<td align="right">188,672</td>
</tr>
<tr>
<td height="16">Canada</td>
<td align="right">17.4</td>
<td align="right">7.74</td>
<td align="right">134,676</td>
</tr>
<tr>
<td height="16">India</td>
<td align="right">16.5</td>
<td align="right">6.23</td>
<td align="right">102,795</td>
</tr>
<tr>
<td height="16">TOTAL</td>
<td></td>
<td></td>
<td align="right">2,629,165</td>
</tr>
</tbody>
</table>
<p>..or about 2.6 million Facebook users dying each year. Obviously the estimate may be a little low, there are only ten countries represented for one thing. What are you going to do when <a href="http://www.youtube.com/watch?v=o6EFg5eWWlM">all your friends are dead</a>?</p>
<p>Add in the all the other sites and we&#8217;re looking at a small-to-medium sized country-worth of &#8220;ghost&#8221; accounts, persisting &#8211; and inviting interaction, even.</p>
<p>I&#8217;m not offering any solutions &#8211; heck, I&#8217;m not even suggesting that this is even a Bad Thing &#8211; perhaps it&#8217;s as close to life after death as we&#8217;ll ever get. I just keep extrapolating to some inflection point where half the content on the Internet was written by people who are now dead.</p>
<p>So if I stop posting here, is it because I&#8217;m bored, out of things to write about or something more &#8230; terminal? And if the latter, how will you know?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/763/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/763/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/763/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/763/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/763/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/763/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/763/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/763/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/763/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/763/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/763/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/763/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/763/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/763/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=763&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2010/12/24/ghosts-in-the-machines/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2010/12/250m_fb_users.png" medium="image">
			<media:title type="html">Honestly, you can find ANYthing on the web these days - make your own, why don&#039;t you?</media:title>
		</media:content>
	</item>
		<item>
		<title>Tiny VBA Tooltippery Tip</title>
		<link>http://grumpyop.wordpress.com/2010/10/22/tiny-vba-tooltippery-tip/</link>
		<comments>http://grumpyop.wordpress.com/2010/10/22/tiny-vba-tooltippery-tip/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 07:58:17 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[Ancient History]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=749</guid>
		<description><![CDATA[Project Euler 100/304 (in which we discover What Went On In 1997) This morning&#8217;s iteration of the daily blog/news trawl for useful information threw up &#8220;Five tips for debugging a routine in the Visual Basic Editor&#8220;, all of which are sensible, although unlikely to be news to anyone reading this, if we&#8217;re honest. Tip #3, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=749&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h6 style="text-align:right;"><a href="http://projecteuler.net">Project Euler</a> 100/304</h6>
<p><span style="color:#999999;"> </span></p>
<h6><em>(in which we discover What Went On In 1997)</em></h6>
<p>This morning&#8217;s iteration of the daily blog/news trawl for useful information threw up &#8220;<a href="http://blogs.techrepublic.com.com/five-tips/?p=364">Five tips for debugging a routine in the Visual Basic Editor</a>&#8220;, all of which are sensible, although unlikely to be news to anyone reading this, if we&#8217;re honest.</p>
<p>Tip #3, &#8220;View variables using data tips&#8221;, however, reminded me of something that I don&#8217;t believe is widely known. Since the site seems to require a full-blown account creation that I can&#8217;t see as appropriate for a simple comment, I&#8217;m going to mention it here.</p>
<p>Hovering the mouse pointer over a variable while in VBA&#8217;s Break mode will show the variable&#8217;s value in a tool tip:</p>
<div id="attachment_751" class="wp-caption alignnone" style="width: 478px"><a href="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_1.png"><img class="size-full wp-image-751" title="Shorter strings display just fine" src="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_1.png?w=630" alt=""   /></a><p class="wp-caption-text">The smart VBA programmer</p></div>
<p>That&#8217;s fine: almost all the time we get to see exactly what we want. Above about (or maybe exactly) 60 characters, however, we get the leading part and three little dots:</p>
<div id="attachment_751" class="wp-caption alignnone" style="width: 510px"><a href="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_2.png"><img class="size-full wp-image-751" title="String's now too long for the tool tip" src="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_2.png?w=630" alt=""   /></a><p class="wp-caption-text">Still no problem if we only want the start of the string...</p></div>
<p>What if we want to see what&#8217;s at the <em>end</em> of the string, though? Well, back in (I think) 1997, I managed to get my then employer to send me to VBA DevCon (no easy task, given that the location was EuroDisney), at which I happened to meet the Microsoft guy who actually wrote the hover/tooltip thing (it was in the VB4 editor first, I believe) and he told me that viewing the <em>last</em> 60-ish characters of the string could be achieved by holding down the Control key before moving the pointer over the variable name:</p>
<div id="attachment_752" class="wp-caption alignnone" style="width: 520px"><a href="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_3.png"><img class="size-full wp-image-752" title="vbatooltippery_3" src="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_3.png?w=630" alt=""   /></a><p class="wp-caption-text">Presto!</p></div>
<p>I don&#8217;t think I&#8217;ve ever seen this recorded. Of course, I haven&#8217;t exactly gone looking for it, so if you came all the way to the end only to discover that I was just repeating something that everyone knows, then I can only apologise. We&#8217;ll get over it.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/749/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/749/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/749/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/749/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/749/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/749/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/749/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/749/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/749/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/749/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/749/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/749/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/749/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/749/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=749&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2010/10/22/tiny-vba-tooltippery-tip/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_1.png" medium="image">
			<media:title type="html">Shorter strings display just fine</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_2.png" medium="image">
			<media:title type="html">String&#039;s now too long for the tool tip</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2010/10/vbatooltippery_3.png" medium="image">
			<media:title type="html">vbatooltippery_3</media:title>
		</media:content>
	</item>
		<item>
		<title>Lacking Anything Worthwhile To Say, The Third Wise Monkey Remained Mostly Mute</title>
		<link>http://grumpyop.wordpress.com/2010/10/15/lacking-something-to-say-the-third-wise-monkey-said-nothing/</link>
		<comments>http://grumpyop.wordpress.com/2010/10/15/lacking-something-to-say-the-third-wise-monkey-said-nothing/#comments</comments>
		<pubDate>Fri, 15 Oct 2010 16:31:51 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[dotNET]]></category>
		<category><![CDATA[ExcelDNA]]></category>
		<category><![CDATA[miscellaneous]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=729</guid>
		<description><![CDATA[Project Euler 100/304 complete (on the permanent leaderboard at last!) (in which we discover What&#8217;s Been Going On lately) &#160; &#160; I&#8217;ve been coding like crazy in C# of late, a language I&#8217;ve barely touched in the last few years. Put it this way, generics were new and sexy the last time I wrote anything [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=729&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h6 style="text-align:right;"><a href="http://projecteuler.net">Project Euler</a> 100/304 complete (on the permanent leaderboard at last!)</h6>
<p><span style="color:#999999;"> </span></p>
<h6><em>(in which we discover What&#8217;s Been Going On lately)</em></h6>
<p>&nbsp;</p>
<div id="attachment_742" class="wp-caption alignleft" style="width: 245px"><a href="http://grumpyop.files.wordpress.com/2010/10/thirdwisemonkey.png"><img class="size-full wp-image-742" title="ThirdWiseMonkey" src="http://grumpyop.files.wordpress.com/2010/10/thirdwisemonkey.png?w=630" alt=""   /></a><p class="wp-caption-text">Don&#039;t talk ... code</p></div>
<p>&nbsp;</p>
<p>I&#8217;ve been coding like crazy in C# of late, a language I&#8217;ve barely touched in the last few years. Put it this way, generics were new and sexy the last time I wrote anything serious in .NET&#8230; (There should be some ExcelDNA fun to be had later.)</p>
<p>I&#8217;d forgotten how flat-out <em>fast</em> compiled languages, even the bytecode/IL kind could be. It&#8217;s not a completely fair comparison, to be sure, but a Ruby script to extract 300,000 accounts from my Oracle database and write them as XML takes a couple of hours, mostly in the output part. A C# program handled the whole thing in 5 minutes. Then processes the accounts in about 30 seconds, of which 10 are spent deserializing the XML into objects, 10 are serializing the results to XML and 10 are performing the moderately heavy-duty mathematical tranformations in between.</p>
<p>&nbsp;</p>
<div id="attachment_743" class="wp-caption alignright" style="width: 116px"><a href="http://grumpyop.files.wordpress.com/2010/10/nunitinsharpdevelop.png"><img class="size-full wp-image-743" title="NUnitInSharpDevelop" src="http://grumpyop.files.wordpress.com/2010/10/nunitinsharpdevelop.png?w=630" alt=""   /></a><br />
<p class="wp-caption-text">Click to test is value for money</p></div>
<p>&nbsp;</p>
<p>Lacking at present a paid-for version of Visual Studio 2010 (the <a href="http://www.microsoft.com/express/downloads/">Express Edition</a>, while brilliantly capable, won&#8217;t do plugins, which precludes integration Subversion and <a href="http://www.nunit.org/">NUnit</a>, to name but two essentials), I have been enjoying greatly my experience with <a href="http://www.icsharpcode.net/opensource/sd/">SharpDevelop</a>, which spots my installs of <a href="http://tortoisesvn.net/">TortoiseSVN</a> and NUnit and allows both to be used inside the IDE. It&#8217;s not perfect: there are areas, particularly in its Intellisense analogue, where exceptions get thrown, but they&#8217;re all caught and I have yet to lose any work. While the polish is, unsurprisingly, at a lower level than Microsoft&#8217;s, it&#8217;s entirely adequate (and I mean that in a good way) and the price is right. I particularly liked being able to open an IronRuby session in the IDE and use it to interact with the classes in the DLL on which I was working.</p>
<p>While I expect VS2010 to become available as the budgeting process grinds through, I&#8217;m not at all sure that it&#8217;ll be necessary to switch. An extended set of automated refactoring tools could be attractive, although <em>Rename</em> and <em>Extract Method</em> are probably the two most useful, productivity-wise, and they&#8217;re already present. I would rather like to have Extract Class, which isn&#8217;t needed often but would be a big time (and error) saver when called for.</p>
<p>On another topic entirely, should you be looking for entertaining reading in the vaguely technical, erudite and borderline insane category, may I recommend <a href="http://drloser.blog.co.uk/">To Umm Is Human</a> to you? Any blog that has &#8220;orang utan&#8221; amongst its tags is worth a look, I&#8217;d say. If you like it, you&#8217;ll like it a lot. I was once made redundant by a Doubleday, but I don&#8217;t think they&#8217;re related.</p>
<p>There&#8217;s an interesting new programmer-oriented podcast on the block, too: <a href="http://thisdeveloperslife.com">This Developer&#8217;s Life</a> has slightly higher production values that may ultimately limit its life &#8211; the time to produce an episode must be substantial. I found myself wanting to join in the conversation with stories of my own, a sure sign that I was engaged in the content.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/729/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/729/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/729/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/729/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/729/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/729/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/729/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/729/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/729/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/729/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/729/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/729/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/729/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/729/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=729&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2010/10/15/lacking-something-to-say-the-third-wise-monkey-said-nothing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2010/10/thirdwisemonkey.png" medium="image">
			<media:title type="html">ThirdWiseMonkey</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2010/10/nunitinsharpdevelop.png" medium="image">
			<media:title type="html">NUnitInSharpDevelop</media:title>
		</media:content>
	</item>
		<item>
		<title>That Do Impress Me Much</title>
		<link>http://grumpyop.wordpress.com/2010/07/15/that-do-impress-me-much/</link>
		<comments>http://grumpyop.wordpress.com/2010/07/15/that-do-impress-me-much/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 12:32:57 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[lean]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=717</guid>
		<description><![CDATA[Over at stackoverflow, now that they have a pile of money to spend invest, the rate of change is picking up. There&#8217;s the re-worked stack exchange model, which has changed dramatically &#8211; and quite likely for the better. They&#8217;ve moved away from the original paid-for hosted service to a community-driven process, whereby a community needs [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=717&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Over at <a href="http://stackoverflow.com">stackoverflow</a>, now that they <a href="http://blog.stackoverflow.com/2010/05/announcing-our-series-a/">have a pile of money</a> to <span style="text-decoration:line-through;">spend</span> invest, the rate of change is picking up. There&#8217;s the re-worked <a href="http://stackexchange.com/">stack exchange</a> model, which has <a href="http://blog.stackoverflow.com/2010/04/changes-to-stack-exchange/">changed dramatically</a> &#8211; and quite likely for the better. They&#8217;ve moved away from the original paid-for hosted service to a community-driven process, whereby a <a href="http://area51.stackexchange.com/">community needs to form</a> and commit to the idea of a new site. The objective is to improve the prospects of achieving critical mass for a new site, thus increasing its chances of success. I imagine a revenue model is mooted, although it may be little more than &#8220;if we build it, they will come&#8221; at present. Sponsored tags and ads spring to mind.</p>
<p>This week we&#8217;ve seen the covers removed (perhaps for a limited time initially) on a &#8220;<a href="http://blog.stackoverflow.com/2010/07/third-place-chat-beta-preview/">third place</a>&#8220;, to go with the existing main Q&amp;A and &#8220;meta&#8221; (questions about the Q&amp;A site). It&#8217;s a chat room. Well, lots of chat rooms of varying degrees of focus, to be more specific. Quite nicely done, too.</p>
<p>What has really impressed me has been that during this &#8220;limited sneak beta preview&#8221;, bugs, issues, feature requests and the like have been flowing through the interface at a fair rate of knots and many have been <em>addressed and released within hours</em>. Minutes, sometimes.</p>
<p>Think about it. User detects a bug, reports it and gets a fix, to an application with global reach, in a couple of hours or less. That&#8217;s agile.</p>
<p>A crucial part of <a href="http://en.wikipedia.org/wiki/Lean_manufacturing">Lean movement</a> in manufacturing<a href="http://findarticles.com/p/articles/mi_qa3618/is_200403/ai_n9375440/"></a> (and its younger <a href="http://en.wikipedia.org/wiki/Lean_software_development">counterpart</a> in software development) is eliminating waste. &#8220;Waste&#8221; is broadly defined, very broadly defined, in fact, but one easily identifiable component is Work In Progress (WIP). In software terms, this often represents effort that has been invested (and money that&#8217;s been tied up) without having been included in a release. The more we invest effort without release the more we&#8217;re wasting, since we have no possibility of obtaining a return on that investment.</p>
<p>Here&#8217;s a particularly quick find/fix from earlier today:</p>
<p><a href="http://grumpyop.files.wordpress.com/2010/07/chat_quick_fix1.png"><img class="alignnone size-full wp-image-724" title="chat_quick_fix" src="http://grumpyop.files.wordpress.com/2010/07/chat_quick_fix1.png?w=630&#038;h=207" alt="" width="630" height="207" /></a></p>
<p>Yes, it was probably a trivial bug, but the problem was notified, found, fixed and released in <em>eight frickin&#8217; minutes</em>. How many of us can turn <em>anything</em> around that fast?</p>
<p>I&#8217;m looking forward to seeing where this goes.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/717/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/717/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/717/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/717/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/717/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/717/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/717/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/717/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/717/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/717/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/717/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/717/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/717/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/717/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=717&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2010/07/15/that-do-impress-me-much/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>

		<media:content url="http://grumpyop.files.wordpress.com/2010/07/chat_quick_fix1.png" medium="image">
			<media:title type="html">chat_quick_fix</media:title>
		</media:content>
	</item>
		<item>
		<title>Sorted for Excel and Whee!</title>
		<link>http://grumpyop.wordpress.com/2010/07/06/sorted-for-excel-and-whee/</link>
		<comments>http://grumpyop.wordpress.com/2010/07/06/sorted-for-excel-and-whee/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 13:26:21 +0000</pubDate>
		<dc:creator>mikewoodhouse</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://grumpyop.wordpress.com/?p=623</guid>
		<description><![CDATA[If you happened upon the VBA Lamp and by rubbing it were able to produce the Excel VBA Genie and were granted a VBA Wish, would you ask for a built-in Sort() function? If you build the kind of Excel apps that I do, you&#8217;ll run up against the need for a Sort all too [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=623&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you happened upon the VBA Lamp and by rubbing it were able to produce the <a href="http://www.j-walk.com/ss/jokes/genie.htm">Excel VBA Genie</a> and were granted a VBA Wish, would you ask for a built-in Sort() function?</p>
<p>If you build the kind of Excel apps that I do, you&#8217;ll run up against the need for a Sort all too frequently. Sorting arrays with sizes in the tens of thousands is not unusual and I was reminded of this when reading a post in <a href="http://blog.livedoor.jp/andrewe/archives/51087940.html">this entry</a> at <a href="http://blog.livedoor.jp/andrewe/">Andrew&#8217;s Excel Tips</a> the other day.</p>
<p>While it&#8217;s not crucial in the (useful) idea presented, the code has a quick and and dirty sort that is about the worst sort algorithm<sup>1</sup> one could intelligently come up with. It&#8217;s also an prettty intuitive solution, which just goes to show that sorting may not be as simple as we may think. I&#8217;m not attacking Andrew&#8217;s skillz here, btw: the code as presented is certainly fit for purpose; it&#8217;s not presented as a general-purpose utility (at least I hope it isn&#8217;t).</p>
<p>I&#8217;ve accumulated a few algorithms over the years and I&#8217;ve coded up a couple more while &#8220;researching&#8221; this piece. On the one hand, we have the oft-derided <a href="http://en.wikipedia.org/wiki/Bubble_sort">BubbleSort</a> and its close relation, <a href="http://en.wikipedia.org/wiki/Cocktail_sort">CocktailSort</a>. In the same group I&#8217;d include <a href="http://en.wikipedia.org/wiki/Insertion_sort">InsertionSort</a> and  <a href="http://en.wikipedia.org/wiki/Selection_sort">SelectionSort</a>. I&#8217;m going to be harsh and categorise those, with the naive sort above, as &#8220;Slow&#8221;. Well, &#8220;mostly slow&#8221;, as we&#8217;ll see.</p>
<p>In the &#8220;Fast&#8221; group, we have the much-touted <a href="http://en.wikipedia.org/wiki/Quicksort">QuickSort</a>, and somewhere in between, we have <a href="http://en.wikipedia.org/wiki/Heapsort">HeapSort</a>,and my current algorithm of choice, <a href="http://en.wikipedia.org/wiki/Comb_sort">CombSort</a>. As I was researching this, I also coded up <a href="http://en.wikipedia.org/wiki/Shell_sort">ShellSort</a>, which is about as old as I am and which was claimed to be faster than QuickSort under some conditions.</p>
<p>I ran some comparisons, not meant in any way to be perfectly scientific<sup>2</sup>. I ran each algorithm on arrays of 50 to 50,000 values with six different characteristics:</p>
<ul>
<li>already sorted</li>
<li>exactly reversed</li>
<li>mostly sorted (values typically within one or two places of target)</li>
<li>ordered blocks of 100 random values (the first 100 values are 0 + RAND(), then 100 + RAND() and so on)</li>
<li>completely random</li>
<li>random 10-character strings</li>
</ul>
<p>First off, the 50-record results:</p>
<hr />
<table cellspacing="0">
<tbody>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">50 recs (ms)</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">sorted</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">near sorted</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">blocks</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">random</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">strings</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">reversed</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Shell</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.06</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.06</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.11</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.10</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.24</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.09</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Quick</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.13</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.13</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.16</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.13</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.29</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.14</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Comb</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.09</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.10</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.17</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.17</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.33</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.13</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Heap</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">0.34</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.33</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.32</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.32</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.52</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.28</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Insertion</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.02</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.02</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.20</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.17</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.47</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.37</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Selection</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.25</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.25</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.25</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.25</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.54</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.25</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Cocktail</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.01</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.02</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.44</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.39</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">1.02</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.77</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Bubble</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.01</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">0.02</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">0.50</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.45</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">1.12</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">0.78</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Naive</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.22</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">0.23</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">0.50</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">0.46</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">1.06</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">0.77</td>
</tr>
</tbody>
</table>
<hr />I&#8217;d say it&#8217;s pretty clear that it doesn&#8217;t matter much what you use to sort a small array, just about anything will be fast enough (unless you&#8217;re going to perform that sort tens of thousands of times in a run). It&#8217;s also apparent that the &#8220;slow&#8221; algorithms are actually pretty good if our data is already reasonably well-ordered.</p>
<p>So far, so &#8220;so what?&#8221;</p>
<p>Let&#8217;s look at the opposite end of the spectrum: 50,000 values? Here, the Fast/Slow divide is apparent. First the &#8220;Slows&#8221; (two tests only, for reasons that should become apparent):</p>
<hr />
<table cellspacing="0">
<tbody>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">50K (ms)</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">near sorted</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">random</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Bubble</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">31</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">522,216</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Cocktail</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">30</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">449,696</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Insertion</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">19</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">179,127</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Naive</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">219,338</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">510,010</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Selection</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">220,735</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">220,743</td>
</tr>
</tbody>
</table>
<hr />Yes, that&#8217;s hundreds of thousands of milliseconds. &#8220;Three or four minutes&#8221; to you and me. The &#8220;Fasts&#8221;, meanwhile:</p>
<hr />
<table cellspacing="0">
<tbody>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">50K (ms)</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">sorted</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">near sorted</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">blocks</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">random</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">strings</td>
<td style="background-color:#99ccff;text-align:right;padding-right:5px;padding-left:5px;">reversed</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Shell</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">162</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">164</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">219</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">377</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">929</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">250</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Quick</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">296</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">298</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">327</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">365</td>
<td style="background-color:#ccffcc;text-align:right;padding-right:5px;padding-left:5px;">790</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">306</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Comb</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">390</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">396</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">477</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">622</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">1,348</td>
<td style="text-align:right;padding-right:5px;padding-left:5px;">452</td>
</tr>
<tr>
<td style="background-color:#99ccff;padding-right:5px;padding-left:5px;">Heap</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">899</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">903</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">885</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">874</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">1,548</td>
<td style="background-color:#ff99cc;text-align:right;padding-right:5px;padding-left:5px;">844</td>
</tr>
</tbody>
</table>
<hr />(I only ran two tests on the &#8220;Slows&#8221;, for fear of dozing off completely.)</p>
<p>Again, for data where values are near their final sorted positions there&#8217;s clear evidence that something like an Insertion Sort is much faster than any of the &#8220;sexier&#8221; options. Provided you know your data will actually meet that criterion, of course.</p>
<p>All that considered, I&#8217;m switching from CombSort to ShellSort as my default algorithm. While it loses out a little to QuickSort in the &#8220;random&#8221; test (probably most representative of my normal use case) it doesn&#8217;t carry with it the fear of stack overflow through extreme recursion, something that&#8217;s bitten me with QS in the past. Anyway, us old&#8217;uns have got to stick together.</p>
<p>As already mentioned, if you have small quantities of data or infrequent sort calls in your application, it really doesn&#8217;t make much difference which algorithm you use, although I&#8217;d still suggest being aware of the properties of several options and having a basic implementation to hand. Once you reach a point where sorting contributes materially to your application run time then you owe it to yourself and your users to make an intelligent selection.</p>
<p>Here&#8217;s my ShellSort implemenation in VB, transcoded fairly literally from the Wikipedia pseudo-code (optimisations welcome):</p>
<p><pre class="brush: vb;">

Public Sub ShellSort(inp)
' sorts supplied array in place in ascending order
Dim inc As Long, i As Long, j As Long
Dim temp ' don't know what's in the input array...
  If Not IsArray(inp) Then Exit Sub ' ...but it had better be an array
  inc = (UBound(inp) - LBound(inp) + 1) / 2 ' use Shell's originally-proposed gap sequence
  Do While inc &gt; 0
    For i = inc To UBound(inp)
      temp = inp(i)
      j = i
      Do
        If j &lt; inc Then Exit Do ' check these conditions separately, as VBA Ors don't short-circuit
        If inp(j - inc) &lt;= temp Then Exit Do ' ... and this will fail when j &lt; inc
        inp(j) = inp(j - inc)
        j = j - inc
      Loop
      inp(j) = temp
    Next
    inc = Round(CDbl(inc) / 2.2)
  Loop

End Sub

</pre></p>
<hr /><sup>1</sup> Not the absolute worst: there&#8217;s the catastrophic genius of <a href="http://en.wikipedia.org/wiki/Bogosort">BogoSort</a>, to name but one, but let&#8217;s not go anywhere nearer to there.<br />
<sup>2</sup> Just so we understand each other, these are <em>my</em> figures for <em>my</em> code on one of <em>my</em> machines. <a href="http://www.urbandictionary.com/define.php?term=YMMV">YMMV</a>. A lot.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grumpyop.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grumpyop.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grumpyop.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grumpyop.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grumpyop.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grumpyop.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grumpyop.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grumpyop.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grumpyop.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grumpyop.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grumpyop.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grumpyop.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grumpyop.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grumpyop.wordpress.com/623/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grumpyop.wordpress.com&amp;blog=4487201&amp;post=623&amp;subd=grumpyop&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grumpyop.wordpress.com/2010/07/06/sorted-for-excel-and-whee/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5978e2ed3a31f1bd2361dbb919d92012?s=96&#38;d=" medium="image">
			<media:title type="html">mikewoodhouse</media:title>
		</media:content>
	</item>
	</channel>
</rss>
