<?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/"
	>

<channel>
	<title>ebmgh.com &#187; Excel</title>
	<atom:link href="http://ebmgh.com/blog/category/excel/feed/" rel="self" type="application/rss+xml" />
	<link>http://ebmgh.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 11 Jan 2011 00:27:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Making Excel/VBA random numbers more random with a seed</title>
		<link>http://ebmgh.com/blog/2010/04/making-excelvba-random-numbers-more-random-with-a-seed/</link>
		<comments>http://ebmgh.com/blog/2010/04/making-excelvba-random-numbers-more-random-with-a-seed/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 02:53:08 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Excel]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/?p=282</guid>
		<description><![CDATA[I have a fairly simple user-defined function for Excel that I use to create random passwords. (I got kind of freaked out last year after someone hacked into my Facebook account. Trouble was, I used the same password for lots of sites. If this petty crook had been a little more savvy, he could have [...]]]></description>
			<content:encoded><![CDATA[<p>I have a fairly simple user-defined function for Excel that I use to create random passwords. (I got kind of freaked out last year after someone hacked into my Facebook account. Trouble was, I used the same password for lots of sites. If this petty crook had been a little more savvy, he could have done a lot more damage. At first, I immediately replaced a bunch of my passwords with strings like this: p9q4MF3nnX4B. The only problem now is that I can&#8217;t remember any of my passwords, and have to keep them in a file, which creates security concerns of its own&#8230;)</p>
<p>I noticed that my little password routine would repeatedly create the same password each time I used it anew, after re-starting the computer and re-launching Excel. It turns out that VBA&#8217;s RAND function is not as random as you&#8217;d think it might be. The way around this is</p>
<p>I saw this code that I found on the <a href="http://forums.techguy.org/business-applications/661639-excel-vba-random-number-generator.html">techguy forum</a>:</p>
<pre dir="ltr">  seed = TimeValue("00:" &amp; Format(Second(Time), "00") &amp; ":" &amp; Format(Minute(Time), "00"))
  Randomize (seed)
</pre>
<p>But according to the <a href="http://msdn.microsoft.com/en-us/library/ee177404%28PROT.10%29.aspx">RND entry</a> at the support site, you can just call Randomize on its own:</p>
<blockquote><p>Before calling Rnd, use the Randomize statement without an argument to  initialize the random-number generator with a seed based on the system  timer.</p></blockquote>
<p>I had never used Randomize before, and never knew that I needed to. In Python, a more sophisticated programming language, <a href="http://docs.python.org/library/random.html">seeding</a> is taken care of for you: &#8220;current system time is also used to initialize the generator when the  module is first imported.&#8221;</p>
<p>Lots more information at the Wikipedia article on <a href="http://en.wikipedia.org/wiki/Pseudo-random_number_generator">Pseudo-Random Number Generators</a>. From here I learned, &#8220;A PRNG can be started from an arbitrary starting state using a <a title="Random seed" href="http://en.wikipedia.org/wiki/Random_seed">seed  state</a>. It will always produce the same sequence thereafter when  initialized with that state.&#8221;</p>
<pre dir="ltr">
</pre>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/04/making-excelvba-random-numbers-more-random-with-a-seed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Returning an Error from an Excel User-Defined Function</title>
		<link>http://ebmgh.com/blog/2010/02/returning-an-error-from-an-excel-user-defined-function/</link>
		<comments>http://ebmgh.com/blog/2010/02/returning-an-error-from-an-excel-user-defined-function/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 18:00:34 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Excel]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/02/returning-an-error-from-an-excel-user-defined-function/</guid>
		<description><![CDATA[It&#8217;s often useful to write your own custom functions for Excel. These are often called User-Defined Functions, or UDFs. It&#8217;s actually not that hard if you know a bit of programming. It&#8217;s all done in VBA, or Visual Basic for Applications. I&#8217;ve probably written hundreds of these in the last 7 or 8 years, but [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s often useful to write your own custom functions for Excel. These are often called User-Defined Functions, or UDFs. It&#8217;s actually not that hard if you know a bit of programming. It&#8217;s all done in VBA, or Visual Basic for Applications. I&#8217;ve probably written hundreds of these in the last 7 or 8 years, but one trick I always forget is how to return a customized error message.
</p>
<p>If a line in your function produces a run-time error, you won&#8217;t get a popup message like you would for a Subroutine. Instead, code execution ends immediately, and you get the error #VALUE! in the cell on the worksheet.
</p>
<p>It is often useful to return a more descriptive error. To do this, you can use On Error to trap the error, and return one of Excel&#8217;s built in error types. To do this, use the VBA function CVErr and a constant to set the built-in error type. These are (via the online help under &#8220;Cell Error Values&#8221;):
</p>
<div>
<table style="border-collapse:collapse" border="0">
<colgroup>
<col style="width:78px"/>
<col style="width:92px"/>
<col style="width:122px"/></colgroup>
<tbody valign="top">
<tr style="background: #d9d9d9">
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt"><strong>Constant</strong></span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code><strong>Error number</strong></code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code><strong>Cell error value</strong></code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrDiv0</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2007</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#DIV/0!</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrNA</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2042</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#N/A</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrName</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2029</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#NAME?</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrNull</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2000</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#NULL!</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrNum</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2036</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#NUM!</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrRef</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2023</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#REF!</code></pre>
</p>
</td>
</tr>
<tr>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<p><span style="font-family:Consolas; font-size:10pt">xlErrValue</span></p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>2015</code></pre>
</p>
</td>
<td vAlign="middle" style="padding-top: 1px; padding-left: 1px; padding-bottom: 1px; padding-right: 1px">
<pre><code>#VALUE!</code></pre>
</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>
 </p>
<p>For your UDF to return custom errors, you must declare the function so that it returns the data type Variant. See also this Microsoft knowldgebase article on Error <a href="http://support.microsoft.com/kb/146864">Trapping with Visual Basic for Applications</a>.
</p>
<p>Here&#8217;s an example of a UDF that returns the error #N/A. In this case, the function is a slightly more sophisticated version of the built-in function FIND, which returns the starting position of a one text string within another string. I wanted a function that would return the nth position, rather than just the first occurrence.
</p>
<p>
<pre><code>Function FindNth(find_text As String, within_text As String, n As Long) As Variant
</code></pre>
</p>
<p>
<pre><code>'Finding the nth occurrence of a text string within another text string
</code></pre>
</p>
<p>
<pre><code>'Uses Excel's built-in Worksheet Find function iteratively
</code></pre>
</p>
<p>
<pre><code>'(probably faster than a brute-force approach using a loop)
</code></pre>
</p>
<p>
<pre><code>'If find_text is not found, returns the error #N/A
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>  Dim pos As Variant
</code></pre>
</p>
<p>
<pre><code>  Dim i As Long
</code></pre>
</p>
<p>
<pre><code>  Dim result As Long
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>  i = 0
</code></pre>
</p>
<p>
<pre><code>  result = 0
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>  Do
</code></pre>
</p>
<p>
<pre><code>    On Error GoTo ErrLine
</code></pre>
</p>
<p>
<pre><code>    pos = Application.WorksheetFunction.Find(find_text, within_text)
</code></pre>
</p>
<p>
<pre><code>    result = result + pos
</code></pre>
</p>
<p>
<pre><code>    i = i + 1
</code></pre>
</p>
<p>
<pre><code>    If i = n Then Exit Do
</code></pre>
</p>
<p>
<pre><code>    within_text = Right(within_text, Len(within_text) - pos)
</code></pre>
</p>
<p>
<pre><code>  Loop
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>  FindNth = result
</code></pre>
</p>
<p>
<pre><code>  Exit Function
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>ErrLine: FindNth = CVErr(xlErrNA)
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>End Function
</code></pre>
</p>
<p>
 </p>
<p>For example:
</p>
<p>
<pre><code>=FINDNTH(" ", "Mira Vista Avenue", 2)
</code></pre>
</p>
<p>
 </p>
<p>Returns 11, the position of the second occurrence of a space in &#8220;Mira Vista Avenue&#8221;.
</p>
<p>
<pre><code>=FINDNTH("x", "Microsoft", 3)
</code></pre>
</p>
<p>
 </p>
<p>Returns #N/A, since it is looking for the 3<sup>rd</sup> letter x in &#8220;Microsoft&#8221;, and can&#8217;t find it.
</p>
<p>In this example, the function should probably return #VALUE! to copy the FIND function&#8217;s built-in behavior. But I wanted to differentiate between a VBA run-time error and an error returned by the function, and #N/A seemed to fit the bill.</p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/02/returning-an-error-from-an-excel-user-defined-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing for String Membership in Excel VBA</title>
		<link>http://ebmgh.com/blog/2010/01/testing-for-string-membership-in-excel-vba/</link>
		<comments>http://ebmgh.com/blog/2010/01/testing-for-string-membership-in-excel-vba/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 01:31:57 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Excel]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/01/testing-for-string-membership-in-excel-vba/</guid>
		<description><![CDATA[I found myself wishing that Excel or VBA had a simple way to test whether a string exists in another string. In Python you can type if substring in string: #Then do something… But Excel lacks this convenience. You can sort of hack the built in InStr function to do it for you. Since I [...]]]></description>
			<content:encoded><![CDATA[<p>I found myself wishing that Excel or VBA had a simple way to test whether a string exists in another string. In Python you can type
</p>
<p>
<pre><code>if substring in string:
</code></pre>
</p>
<p>
<pre><code>  #Then do something…
</code></pre>
</p>
<p>But Excel lacks this convenience. You can sort of hack the built in InStr function to do it for you. Since I always found this confusing (who can remember what the difference is between &#8220;text compare&#8221; and &#8220;binary compare&#8221;?), I created a simple function called Contains. On the spreadsheet, you can just type
<pre><code>=Contains(<span style="font-family:Calibri">"</span>abcdefg<span style="font-family:Calibri">"</span>, <span style="font-family:Calibri">"</span>a<span style="font-family:Calibri">"</span></code></pre>
<p>) and it returns TRUE. In VBA, it is useful in IF statements. Not as clean as Python, but a helpful convenience.
</p>
<p>
<pre><code>Function Contains(str As String, substr As String, _
</code></pre>
</p>
<p>
<pre><code>   Optional CaseSensitive As Boolean = False) As Boolean
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>'Does a simple test to see if str contains substr
</code></pre>
</p>
<p>
<pre><code>'Example: =Contains("abcd","a") returns TRUE
</code></pre>
</p>
<p>
<pre><code>'         =Contains("abcd","x") returns FALSE
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>'Set CaseSensitive flag to TRUE if you don't want "a" to find "A"
</code></pre>
</p>
<p>
<pre><code>'         =Contains("ABCD","a",True) returns FALSE
</code></pre>
</p>
<p>
<pre><code>'         =Contains("ABCD","a",False) returns TRUE (because the comparison is case sensitive)
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>Dim opt As Long
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>If CaseSensitive Then
</code></pre>
</p>
<p>
<pre><code>  opt = vbBinaryCompare
</code></pre>
</p>
<p>
<pre><code>Else
</code></pre>
</p>
<p>
<pre><code>  opt = vbTextCompare
</code></pre>
</p>
<p>
<pre><code>End If
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>If InStr(1, str, substr, opt) &gt; 0 Then
</code></pre>
</p>
<p>
<pre><code>  Contains = True
</code></pre>
</p>
<p>
<pre><code>Else
</code></pre>
</p>
<p>
<pre><code>  Contains = False
</code></pre>
</p>
<p>
<pre><code>End If
</code></pre>
</p>
<p>
 </p>
<p>
<pre><code>End Function</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/01/testing-for-string-membership-in-excel-vba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixing Excel’s SMALL and LARGE Functions</title>
		<link>http://ebmgh.com/blog/2010/01/fixing-excel%e2%80%99s-small-and-large-functions/</link>
		<comments>http://ebmgh.com/blog/2010/01/fixing-excel%e2%80%99s-small-and-large-functions/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 23:04:24 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Excel]]></category>

		<guid isPermaLink="false">http://ebmgh.com/blog/2010/01/fixing-excel%e2%80%99s-small-and-large-functions/</guid>
		<description><![CDATA[Excel has a pair of useful built-in functions called SMALL and LARGE. Suppose you want to know the third-largest number in a column. Or you want to find the fourth-smallest. The function LARGE returns the kth largest value in a dataset. Entering =LARGE(A1:A9,3) returns the third largest value in the range A1 to A9. The [...]]]></description>
			<content:encoded><![CDATA[<p>Excel has a pair of useful built-in functions called SMALL and LARGE. Suppose you want to know the third-largest number in a column. Or you want to find the fourth-smallest.</p>
<p><img src="http://ebmgh.com/blog/wp-content/uploads/2010/01/011410_2303_FixingExcel1.png" alt="" /></p>
<p>The function LARGE returns the k<sup>th</sup> largest value in a dataset. Entering</p>
<pre><code>=LARGE(A1:A9,3) </code></pre>
<p>returns the third largest value in the range A1 to A9. The function is smart enough to ignore blank cells and text. However, if you have an error in a cells, the result of the formula will be an error.</p>
<p>Here are custom functions to replace the built-in ones, called MyLarge and MySmall. Their use is identical to the Excel version: just enter</p>
<pre><code>=MYLARGE(A1:A9,3).</code></pre>
<p>If you don&#8217;t know how to use these, check out the following: <a href="http://articles.techrepublic.com.com/5100-10878_11-5300300.html"><em>How do I… Create a user-defined function in Microsoft Excel</em></a> at Tech Republic. Or you can download an <a href="http://ebmgh.com/files/mylarge_demo.xls">example workbook</a> with the functions.</p>
<p><span id="more-123"></span></p>
<p>Note that these functions call a subroutine called <strong>QuickSort</strong>, which I copied from <a href="http://spreadsheetpage.com/">John Walkenbach</a>&#8216;s book <a href="http://www.amazon.com/Excel-Power-Programming-Spreadsheets-Bookshelf/dp/0470044012">Power Programming with Excel</a> VBA years ago. (Highly recommended if you use Excel a lot and want to learn to automate repetitive tasks or do more advanced stuff.)</p>
<pre><code>
Function MyLarge(x, k)
'Replicates Excel's LARGE function, but will not balk at errors
'Returns the k-th largest value in a data set.
'Usage: =MYLARGE(A1:A15,3), returns the third largest value in the range A1 to A15

Dim arr() As Double 'An array to hold the cell values
Dim i As Long  'counter for looping through the array
Dim n As Long  'n is the number of elements in array
Dim nrev As Long  'revised count of number of VALID elements in array x

nrev = -1
n = Int(x.Count)
ReDim arr(n) As Double

'Note that Excel ranges always start with an index = 1
For i = 1 To n
  If Not IsEmpty(x(i)) And Not IsError(x(i)) And IsNumeric(x(i)) Then
    nrev = nrev + 1
    arr(nrev) = x(i)
  End If
Next i

ReDim Preserve arr(nrev)
Call Quicksort(arr, 0, nrev)

On Error GoTo IndexError
  MyLarge = arr(nrev - k + 1)
  Exit Function

IndexError:
  MyLarge = CVErr(xlErrNum)

End Function

Function MySmall(x, k)
'Replicates Excel's SMALL function, but will not balk at errors
'Returns the k-th smallest value in a data set.
'Usage: =MYSMALL(A1:A15,3), returns the third smallest value in the range A1 to A15

Dim arr() As Double 'An array to hold the cell values
Dim i As Long  'counter for looping through the array
Dim n As Long  'n is the number of elements in array
Dim nrev As Long  'revised count of number of VALID elements in array x

nrev = -1
n = Int(x.Count)
ReDim arr(n) As Double

'Note that Excel ranges always start with an index = 1
For i = 1 To n
  If Not IsEmpty(x(i)) And Not IsError(x(i)) And IsNumeric(x(i)) Then
    nrev = nrev + 1
    arr(nrev) = x(i)
  End If
Next i

ReDim Preserve arr(nrev)
Call Quicksort(arr, 0, nrev)

On Error GoTo IndexError
  MySmall = arr(k - 1)
  Exit Function

IndexError:
  MySmall = CVErr(xlErrNum)

End Function

Sub Quicksort(values() As Double, ByVal min As Long, ByVal max As Long)

'A fairly efficient sort algorithm for sorting 1-dimensional arrays of numbers
'Source: Walkenbach, J., 1999, Power Programming for Excel/VBA

'values() is the 1-dimensional array to be sorted

'min is the array index for the beginning of slice of the array where the sort is to begin
'To sort the entire array, min = 0 or 1 (depending on what Base you are working in)

'max is the array index for the end of the part of the array to be sorted.
'To sort the entire array, use max = len(values)

'Note that this is an example of a *recursive algorithm*
'To understand recursive algorithms, first you have to understand recursive algorithms <img src='http://ebmgh.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> 

Dim med_value As String
Dim Hi As Long
Dim lo As Long
Dim i As Long

  ' If the list has only 1 item, it's sorted.
  If min &gt;= max Then Exit Sub

  ' Pick a dividing item randomly.
  i = min + Int(Rnd(max - min + 1))
  med_value = values(i)

  ' Swap the dividing item to the front of the list.
  values(i) = values(min)

  ' Separate the list into sublists.
  lo = min
  Hi = max
  Do
    ' Look down from hi for a value &lt; med_value.     Do While values(Hi) &gt;= med_value
      Hi = Hi - 1
      If Hi &lt;= lo Then Exit Do
    Loop

    If Hi &lt;= lo Then       ' The list is separated.       values(lo) = med_value       Exit Do     End If     ' Swap the lo and hi values.     values(lo) = values(Hi)     ' Look up from lo for a value &gt;= med_value.
    lo = lo + 1
    Do While values(lo) &lt; med_value       lo = lo + 1       If lo &gt;= Hi Then Exit Do
    Loop

    If lo &gt;= Hi Then
      ' The list is separated.
      lo = Hi
      values(Hi) = med_value
      Exit Do
    End If

    ' Swap the lo and hi values.
    values(Hi) = values(lo)
  Loop ' Loop until the list is separated.

  ' Recursively sort the sublists.
  Quicksort values, min, lo - 1
  Quicksort values, lo + 1, max

End Sub
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://ebmgh.com/blog/2010/01/fixing-excel%e2%80%99s-small-and-large-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Served from: ebmgh.com @ 2012-05-20 09:06:41 -->
