<?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>yoursumbuddy</title>
	<atom:link href="http://yoursumbuddy.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://yoursumbuddy.com</link>
	<description>Doug Glancy&#039;s Excel Site</description>
	<lastBuildDate>Sat, 12 May 2012 20:32:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Oh You False Empty Cell</title>
		<link>http://yoursumbuddy.com/oh-you-false-empty-cell/</link>
		<comments>http://yoursumbuddy.com/oh-you-false-empty-cell/#comments</comments>
		<pubDate>Thu, 10 May 2012 04:43:08 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Formulas]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=987</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/oh-you-false-empty-cell/">Oh You False Empty Cell</a></p><p>Oh You False Empty Cell I was comparing two worksheets by creating formulas off to the side of one sheet. These returned True if the corresponding cells in the two sheets matched, False if they didn&#8217;t. I converted the Trues &#8230; <a href="http://yoursumbuddy.com/oh-you-false-empty-cell/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/oh-you-false-empty-cell/">Oh You False Empty Cell</a></p><h1><a title="Permalink to Oh You False Empty Cell" href="http://yoursumbuddy.com/oh-you-false-empty-cell/" rel="bookmark">Oh You False Empty Cell</a></h1>
<p>I was comparing two worksheets by creating formulas off to the side of one sheet.  These returned True if the corresponding cells in the two sheets matched, False if they didn&#8217;t.  I converted the Trues and Falses to values, and replaced the Trues with nothing.  Then I threw some conditional formatting on the data in one of the sheets.  The formatting referred to the area with empty cells and Falses.  The condition was for cells offset from Falses to be shaded.  </p>
<p>I expected a smattering of color.  What I got was a solid swath of light orange.  Kind of like this, but on three separate sheets:</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/05/Post_0022_FALSE_conditional_Formatting_1.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/05/Post_0022_FALSE_conditional_Formatting_1.jpg" alt="" title="Post_0022_FALSE_conditional_Formatting_1" width="564" height="396" class="alignnone size-full wp-image-988" /></a></p>
<p>I assumed that I&#8217;d screwed up the conditional formatting formula, a not unreasonable premise.  However, after a couple of minutes I was sure I hadn&#8217;t, and it was then I realized that empty cells equate to False.  I&#8217;m sure everybody else already knows this, so I figured I&#8217;d better dig a little deeper in case it comes up at a party or something.</p>
<p>Next I checked if cells with =&#8221;" equate to False.  They don&#8217;t.  Neither do ones with 0, which I thought they might, since False multiplied by 1 equals 0.  Here&#8217;s the visual summary, this time with a lambent blue for False.</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/05/Post_0022_FALSE_conditional_Formatting_2.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/05/Post_0022_FALSE_conditional_Formatting_2.jpg" alt="False Empty Cell 2" title="Post_0022_FALSE_conditional_Formatting_2" width="598" height="472" class="alignnone size-full wp-image-993" /></a></p>
<p>In VBA the results are similar, except that 0 = vbEmpty.  I have no idea what that means.  I&#8217;m pretty sure Dick had a post on this, called &#8220;testing for empty cells,&#8221; but it seems to have gone down in the <a href="http://www.dailydoseofexcel.com/archives/2011/11/27/alive-but-hardly-well/" title="DDOE server crash" target="_blank">great DDOE server crash of 2011</a>.</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/05/Post_0022_FALSE_immediate_window.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/05/Post_0022_FALSE_immediate_window.jpg" alt="" title="Post_0022_FALSE_immediate_window" width="295" height="193" class="alignnone size-full wp-image-1003" /></a></p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/oh-you-false-empty-cell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data Normalizer &#8211; the SQL</title>
		<link>http://yoursumbuddy.com/data-normalizer-the-sql/</link>
		<comments>http://yoursumbuddy.com/data-normalizer-the-sql/#comments</comments>
		<pubDate>Wed, 09 May 2012 03:56:39 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=930</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/data-normalizer-the-sql/">Data Normalizer &#8211; the SQL</a></p><p>Data Normalizer &#8211; the SQL In Data Normalizer I showed you how I normalize worksheet data using arrays and For/Next loops. I&#8217;ve been doing a fair amount of SQL in VBA lately, and thought I&#8217;d rewrite the code using that &#8230; <a href="http://yoursumbuddy.com/data-normalizer-the-sql/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/data-normalizer-the-sql/">Data Normalizer &#8211; the SQL</a></p><h1><a title="Permalink to Data Normalizer - the SQL" href="http://yoursumbuddy.com/data-normalizer-the-sql/" rel="bookmark">Data Normalizer &#8211; the SQL</a></h1>
<p>In <a href="http://yoursumbuddy.com/data-normalizer" title="Data Normalizer" target ="_blank">Data Normalizer</a> I showed you how I normalize worksheet data using arrays and For/Next loops.  I&#8217;ve been doing a fair amount of SQL in VBA lately, and thought I&#8217;d rewrite the code using that approach.</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_abnormal_data1.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_abnormal_data1-300x51.jpg" alt="abnormal data" title="abnormal data" width="300" height="51" class="alignleft size-medium wp-image-747" /></a></p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_normalized_data.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_normalized_data-160x300.jpg" alt="normalized data" title="normalized data" width="160" height="300" class="alignright size-medium wp-image-751" /></a></p>
<p>A little searching revealed the T-SQL/SQL Server &#8220;<a href="http://archive.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=UNPIVOTData" title="T-SQL Unpivot" target="_blank">Unpivot</a>&#8221; command, which normalizes your data and sets the new field names all in one swell foop.  It&#8217;s not available in Access/Jet SQL though, so can&#8217;t be used on Excel.  Instead, the preferred method is to use a series of Selects that pick one normalizing column at a time (along with the repeating columns) and Unions them together.</p>
<p>I tried ADO first, using the method of SaveCopyAs&#8217;ing the workbook-to-be-normalized in order to avoid the <a href="http://support.microsoft.com/kb/319998" title="ADO memory leak - MSDN" target="_blank">ADO memory leak</a>.  ADO was way slower than DAO, something like four times slower with 3000 records of 16 columns.  So I went with DAO, which still takes about twice as long as the array method.  Turning the ADO to DAO was easy, especially with this <a href="http://www.ozgrid.com/forum/showthread.php?t=37398" title="Dennis Wallentin DAO code sample to read workbook" target="_blank">concise sample from XL-Dennis</a>.</p>
<p>As Jeff Weir pointed out in a comment, this does require a reference (Tools>References) to the Microsoft DAO 3.5 Object Library.  I&#8217;ve been switching some code over to late binding, but there doesn&#8217;t seem to be much enthusiasm for this with DAO.  I&#8217;m not sure if that&#8217;s because it&#8217;s so pervasive and well-established, or for some other reason.</p>
<p>The core logic of the routine is pretty simple.  In pseudo-English:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">For each column in the columns to be normalized<br />
Select all repeating columns<br />
and Select (create) a new column, giving it the same name each time (&quot;Team&quot; in this example)<br />
and Select the column with that team's data, giving it the same name each time (&quot;Home Runs&quot; in this example<br />
and Union it to the Select statement created in the next loop iteration</div></div>
<p>Without further ado (heh heh) here&#8217;s the routine.</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">'Requires a reference to DAO 3.5 or later<br />
</span><span style="color: #008000;">'Arguments<br />
</span><span style="color: #008000;">'List: The range to be normalized.<br />
</span><span style="color: #008000;">'RepeatingColsCount: The number of columns, starting with the leftmost,<br />
</span><span style="color: #008000;">' &nbsp; whose headings remain the same.<br />
</span><span style="color: #008000;">'NormalizedColHeader: The column header for the rolled-up category.<br />
</span><span style="color: #008000;">'DataColHeader: The column header for the normalized data.<br />
</span><span style="color: #008000;">'NewWorkbook: Put the sheet with the data in a new workbook?<br />
</span><span style="color: #008000;">'<br />
</span><span style="color: #008000;">'NOTE: The data must be in a contiguous range and the<br />
</span><span style="color: #008000;">'rows that will be repeated must be to the left,<br />
</span><span style="color: #008000;">'with the rows to be normalized to the right.<br />
</span><br />
<span style="color: #E56717; font-weight: bold;">Sub</span> NormalizeList_SQL_DAO(List <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Range, RepeatingColsCount <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NormalizedColHeader <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, DataColHeader <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Optional</span> NewWorkbook <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span> = <span style="color: #00C2FF; font-weight: bold;">False</span>)<br />
<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> FirstNormalizingCol <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, NormalizingColsCount <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> RepeatingColsHeaders <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span>, NormalizingColsHeaders <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> RepeatingColsIndex <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, NormalizingColsIndex <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> wbSource <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Workbook, wbTarget <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Workbook<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> wsTarget <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Worksheet<br />
<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> daoWorkSpace <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Workspace<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> daoWorkbook <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Database<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> daoRecordset <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Recordset<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> strSql <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> strExtendedProperties <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> List<br />
&nbsp; &nbsp; <span style="color: #008000;">'If the normalized list won't fit, you must quit.<br />
</span> &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> .Rows.Count * (.Columns.Count - RepeatingColsCount) &gt; .Parent.Rows.Count <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; MsgBox <span style="color: #800000;">&quot;The normalized list will be too many rows.&quot;</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vbExclamation + vbOKOnly, <span style="color: #800000;">&quot;Sorry&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #E56717; font-weight: bold;">Exit</span> <span style="color: #E56717; font-weight: bold;">Sub</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; <span style="color: #008000;">'List.Parent.Parent is the lists Workbook<br />
</span> &nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> wbSource = List.Parent.Parent<br />
&nbsp; &nbsp; <span style="color: #008000;">'The columns to normalize must be to the right of the columns that will repeat<br />
</span> &nbsp; &nbsp;FirstNormalizingCol = RepeatingColsCount + 1<br />
&nbsp; &nbsp; NormalizingColsCount = .Columns.Count - RepeatingColsCount<br />
&nbsp; &nbsp; <span style="color: #008000;">'Get the header names of the repeating columns<br />
</span> &nbsp; &nbsp;RepeatingColsHeaders = List.Cells(1).Resize(1, RepeatingColsCount).Value<br />
&nbsp; &nbsp; <span style="color: #008000;">'Get the header names of the normalizing columns<br />
</span> &nbsp; &nbsp;NormalizingColsHeaders = List.Cells(FirstNormalizingCol).Resize(1, NormalizingColsCount).Value<br />
<br />
&nbsp; &nbsp; strSql = vbNullString<br />
&nbsp; &nbsp; <span style="color: #008000;">'loop through each normalizing column<br />
</span> &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">For</span> NormalizingColsIndex = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> NormalizingColsCount<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'Create an individual Select for the normalizing column<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;strSql = strSql &amp; <span style="color: #800000;">&quot; SELECT &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'Select all the repeating columns<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">For</span> RepeatingColsIndex = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> RepeatingColsCount<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strSql = strSql &amp; RepeatingColsHeaders(1, RepeatingColsIndex) &amp; <span style="color: #800000;">&quot;, &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> RepeatingColsIndex<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'Select the normalizing column and assign the NormalizedColHeader field name<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'and select the data being counted and assign it the DataColHeader field name<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;strSql = strSql &amp; <span style="color: #800000;">&quot;'&quot;</span> &amp; NormalizingColsHeaders(1, NormalizingColsIndex) &amp; <span style="color: #800000;">&quot;'&quot;</span> &amp; <span style="color: #800000;">&quot; AS &quot;</span> &amp; NormalizedColHeader &amp; _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #800000;">&quot;, &quot;</span> &amp; NormalizingColsHeaders(1, NormalizingColsIndex) &amp; <span style="color: #800000;">&quot; AS &quot;</span> &amp; DataColHeader<br />
&nbsp; &nbsp; &nbsp; &nbsp; strSql = strSql &amp; <span style="color: #800000;">&quot; FROM [&quot;</span> &amp; List.Parent.Name &amp; _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #800000;">&quot;$&quot;</span> &amp; List.Address(rowabsolute:=<span style="color: #00C2FF; font-weight: bold;">False</span>, columnabsolute:=<span style="color: #00C2FF; font-weight: bold;">False</span>) &amp; <span style="color: #800000;">&quot;]&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> NormalizingColsIndex &lt; NormalizingColsCount <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'Union the Select statements created for the normalizing columns<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strSql = strSql &amp; <span style="color: #800000;">&quot; UNION ALL&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> NormalizingColsIndex<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<span style="color: #008000;">'Set up the DAO connection<br />
</span>strExtendedProperties = <span style="color: #800000;">&quot;Excel 8.0;HDR=Yes;IMEX=1&quot;</span><br />
<span style="color: #151B8D; font-weight: bold;">Set</span> daoWorkSpace = DBEngine.Workspaces(0)<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> daoWorkbook = daoWorkSpace.OpenDatabase(wbSource.FullName, <span style="color: #00C2FF; font-weight: bold;">False</span>, <span style="color: #00C2FF; font-weight: bold;">True</span>, strExtendedProperties)<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> daoRecordset = daoWorkbook.OpenRecordset(strSql, dbOpenForwardOnly)<br />
<br />
<span style="color: #008000;">'Put the normal data in the same workbook, or a new one.<br />
</span><span style="color: #8D38C9; font-weight: bold;">If</span> NewWorkbook <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> wbTarget = Workbooks.Add<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> wsTarget = wbTarget.Worksheets(1)<br />
<span style="color: #8D38C9; font-weight: bold;">Else</span><br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> wbSource = List.Parent.Parent<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">With</span> wbSource.Worksheets<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> wsTarget = .Add(after:=.Item(.Count))<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<br />
<span style="color: #008000;">'copy the headers and DAO recordset to the new worksheet<br />
</span><span style="color: #8D38C9; font-weight: bold;">With</span> wsTarget<br />
&nbsp; &nbsp; .Cells(1, 1).Resize(1, RepeatingColsCount).Value = RepeatingColsHeaders<br />
&nbsp; &nbsp; .Cells(1, RepeatingColsCount + 1) = NormalizedColHeader<br />
&nbsp; &nbsp; .Cells(1, RepeatingColsCount + 2) = DataColHeader<br />
&nbsp; &nbsp; .Cells(2, 1).CopyFromRecordset daoRecordset<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<br />
<span style="color: #008000;">'clean up<br />
</span>daoRecordset.<span style="color: #8D38C9; font-weight: bold;">Close</span><br />
daoWorkbook.<span style="color: #8D38C9; font-weight: bold;">Close</span><br />
daoWorkSpace.<span style="color: #8D38C9; font-weight: bold;">Close</span><br />
<span style="color: #151B8D; font-weight: bold;">Set</span> daoRecordset = <span style="color: #00C2FF; font-weight: bold;">Nothing</span><br />
<span style="color: #151B8D; font-weight: bold;">Set</span> daoWorkbook = <span style="color: #00C2FF; font-weight: bold;">Nothing</span><br />
<span style="color: #151B8D; font-weight: bold;">Set</span> daoWorkSpace = <span style="color: #00C2FF; font-weight: bold;">Nothing</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>If you break after strSql is created, it looks like this:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT League, Year, 'ATL' AS Team, ATL AS HomeRuns FROM [HR-NL$A1:R110]<br />
&nbsp;UNION ALL<br />
&nbsp;SELECT League, Year, 'CHC' AS Team, CHC AS HomeRuns FROM [HR-NL$A1:R110]<br />
&nbsp;UNION ALL<br />
&nbsp;...<br />
&nbsp;SELECT League, Year, 'MIL' AS Team, MIL AS HomeRuns FROM [HR-NL$A1:R110]</div></div>
<p>Call it like this:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">NormalizeList_SQL_DAO ActiveSheet.UsedRange, 2, &quot;Team&quot;, &quot;HomeRuns&quot;, False</div></div>
<p>One pitfall of this SQL version is the <a href="http://support.microsoft.com/kb/194124" title="Mixed Data Type issue with Excel ISAM driver" target="_blank">mixed data-type</a> issue with the Excel ISAM driver.  In this example it converts all the home run counts from numbers to text because of the blanks in the data.</p>
<p>All in all, I think the array approach is better than SQL for this use.  The core skill of creating SQL in VBA is a valuable one though, and one I&#8217;m glad to be developing.</p>
<p>I updated the <a href="http://yoursumbuddy.com/downloads/post_0016_Data_Normalizer.zip"  title="Data Normalizer .xls zip file" target="_blank">Data Normalizer</a> .xls to include this code.</p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/data-normalizer-the-sql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Create Pivot Table Named Ranges</title>
		<link>http://yoursumbuddy.com/create-pivot-table-named-ranges/</link>
		<comments>http://yoursumbuddy.com/create-pivot-table-named-ranges/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 06:45:41 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Pivot Tables]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=879</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/create-pivot-table-named-ranges/">Create Pivot Table Named Ranges</a></p><p>Create Pivot Table Named Ranges I need to calculate percentiles from subsets of data in a pivot table. In order to refer to pivot table fields, it sure would be nice if they had dynamic named ranges. So I wrote &#8230; <a href="http://yoursumbuddy.com/create-pivot-table-named-ranges/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/create-pivot-table-named-ranges/">Create Pivot Table Named Ranges</a></p><h1><a title="Permalink to Create Pivot Table Named Ranges" href="http://yoursumbuddy.com/create-pivot-table-named-ranges/" rel="bookmark">Create Pivot Table Named Ranges</a></h1>
<p>I need to calculate percentiles from subsets of data in a pivot table.  In order to refer to pivot table fields, it sure would be nice if they had dynamic named ranges.  So I wrote some code to create pivot table named ranges.</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/04/Post_0020_pivot_named_range_generator_intellisense.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/04/Post_0020_pivot_named_range_generator_intellisense.jpg" alt="pivot table named range generator intellisense" title="pivot table named range generator intellisense" width="427" height="202" class="alignnone size-full wp-image-883" /></a></p>
<p>Programming pivot tables is fun.  The extensive object model is a VBA wonderland with treats around every turn.  There are great web sites out there with excellent pivot table coding samples &#8211; <a href="http://contextures.com/tiptech.html" title="Contextures site index" target="_blank">Contextures</a> leaps to mind.  In terms of identifying PivotFields, DataFields and other pivot table ranges, Jon Peltier <a href="http://peltiertech.com/WordPress/referencing-pivot-table-ranges-in-vba/" title="Jon Peltier - referencing pivot table ranges" target="_blank">wrote a superb post</a> in 2009 that&#8217;s still generating discussion.</p>
<p>My code is pretty simple.  It cycles through the data fields, and any other visible fields, in the specified pivot table and adds a named range for each one to the pivot table&#8217;s worksheet:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Sub</span> RefreshPivotNamedRanges(pvt <span style="color: #151B8D; font-weight: bold;">As</span> Excel.PivotTable)<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> ws <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Worksheet<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> pvtField <span style="color: #151B8D; font-weight: bold;">As</span> Excel.PivotField<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> FieldType <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> pvt<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> ws = .Parent<br />
&nbsp; &nbsp; ClearOldNames ws, pvt<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> <span style="color: #8D38C9; font-weight: bold;">Each</span> pvtField <span style="color: #8D38C9; font-weight: bold;">In</span> .DataFields<br />
&nbsp; &nbsp; &nbsp; &nbsp; AddNamedRange ws, pvt.Name, <span style="color: #800000;">&quot;Data&quot;</span>, pvtField.SourceName, pvtField.DataRange.Address<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> pvtField<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> <span style="color: #8D38C9; font-weight: bold;">Each</span> pvtField <span style="color: #8D38C9; font-weight: bold;">In</span> .PivotFields<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Select</span> <span style="color: #8D38C9; font-weight: bold;">Case</span> pvtField.Orientation<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Case</span> xlHidden<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">GoTo</span> next_one<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Case</span> xlPageField<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FieldType = <span style="color: #800000;">&quot;Page&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Case</span> xlDataField<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FieldType = <span style="color: #800000;">&quot;Data&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Case</span> xlRowField<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FieldType = <span style="color: #800000;">&quot;Row&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Case</span> xlColumnField<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FieldType = <span style="color: #800000;">&quot;Col&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">Select</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; AddNamedRange ws, pvt.Name, FieldType, pvtField.Name, pvtField.DataRange.Address<br />
next_one:<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> pvtField<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>The PivotField.Orientation property has five enumerated constants that tell you what type of field it is &#8211; xlDataField, xlRowField, etc. The For/Next loop skips over the ones that come up xlHidden and processes the rest.  Strangely, even though there&#8217;s a xlDataField type, and even though I can refer to pvt.PivotFields(&#8220;Sum of Home Runs&#8221;), the data fields don&#8217;t actually show up when cycling through the PivotFields.  Instead, to get those fields the code first cycles through the pivot table&#8217;s DataFields collection.  </p>
<p>When calling the AddNamedRange routine for a DataField, the codes passes its SourceName, not the Name.  So in this example, the new name will include &#8220;Home Runs,&#8221; not &#8220;Sum of Home Runs.&#8221;  You may want to pass the Name instead.</p>
<p>This next routine does what it says and clears out the previous range names associated with the pivot table.  It&#8217;s not fool-proof.  For example, if the pivot table name was changed, it won&#8217;t find the range names.  I should probably use the pivot table&#8217;s Tag property to store names that won&#8217;t get changed:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Sub</span> ClearOldNames(ws <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Worksheet, pvt <span style="color: #151B8D; font-weight: bold;">As</span> Excel.PivotTable)<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> nm <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Name<br />
<br />
<span style="color: #8D38C9; font-weight: bold;">For</span> <span style="color: #8D38C9; font-weight: bold;">Each</span> nm <span style="color: #8D38C9; font-weight: bold;">In</span> ws.Names<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> InStr(nm.Name, <span style="color: #800000;">&quot;!_&quot;</span> &amp; pvt.Name) &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; nm.Delete<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<span style="color: #8D38C9; font-weight: bold;">Next</span> nm<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>The routine below adds the worksheet-level names to the pivot table&#8217;s sheet.  It calls a function that replaces spaces and other characters that aren&#8217;t allowed in range names (code at the end of the post).  It also adds a &#8220;_&#8221; at the beginning of the name to hopefully avoid illegal names like &#8220;A1&#8243;:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Sub</span> AddNamedRange(<span style="color: #151B8D; font-weight: bold;">ByRef</span> ws <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Worksheet, <span style="color: #151B8D; font-weight: bold;">ByVal</span> PivotName <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> FieldType <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> PivotFieldName <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> PivotFieldAddress <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>)<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> CleanedRangeName <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<br />
CleanedRangeName = <span style="color: #800000;">&quot;_&quot;</span> &amp; GetCleanedRangeName(PivotName &amp; <span style="color: #800000;">&quot;_&quot;</span> &amp; FieldType &amp; <span style="color: #800000;">&quot;_&quot;</span> &amp; PivotFieldName, <span style="color: #800000;">&quot;_&quot;</span>)<br />
ws.Names.Add Name:=CleanedRangeName, RefersTo:=<span style="color: #800000;">&quot;=&quot;</span> &amp; PivotFieldAddress &amp; <span style="color: #800000;">&quot;&quot;</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>To automate this stuff, put the code in a regular module and call RefreshPivotNamedRanges from a PivotTableUpdate event.  The names will be regenerated each time the pivot table is refreshed, either manually or when you drag a field, or however.</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/04/Post_0020_pivot_named_range_generator_NM1.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/04/Post_0020_pivot_named_range_generator_NM1.jpg" alt="Create Pivot Table Named Ranges - Name Manager 1" title="Create Pivot Table Named Ranges - Name Manager 1" width="766" height="424" class="alignnone size-full wp-image-886" /></a></p>
<p>So now my Percentile array formula can find the value for the selected year and percentile:<br />
<a href="http://yoursumbuddy.com/wp-content/uploads/2012/04/Post_0020_pivot_named_range_generator_percentile.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/04/Post_0020_pivot_named_range_generator_percentile.jpg" alt="" title="create pivot table named ranges - percentile formula" width="684" height="419" class="size-full wp-image-890" /></a></p>
<p>Here&#8217;s the code to get the legal range names.  You&#8217;ll need to set a reference to Microsoft VBScript Regular Expressions (at least if you&#8217;re an early binder):</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Function</span> GetCleanedRangeName(RangeName <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, SpaceReplacement <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> NewName <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<br />
<span style="color: #008000;">'the &quot;\&quot; character escapes the Regex &quot;reserved&quot; characters<br />
</span><span style="color: #008000;">'x22 is double-quote<br />
</span>NewName = Regex_Replace(RangeName, <span style="color: #800000;">&quot;[\\\^\|\(\)\[\]\$\{\}\-x22/`~!@#%&amp;=;:&lt;&gt;]&quot;</span>, <span style="color: #800000;">&quot;&quot;</span>, <span style="color: #00C2FF; font-weight: bold;">False</span>)<br />
<span style="color: #008000;">'get rid of multiple contiguous spaces<br />
</span>NewName = Application.WorksheetFunction.Trim(NewName)<br />
<span style="color: #008000;">'255 is the length limit for a legal name<br />
</span>NewName = Left(Replace(NewName, <span style="color: #800000;">&quot; &quot;</span>, SpaceReplacement), 255)<br />
GetCleanedRangeName = NewName<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span><br />
<br />
<span style="color: #E56717; font-weight: bold;">Function</span> Regex_Replace(OriginalString <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, Pattern <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, Replacement, varIgnoreCase <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span>) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<span style="color: #008000;">' Function matches pattern, returns true or false<br />
</span><span style="color: #008000;">' varIgnoreCase must be TRUE (match is case insensitive) or FALSE (match is case sensitive)<br />
</span><span style="color: #008000;">' Use this string to replace double-quoted substrings - &quot;&quot;&quot;[^&quot;&quot;\r\n]*&quot;&quot;&quot;<br />
</span><span style="color: #151B8D; font-weight: bold;">Dim</span> objRegExp <span style="color: #151B8D; font-weight: bold;">As</span> VBScript_RegExp_55.RegExp<br />
<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> objRegExp = <span style="color: #E56717; font-weight: bold;">New</span> VBScript_RegExp_55.RegExp<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> objRegExp<br />
&nbsp; &nbsp; .Pattern = Pattern<br />
&nbsp; &nbsp; .IgnoreCase = varIgnoreCase<br />
&nbsp; &nbsp; .Global = <span style="color: #00C2FF; font-weight: bold;">True</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
Regex_Replace = objRegExp.Replace(OriginalString, Replacement)<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> objRegExp = <span style="color: #00C2FF; font-weight: bold;">Nothing</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>This has undergone a massive .5 days of testing, so I can guarantee there&#8217;s glitches. But if you&#8217;d like to give it a spin, <a href="http://yoursumbuddy.com/downloads/post_0020_Generate_Pivot_Table_Named_Ranges.zip" title="Create Pivot Table Named Ranges sample file">here you go</a>.  It&#8217;s an Excel 2007/10 file as earlier versions don&#8217;t support the &#8220;Repeat All Item Labels&#8221; pivot setting that I rely on for the Percentile array formula.  Other than that, it works just as well in Excel 2003.</p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/create-pivot-table-named-ranges/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Prompt to Save Addins</title>
		<link>http://yoursumbuddy.com/prompt-to-save-addin/</link>
		<comments>http://yoursumbuddy.com/prompt-to-save-addin/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 04:42:39 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Addins]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=848</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/prompt-to-save-addin/">Prompt to Save Addins</a></p><p>Prompt to Save Addin I&#8217;m pretty good about saving my work, and probably hit Ctrl-S a couple hundred times a day. And of course, as long as things don&#8217;t crash, Excel makes it hard to lose your work. One exception &#8230; <a href="http://yoursumbuddy.com/prompt-to-save-addin/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/prompt-to-save-addin/">Prompt to Save Addins</a></p><h1><a title="Permalink to Prompt to Save Addin" href="http://yoursumbuddy.com/prompt-to-save-addin/" rel="bookmark">Prompt to Save Addin</a></h1>
<p>I&#8217;m pretty good about saving my work, and probably hit Ctrl-S a couple hundred times a day.  And of course, as long as things don&#8217;t crash, Excel makes it hard to lose your work.  One exception is addins, which don&#8217;t trigger a save prompt when you close them after making changes, at least when the <a href="http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._workbook.isaddin.aspx" title="MSDN IsAddin definition" target="_blank">IsAddin </a>property is True.  So I have a routine in my most-used addins that reminds me to save them.  But I don&#8217;t have it in all of them.  The other day this bit me, and I lost 10 minutes of work on an xlam.  I decided to generalize my prompt to save addins and put it in an application-level event in my main utility addin.  (These decisions come easy; what&#8217;s more fun than building a new tool?)  This way I&#8217;m prompted to save any time I close an addin that I&#8217;ve changed.</p>
<p>If you&#8217;ve never used application-level events, <a href="http://www.cpearson.com/excel/appevent.aspx" title="Chip Pearson's application events page" target="_blank">Chip Pearson&#8217;s site</a> has some good information. Okay, here&#8217;s how you can add this code to your favorite utility addin (<a href="http://www.rondebruin.nl/personal.htm" title="Ron de Bruin's personal.xls page" target="_blank">personal.xls</a> will do nicely).</p>
<p>Create a Class called &#8220;clsApplication&#8221; and paste this code into it:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #8D38C9; font-weight: bold;">WithEvents</span> app <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Application<br />
<br />
<span style="color: #E56717; font-weight: bold;">Private</span> <span style="color: #E56717; font-weight: bold;">Sub</span> App_WorkbookBeforeClose(<span style="color: #151B8D; font-weight: bold;">ByVal</span> wb <span style="color: #151B8D; font-weight: bold;">As</span> Workbook, Cancel <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span>)<br />
<span style="color: #8D38C9; font-weight: bold;">If</span> wb.IsAddin <span style="color: #8D38C9; font-weight: bold;">And</span> <span style="color: #8D38C9; font-weight: bold;">Not</span> wb.Saved <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> MsgBox(wb.Name &amp; <span style="color: #800000;">&quot;Addin&quot;</span> &amp; vbCrLf &amp; <span style="color: #800000;">&quot;is unsaved. Save?&quot;</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vbExclamation + vbYesNo, <span style="color: #800000;">&quot;Unsaved Addin&quot;</span>) = vbYes <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> ExcelInstanceCount &gt; 1 <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MsgBox <span style="color: #800000;">&quot;More than one Excel instance running.&quot;</span> &amp; vbCrLf &amp; _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #800000;">&quot;Save cancelled&quot;</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vbInformation, <span style="color: #800000;">&quot;Sorry&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #E56717; font-weight: bold;">Exit</span> <span style="color: #E56717; font-weight: bold;">Sub</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wb.Save<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>Create a global variable to hold the class instance.  At the top of a regular code module (before any procedures) put this line:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Public cApplication As clsApplication</div></div>
<p>(I like to put all my global variables like the one above in a single module, called modGlobals.)</p>
<p>In the ThisWorkbook WorkbookOpen event for your utility addin, put this code:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #151B8D; font-weight: bold;">Set</span> cApplication = <span style="color: #E56717; font-weight: bold;">New</span> clsApplication<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> cApplication.app = Excel.Application</div></div>
<p>One problem is that when an addin is saved with more than one instance of Excel open, it gets saved to a new location (maybe the folder of ActiveWorkbook?).  So I added code to the BeforeClose event to cancel the save if that&#8217;s true.  Here&#8217;s the function that does the checking:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Function</span> GetExcelInstanceCount() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> hwnd <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #8D38C9; font-weight: bold;">Do</span><br />
&nbsp; &nbsp; hwnd = FindWindowEx(0&amp;, hwnd, <span style="color: #800000;">&quot;XLMAIN&quot;</span>, vbNullString)<br />
&nbsp; &nbsp; i = i + 1<br />
<span style="color: #8D38C9; font-weight: bold;">Loop</span> <span style="color: #8D38C9; font-weight: bold;">Until</span> hwnd = 0<br />
GetExcelInstanceCount = i - 1<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>One last thing to do is add code to my global error handler that re-instantiates the cApplication.Class and its App property if they&#8217;ve gotten lost, which can easily happen during debugging.</p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/prompt-to-save-addin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solving the NPR Sunday Puzzle &#8211; #3</title>
		<link>http://yoursumbuddy.com/solving-the-npr-sunday-puzzle-3/</link>
		<comments>http://yoursumbuddy.com/solving-the-npr-sunday-puzzle-3/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 05:02:26 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Formulas]]></category>
		<category><![CDATA[Fun]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=786</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/solving-the-npr-sunday-puzzle-3/">Solving the NPR Sunday Puzzle &#8211; #3</a></p><p>Solving the NPR Sunday Puzzle &#8211; #3 Every time I hear Will Shortz say &#8220;name a country of the world&#8221; my heart beats a little faster, cause I know there&#8217;s probably an array-formula post in it. This week was no &#8230; <a href="http://yoursumbuddy.com/solving-the-npr-sunday-puzzle-3/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/solving-the-npr-sunday-puzzle-3/">Solving the NPR Sunday Puzzle &#8211; #3</a></p><h1><a title="Permalink to Solving the NPR Sunday Puzzle - #3" href="http://yoursumbuddy.com/solving-the-npr-sunday-puzzle-3/" rel="bookmark">Solving the NPR Sunday Puzzle &#8211; #3</a></h1>
<p>Every time I hear Will Shortz say &#8220;name a country of the world&#8221; my heart beats a little faster, cause I know there&#8217;s probably an array-formula post in it. This week was no exception:</p>
<p><em>&#8220;Name an article of clothing that contains three consecutive letters of the alphabet consecutively in the word. For example, &#8220;canopy&#8221; contains the consecutive letters N-O-P. This article of clothing is often worn in a country whose name also contains three consecutive letters of the alphabet together. What is the clothing article, and what is the country?&#8221;<br />
</em></p>
<p><strong>This spreadsheet is live. Double-clicking in a cell in the 2nd column shows the formula.  You can then drag the lower-right fill handle to see the whole gnarly thing.</strong></p>
<p><iframe src="https://r.office.microsoft.com/r/rlidExcelEmbed?su=-2945953654735389335&amp;Fi=SDD71DDEC264BBBD69!271&amp;ak=t%3d0%26s%3d0%26v%3d!AH2ORvfomejzd2U&amp;kip=1&amp;AllowTyping=True&amp;ActiveCell='NPR%20Sunday%20Puzzle%20%233'!B2&amp;Item='NPR%20Sunday%20Puzzle%20%233'!A1%3AAU258&amp;wdHideGridlines=True&amp;wdDownloadButton=True" frameborder="0" scrolling="no" width="700" height="500"></iframe></p>
<p>Countries are a lot more list-friendly, so I solved that part first.  There are two types of solutions above: an array formula in the 2nd column, and a conditional formatting solution in the 3rd to 40-somethingth column. The 2nd solution is the way I&#8217;d do it for serious work, but the array formula is more fun:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">=IFERROR(<br />
MID(A4,MIN(IF(<br />
CODE(MID(LOWER($A4),ROW(INDIRECT(&quot;1:&quot;&amp; LEN($A4)-2)),1))+1=<br />
CODE(MID(LOWER($A4),ROW(INDIRECT(&quot;2:&quot;&amp; LEN($A4)-1)),1)),<br />
IF(CODE(MID(LOWER($A4),ROW(INDIRECT(&quot;1:&quot;&amp; LEN($A4)-2)),1))+2=<br />
CODE(MID(LOWER($A4),ROW(INDIRECT(&quot;3:&quot;&amp; LEN($A4))),1)),<br />
ROW(INDIRECT(&quot;1:&quot;&amp; LEN($A4)-2))))),3),<br />
&quot;&quot;)</div></div>
<p>This formula says to compare every letter in the country name to the next two letters.  If the numeric code for a letter is one less than the letter after it, and two less than the letter after that, return those three letters. The reason the 2nd column is mostly blank is because surprisingly few country names have three consecutive letters.  (Or my formula sucks.)</p>
<p>Here&#8217;s how it works. Let&#8217;s assume the formula refers to Albania, the 3rd country in the list:</p>
<p><strong>LEN</strong> returns the length of the country&#8217;s name.</p>
<p><strong>INDIRECT(&#8220;1:&#8221;&#038; LEN($A4)-2)</strong> evaluates to (1:5).</p>
<p><strong>ROW(INDIRECT(&#8220;1:&#8221;&#038; LEN($A4)-2))</strong> evaluates to {1;2;3;4;5}. This tells the array formula which characters in &#8220;Albania&#8221; to evaluate against their respective two next characters.  <a href="http://www.dailydoseofexcel.com/archives/2004/08/25/using-row-in-array-formulas/" title="ROW in array functions" target="_blank">Using ROW this way</a> is very handy in array formulas.</p>
<p><strong>CODE(MID(LOWER($A4),ROW(INDIRECT(&#8220;1:&#8221;&#038; LEN($A4)-2)),1))</strong> resolves to {97;108;98;97;110}. In other words, the numeric values of the first five letters of Albania are 97, 108, etc. <a title="CODE worksheet function" href="http://office.microsoft.com/en-us/excel-help/code-function-HP010342275.aspx" target="_blank">CODE</a> is the function that returns the values. LOWER converts each letter to lower case, otherwise, for example, a lowercase &#8220;b&#8221; wouldn&#8217;t be seen as following an uppercase &#8220;A&#8221;. The MID piece tells the array formula to parse each of the first 5 letters in the word.</p>
<p>Okay, now we&#8217;re getting close. This bit:<br />
<strong>CODE(MID(LOWER($A4),ROW(INDIRECT(&#8220;1:&#8221;&#038; LEN($A4)-2)),1))+1=<br />
CODE(MID(LOWER($A4),ROW(INDIRECT(&#8220;2:&#8221;&#038; LEN($A4)-1)),1))</strong> resolves to<br />
{98;109;99;98;111}={108;98;97;110;105}, which in turn resolves to {FALSE;FALSE;FALSE;FALSE;FALSE}. In other words, one added to the code for the first five letters in &#8220;Albania&#8221; doesn&#8217;t ever equal the code for their respective next letters. So there&#8217;s not even two consecutive letters. What a country!  The next two lines in the formula repeat the comparison, this time with the 2nd through 7th letters.</p>
<p>The 2nd line, which starts with MID, and the 2nd to last line say that if the whole mess is true, return the three letters that start at that position.</p>
<p>The IFERROR function at the beginning and the last line simply say that if the formula errors (doesn&#8217;t find three consecutive letters) put a blank in the cell. <a title="Excel worksheet IFERROR function" href="http://office.microsoft.com/en-us/excel-help/iferror-function-HA001231765.aspx" target="_blank">IFERROR </a>is available in Excel 2007 and 2010. I like it very much as they keep formulas like this from being twice as ridiculously long.</p>
<p>Much of the evaluation above was done using the F9 key. Selecting part of a formula and then pressing F9 evaluates that piece of the formula, a <a title="F9 for evaluating formulas" href="http://www.techrepublic.com/article/use-these-handy-tips-to-debug-your-excel-formulas/1033815" target="_blank">very useful feature</a>.</p>
<p>There are only two countries that meet the criteria, Afghanistan and Tuvalu.  I figured it was probably the former and soon enough realized the article of clothing was &#8220;<a href="http://en.wikipedia.org/wiki/Hijab" title="Wikipedia hijab article" target="_blank">hijab</a>.&#8221;</p>
<p>If you&#8217;ve made it this far, thanks!  Oh yeah, the multiple cell and conditional formatting way works similarly to the array formula, only by breaking it up it&#8217;s a lot easier.</p>
<p>If anybody has a better array formula, please share.</p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/solving-the-npr-sunday-puzzle-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Copy Table Data While Not Breaking References</title>
		<link>http://yoursumbuddy.com/copy-table-data-while-not-breaking-references/</link>
		<comments>http://yoursumbuddy.com/copy-table-data-while-not-breaking-references/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 15:27:15 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Tables]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=757</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/copy-table-data-while-not-breaking-references/">Copy Table Data While Not Breaking References</a></p><p>Copy Table Data While Not Breaking References I&#8217;ve mentioned before I&#8217;m a big fan of tables in Excel 2010. One way I use them is in models, where each table represents a different scenario. The models let users create new &#8230; <a href="http://yoursumbuddy.com/copy-table-data-while-not-breaking-references/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/copy-table-data-while-not-breaking-references/">Copy Table Data While Not Breaking References</a></p><h1><a title="Permalink to Copy Table Data While Not Breaking References" href="http://yoursumbuddy.com/copy-table-data-while-not-breaking-references/" rel="bookmark">Copy Table Data While Not Breaking References</a></h1>
<p>I&#8217;ve mentioned before I&#8217;m a big fan of tables in Excel 2010.  One way I use them is in models, where each table represents a different scenario.  The models let users create new scenarios, based either on an existing one or a blank template.  Each version is stored in a table in its own worksheet.  These tables always have the same fields (columns) but the values in the variable fields are different.  The number of rows can differ from table to table.</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/04/post_0017_coffee_model.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/04/post_0017_coffee_model.jpg" alt="Coffee Model" title="coffee model" width="686" height="382" class="alignnone size-full wp-image-776" /></a></p>
<p>I often want to copy, in VBA, the contents from a &#8220;source&#8221; to a &#8220;target&#8221; table.  If I just copy the whole thing, the target table will be overwritten and renamed &#8211; something like &#8220;tblSource1&#8243; (adding a &#8220;1&#8243; to the source table name).  That breaks any formulas referring to &#8220;tblTarget.&#8221;  They&#8217;ll show a #REF error because they can&#8217;t find &#8220;tblTarget.&#8221;  So I need code that copies the table data from tblSource to tblTarget without completely replacing tblTarget.</p>
<p>I&#8217;ve been writing code on a case-by-case basis, but thought that I&#8217;d generalize it a bit more.  In addition to keeping the table&#8217;s identity intact, it should copy the source&#8217;s totals row if there is one, and turn off the target&#8217;s total row if there isn&#8217;t.  The number of rows should increase or decrease to match the source.  And, although I&#8217;ve only ever copied tables as values, I want the option to copy formulas.</p>
<p>I thought about dealing with a different number of columns but, at least in my uses so far, that shouldn&#8217;t happen.  If I ever do try to accommodate models with changing numbers of fields, I think I&#8217;d do some testing before ever calling this code, and adjust the headers in another procedure.</p>
<p>So here&#8217;s what I came up with:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Sub</span> CopyTableData(loSource <span style="color: #151B8D; font-weight: bold;">As</span> Excel.ListObject, loTarget <span style="color: #151B8D; font-weight: bold;">As</span> Excel.ListObject, <span style="color: #151B8D; font-weight: bold;">Optional</span> CopyFormulas <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span> = <span style="color: #00C2FF; font-weight: bold;">False</span>)<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> FormulaCells <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Range<br />
<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> loTarget<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> .DataBodyRange.Rows.Count &lt;&gt; loSource.DataBodyRange.Rows.Count <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'have to clear target otherwise old table content may be outside new table<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;.DataBodyRange.Cells.Clear<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'set target rows count to source rows count<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;.Resize .Range.Cells(1).Resize(loSource.HeaderRowRange.Rows.Count + _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;loSource.DataBodyRange.Rows.Count, loSource.Range.Columns.Count)<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; loSource.DataBodyRange.Copy Destination:=.DataBodyRange.Cells(1)<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> CopyFormulas <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">On</span> <span style="color: #151B8D; font-weight: bold;">Error</span> <span style="color: #151B8D; font-weight: bold;">Resume</span> <span style="color: #8D38C9; font-weight: bold;">Next</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'any formulas?<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> FormulaCells = .DataBodyRange.SpecialCells(xlCellTypeFormulas)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">On</span> <span style="color: #151B8D; font-weight: bold;">Error</span> <span style="color: #8D38C9; font-weight: bold;">GoTo</span> 0<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'if yes, then replace any references to source table with target<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> <span style="color: #8D38C9; font-weight: bold;">Not</span> FormulaCells <span style="color: #8D38C9; font-weight: bold;">Is</span> <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FormulaCells.Replace what:=loSource.Name, replacement:=.Name, lookat:=xlPart<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .DataBodyRange.Value2 = .DataBodyRange.Value2<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<br />
&nbsp; &nbsp; <span style="color: #008000;">'turn target Totals row on or off to match Source<br />
</span> &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> loSource.ShowTotals <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .ShowTotals = <span style="color: #00C2FF; font-weight: bold;">True</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; loSource.TotalsRowRange.Copy Destination:=.TotalsRowRange<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .ShowTotals = <span style="color: #00C2FF; font-weight: bold;">False</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>One thing I learned is that there are two Resizes in a table (listobject).  The first type, the Range property, was familiar, e.g.,</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Range(&quot;A1&quot;).Resize(20,1)</div></div>
<p>&#8230; which yields a range object whose address is A1:A20.</p>
<p>The second is the Listobject.Resize method, which allows you to modify a table&#8217;s range, e.g.,</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">loTarget.Resize(Range(&quot;A1:F20&quot;)</div></div>
<p>which will change loTarget&#8217;s range to A1:F20.</p>
<p>Both of these types of Resizes are used in the code above, in the same line, happily enough.</p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/copy-table-data-while-not-breaking-references/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data Normalizer</title>
		<link>http://yoursumbuddy.com/data-normalizer/</link>
		<comments>http://yoursumbuddy.com/data-normalizer/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 08:01:43 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Pivot Tables]]></category>
		<category><![CDATA[Tables]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=704</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/data-normalizer/">Data Normalizer</a></p><p>Data Normalizer Sometimes I get data like this&#8230; that needs to be like this&#8230; The goal here is to roll up all the home runs into one, much longer, column. The data will then be pivot-worthy. Generally, I need to &#8230; <a href="http://yoursumbuddy.com/data-normalizer/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/data-normalizer/">Data Normalizer</a></p><h1><a title="Permalink to Data Normalizer" href="http://yoursumbuddy.com/data-normalizer/" rel="bookmark">Data Normalizer</a></h1>
<p>Sometimes I get data like this&#8230;</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_abnormal_data1.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_abnormal_data1.jpg" alt="" title="abnormal data" width="841" height="144" class="alignnone size-full wp-image-747" /></a></p>
<p>that needs to be like this&#8230;</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_normalized_data.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_normalized_data.jpg" alt="" title="normalized data" width="279" height="521" class="alignnone size-full wp-image-751" /></a></p>
<p>The goal here is to roll up all the home runs into one, much longer, column.  The data will then be pivot-worthy.</p>
<p>Generally, I need to keep one or more leftmost column headers, in this case &#8220;League&#8221; and &#8220;Year.&#8221; I need a new column to describe the rolled-up category (&#8220;Team&#8221;) and one for the data itself (&#8220;Home Runs&#8221;). I&#8217;ve written code a couple of times to handle specific cases and thought I&#8217;d try to generalize it. Here&#8217;s the result:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">'Arguments<br />
</span><span style="color: #008000;">'List: The range to be normalized.<br />
</span><span style="color: #008000;">'RepeatingColsCount: The number of columns, starting with the leftmost,<br />
</span><span style="color: #008000;">' &nbsp; whose headings remain the same.<br />
</span><span style="color: #008000;">'NormalizedColHeader: The column header for the rolled-up category.<br />
</span><span style="color: #008000;">'DataColHeader: The column header for the normalized data.<br />
</span><span style="color: #008000;">'NewWorkbook: Put the sheet with the data in a new workbook?<br />
</span><span style="color: #008000;">'<br />
</span><span style="color: #008000;">'NOTE: The data must be in a contiguous range and the<br />
</span><span style="color: #008000;">'rows that will be repeated must be to the left,<br />
</span><span style="color: #008000;">'with the rows to be normalized to the right.<br />
</span><br />
<span style="color: #E56717; font-weight: bold;">Sub</span> NormalizeList(List <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Range, RepeatingColsCount <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, _<br />
&nbsp; &nbsp; NormalizedColHeader <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, DataColHeader <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, _<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Optional</span> NewWorkbook <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span> = <span style="color: #00C2FF; font-weight: bold;">False</span>)<br />
<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> FirstNormalizingCol <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, NormalizingColsCount <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> ColsToRepeat <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Range, ColsToNormalize <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Range<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> NormalizedRowsCount <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> RepeatingList() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> NormalizedList() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> ListIndex <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, j <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> wbSource <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Workbook, wbTarget <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Workbook<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> wsTarget <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Worksheet<br />
<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> List<br />
&nbsp; &nbsp; <span style="color: #008000;">'If the normalized list won't fit, you must quit.<br />
</span> &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> .Rows.Count * (.Columns.Count - RepeatingColsCount) &gt; .Parent.Rows.Count <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; MsgBox <span style="color: #800000;">&quot;The normalized list will be too many rows.&quot;</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vbExclamation + vbOKOnly, <span style="color: #800000;">&quot;Sorry&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #E56717; font-weight: bold;">Exit</span> <span style="color: #E56717; font-weight: bold;">Sub</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<br />
&nbsp; &nbsp; <span style="color: #008000;">'You have the range to be normalized and the count of leftmost rows to be repeated.<br />
</span> &nbsp; &nbsp;<span style="color: #008000;">'This section uses those arguments to set the two ranges to parse<br />
</span> &nbsp; &nbsp;<span style="color: #008000;">'and the two corresponding arrays to fill<br />
</span> &nbsp; &nbsp;FirstNormalizingCol = RepeatingColsCount + 1<br />
&nbsp; &nbsp; NormalizingColsCount = .Columns.Count - RepeatingColsCount<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> ColsToRepeat = .Cells(1).Resize(.Rows.Count, RepeatingColsCount)<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> ColsToNormalize = .Cells(1, FirstNormalizingCol).Resize(.Rows.Count, NormalizingColsCount)<br />
&nbsp; &nbsp; NormalizedRowsCount = ColsToNormalize.Columns.Count * .Rows.Count<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">ReDim</span> RepeatingList(1 <span style="color: #8D38C9; font-weight: bold;">To</span> NormalizedRowsCount, 1 <span style="color: #8D38C9; font-weight: bold;">To</span> RepeatingColsCount)<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">ReDim</span> NormalizedList(1 <span style="color: #8D38C9; font-weight: bold;">To</span> NormalizedRowsCount, 1 <span style="color: #8D38C9; font-weight: bold;">To</span> 2)<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<br />
<span style="color: #008000;">'Fill in every i elements of the repeating array with the repeating row labels.<br />
</span><span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> NormalizedRowsCount <span style="color: #8D38C9; font-weight: bold;">Step</span> NormalizingColsCount<br />
&nbsp; &nbsp; ListIndex = ListIndex + 1<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> j = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> RepeatingColsCount<br />
&nbsp; &nbsp; &nbsp; &nbsp; RepeatingList(i, j) = List.Cells(ListIndex, j).Value2<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> j<br />
<span style="color: #8D38C9; font-weight: bold;">Next</span> i<br />
<br />
<span style="color: #008000;">'We stepped over most rows above, so fill in other repeating array elements.<br />
</span><span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> NormalizedRowsCount<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> j = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> RepeatingColsCount<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> RepeatingList(i, j) = <span style="color: #800000;">&quot;&quot;</span> <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RepeatingList(i, j) = RepeatingList(i - 1, j)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> j<br />
<span style="color: #8D38C9; font-weight: bold;">Next</span> i<br />
<br />
<span style="color: #008000;">'Fill in each element of the first dimension of the normalizing array<br />
</span><span style="color: #008000;">'with the former column header (which is now another row label) and the data.<br />
</span><span style="color: #8D38C9; font-weight: bold;">With</span> ColsToNormalize<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> .Rows.Count<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> j = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> .Columns.Count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NormalizedList(((i - 1) * NormalizingColsCount) + j, 1) = .Cells(1, j)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NormalizedList(((i - 1) * NormalizingColsCount) + j, 2) = .Cells(i, j)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> j<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<br />
<span style="color: #008000;">'Put the normal data in the same workbook, or a new one.<br />
</span><span style="color: #8D38C9; font-weight: bold;">If</span> NewWorkbook <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> wbTarget = Workbooks.Add<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> wsTarget = wbTarget.Worksheets(1)<br />
<span style="color: #8D38C9; font-weight: bold;">Else</span><br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> wbSource = List.Parent.Parent<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">With</span> wbSource.Worksheets<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> wsTarget = .Add(after:=.Item(.Count))<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> wsTarget<br />
&nbsp; &nbsp; <span style="color: #008000;">'Put the data from the two arrays in the new worksheet.<br />
</span> &nbsp; &nbsp;.Range(<span style="color: #800000;">&quot;A1&quot;</span>).Resize(NormalizedRowsCount, RepeatingColsCount) = RepeatingList<br />
&nbsp; &nbsp; .Cells(1, FirstNormalizingCol).Resize(NormalizedRowsCount, 2) = NormalizedList<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #008000;">'At this point there will be repeated header rows, so delete all but one.<br />
</span> &nbsp; &nbsp;.Range(<span style="color: #800000;">&quot;1:&quot;</span> &amp; NormalizingColsCount - 1).EntireRow.Delete<br />
<br />
&nbsp; &nbsp; <span style="color: #008000;">'Add the headers for the new label column and the data column.<br />
</span> &nbsp; &nbsp;.Cells(1, FirstNormalizingCol).Value = NormalizedColHeader<br />
&nbsp; &nbsp; .Cells(1, FirstNormalizingCol + 1).Value = DataColHeader<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>You&#8217;d call it like this:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Sub</span> TestIt()<br />
NormalizeList ActiveSheet.UsedRange, 2, <span style="color: #800000;">&quot;Team&quot;</span>, <span style="color: #800000;">&quot;Home Runs&quot;</span>, <span style="color: #00C2FF; font-weight: bold;">False</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>It runs pretty fast. The sample sheet above &#8211; 109 years of data by 16 teams &#8211; completes instantly. 3,000 rows completes in a couple of seconds.</p>
<p>If I also run the routine on some American League data and put all the new rows in one sheet (with the same column headers) I can generate a pivot table that looks like this, which I couldn&#8217;t have done with the original data:</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_pivoted_data.jpg"><img class="alignnone size-full wp-image-713" src="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0016_pivoted_data.jpg" alt="" title="pivoted data" width="360" height="472" /></a></p>
<p>You can <a href="http://yoursumbuddy.com/downloads/post_0016_Data_Normalizer.zip" target="_blank">download a zip file with a .xls workbook</a> that contains the data and code.  Just click on the &#8220;normalize&#8221; button.</p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/data-normalizer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Anything</title>
		<link>http://yoursumbuddy.com/anything/</link>
		<comments>http://yoursumbuddy.com/anything/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 20:30:41 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Blogging]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=667</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/anything/">Anything</a></p><p>Anything I think about this blog a lot. I’m always pondering the next post, a challenge given the multitude of great ones that have gone before. I’ve tinkered with WordPress quite a bit, which is fun. Using it inspired me &#8230; <a href="http://yoursumbuddy.com/anything/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/anything/">Anything</a></p><h1><a title="Permalink to anything" href="http://yoursumbuddy.com/anything/"rel="bookmark">Anything</a></h1>
<p>I think about this blog a lot.  I’m always pondering the next post, a challenge given the multitude of great ones that have gone before.  I’ve tinkered with WordPress quite a bit, which is fun.  Using it inspired me to create this gravatar …</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/03/gravatar1.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/03/gravatar1-150x150.jpg" alt="" title="smiling sigma" width="150" height="150" class="alignnone size-thumbnail wp-image-700" /></a></p>
<p>… which I like to call the “smiling sigma.”</p>
<p>And I check my stats (such as they are) a lot.  One of my favorites is the list of search terms bringing people to this site.  </p>
<h2>Search Terms</h2>
<p>The two most common have to do with pivot tables and conditional formatting.  After that there are a few concerning the NPR Sunday Puzzle, and I’m proud to note that when I google “NPR Sunday Puzzle,” this site is right up there in the results.</p>
<p>Here’s some of my favorites:</p>
<p>“word puzzle first letter hero villain world capital blog” &#8211; definitely an NPR Sunday Puzzle solver</p>
<p>“toolbar lengkap excel 2003” &#8211; I understand that “lengkap” is Indonesian for “complete”</p>
<p>“goofy code” – I rank very high in the results on this, hopefully only because there’s a post here with that name</p>
<h2>My Second Most Favorite Search Term</h2>
<p><strong>“sum buddy i use to no”</strong> &#8211; Now there’s a person after my own heart!  What were they looking for?  And how do you &#8220;use somebody to no&#8221; anyways?  It sounds handy.</p>
<p>Sadly, I’ll never no.</p>
<h2>My Most Favorite Search Term</h2>
<p><strong>“Anything”</strong> </p>
<p>Yup, according to AwStats, somebody googled “anything” and ended up here.  I’m not completely convinced this happened, but it’s there on my screen, so I’m going with it.</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0015_anything.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0015_anything.jpg" alt="" title="search keyphrases" width="393" height="810" class="alignnone size-full wp-image-673" /></a></p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/anything/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Flexible VBA Chooser Form</title>
		<link>http://yoursumbuddy.com/a-flexible-vba-chooser-form/</link>
		<comments>http://yoursumbuddy.com/a-flexible-vba-chooser-form/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 05:29:15 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Pivot Tables]]></category>
		<category><![CDATA[UserForm]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=633</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/a-flexible-vba-chooser-form/">A Flexible VBA Chooser Form</a></p><p>A Flexible VBA Chooser Form Fairly often in VBA code I need to offer the user a list and have them make a choice, like picking which open workbook to do something to. I created a function and a userform &#8230; <a href="http://yoursumbuddy.com/a-flexible-vba-chooser-form/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/a-flexible-vba-chooser-form/">A Flexible VBA Chooser Form</a></p><h1><a title="Permalink to A Flexible VBA Chooser Form" href="http://yoursumbuddy.com/a-flexible-vba-chooser-form/"rel="bookmark">A Flexible VBA Chooser Form</a></h1>
<p>Fairly often in VBA code I need to offer the user a list and have them make a choice, like picking which open workbook to do something to.  I created a function and a userform to handle these situations.  (Around the house, I call the form &#8220;ChooserForm&#8221; but it&#8217;s given name is &#8220;frmChooser.&#8221;)  The function takes an array of choices and a caption as its arguments.  The function loads frmChooser and passes it the string array and the caption.  When the user makes a choice and clicks OK the function returns the choice to the calling routine.</p>
<p>Let&#8217;s look at how it works, starting from the inside out (by which I mean with the userform):</p>
<h2>The frmChooser UserForm</h2>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Private</span> mboolClosedWithOk <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span><br />
<span style="color: #E56717; font-weight: bold;">Private</span> mChoiceList() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<br />
<span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #151B8D; font-weight: bold;">Property</span> <span style="color: #151B8D; font-weight: bold;">Let</span> ChoiceList(PassedList() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>)<br />
mChoiceList() = PassedList()<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #151B8D; font-weight: bold;">Property</span><br />
<br />
<span style="color: #E56717; font-weight: bold;">Private</span> <span style="color: #E56717; font-weight: bold;">Sub</span> UserForm_Activate()<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> Me.cboChooser<br />
&nbsp; &nbsp; .List = mChoiceList()<br />
&nbsp; &nbsp; .ListIndex = 0<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span><br />
<br />
<span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #151B8D; font-weight: bold;">Property</span> <span style="color: #151B8D; font-weight: bold;">Get</span> ChoiceValue() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
ChoiceValue = Me.cboChooser.Value<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #151B8D; font-weight: bold;">Property</span><br />
<br />
<span style="color: #E56717; font-weight: bold;">Private</span> <span style="color: #E56717; font-weight: bold;">Sub</span> cmdOk_Click()<br />
mboolClosedWithOk = <span style="color: #00C2FF; font-weight: bold;">True</span><br />
Me.Hide<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span><br />
<br />
<span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #151B8D; font-weight: bold;">Property</span> <span style="color: #151B8D; font-weight: bold;">Get</span> ClosedWithOk() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span><br />
ClosedWithOk = mboolClosedWithOk<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #151B8D; font-weight: bold;">Property</span><br />
<br />
<span style="color: #E56717; font-weight: bold;">Private</span> <span style="color: #E56717; font-weight: bold;">Sub</span> cmdCancel_Click()<br />
mboolClosedWithOk = <span style="color: #00C2FF; font-weight: bold;">False</span><br />
Me.Hide<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span><br />
<br />
<span style="color: #E56717; font-weight: bold;">Private</span> <span style="color: #E56717; font-weight: bold;">Sub</span> UserForm_QueryClose(Cancel <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Integer</span>, CloseMode <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Integer</span>)<br />
<span style="color: #008000;">'in case the user clicked the &quot;X&quot;<br />
</span><span style="color: #8D38C9; font-weight: bold;">If</span> CloseMode = vbFormControlMenu <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; Cancel = <span style="color: #00C2FF; font-weight: bold;">True</span><br />
&nbsp; &nbsp; cmdCancel_Click<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>The form has three custom properties.  The first, Let ChoiceList, assigns the array of choices to the form&#8217;s module-level variable, mChoiceList().  On form activation the combobox cboChooser&#8217;s list is filled with the mChoiceList array.</p>
<p>The second property, Get ChoiceValue, is the currently selected value of the combobox.  The function will &#8220;get&#8221; this, after the OK button is clicked, to determine the user&#8217;s choice.  </p>
<p>The third property, Get ClosedWithOk tells the calling function whether the user hit the OK button.  If it&#8217;s True then the function will do its processing.  If it&#8217;s false, then the user hit the Cancel button or the &#8220;X,&#8221; and we&#8217;ll skip the processing.</p>
<h2>The Function code</h2>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Function</span> GetChoiceFromChooserForm(strChoices() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, strCaption <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> ufChooser <span style="color: #151B8D; font-weight: bold;">As</span> frmChooser<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> strChoicesToPass() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<br />
<span style="color: #008000;">'why is this necessary?<br />
</span><span style="color: #151B8D; font-weight: bold;">ReDim</span> strChoicesToPass(<span style="color: #151B8D; font-weight: bold;">LBound</span>(strChoices) <span style="color: #8D38C9; font-weight: bold;">To</span> <span style="color: #151B8D; font-weight: bold;">UBound</span>(strChoices))<br />
strChoicesToPass() = strChoices()<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> ufChooser = <span style="color: #E56717; font-weight: bold;">New</span> frmChooser<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> ufChooser<br />
&nbsp; &nbsp; .Caption = strCaption<br />
&nbsp; &nbsp; .ChoiceList = strChoicesToPass<br />
&nbsp; &nbsp; .Show<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> .ClosedWithOk <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; GetChoiceFromChooserForm = .ChoiceValue<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; Unload ufChooser<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>The function creates an instance of frmChooser, called &#8220;ufChooser,&#8221; passes the Caption and ChoiceList properties and shows the form.  After the .Show command, processing passes into the form and the code shown in the previous section.  Processing returns to the function when the form is hidden, by either the OK or Cancel button&#8217;s click event.  The function then checks the form&#8217;s ClosedWithOK property.  If it&#8217;s true the function returns the form&#8217;s ChoiceValue property &#8211; the value selected in the combobox &#8211; to the calling routine.</p>
<p>You may have noticed the question &#8220;why is this necessary?&#8221;  I can&#8217;t just pass strChoices() straight into the frmChooser instance.  It causes a runtime &#8220;internal error.&#8221;  Instead I have to declare a second string array strChoicesToPass() and copy the first array to it.  If anybody can explain why, please share!  (I think I could pass a variant straight through, but I don&#8217;t.)</p>
<p>The general form of this function&#8217;s code, and that of the userform, is from the venerable <a href="http://www.amazon.com/Professional-Excel-Development-Definitive-Applications/dp/0321508793/ref=dp_ob_image_bk/177-5010113-4897845" title="Professional Excel Development" target="_blank">Professional Excel Development.</a></p>
<h2>Using the Function</h2>
<p>Now that we&#8217;ve got the function and the form, let&#8217;s choose something!  I&#8217;ve got some code below that lists all the visible fields in a pivot table.  When one is picked, the data range for the field is highlighted, along with the source column in the table, and the fields source name is displayed:</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Sub</span> ShowPivotFieldInfo()<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> pvt <span style="color: #151B8D; font-weight: bold;">As</span> Excel.PivotTable<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> lo <span style="color: #151B8D; font-weight: bold;">As</span> Excel.ListObject<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> StartingCell <span style="color: #151B8D; font-weight: bold;">As</span> Excel.Range<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> PivotFieldNames() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> pvtField <span style="color: #151B8D; font-weight: bold;">As</span> Excel.PivotField<br />
<span style="color: #151B8D; font-weight: bold;">Dim</span> ChosenName <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> pvt = ActiveSheet.PivotTables(<span style="color: #800000;">&quot;pvtRecordTemps&quot;</span>)<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> lo = ActiveSheet.ListObjects(<span style="color: #800000;">&quot;tblRecordTemps&quot;</span>)<br />
<span style="color: #151B8D; font-weight: bold;">Set</span> StartingCell = ActiveCell<br />
<span style="color: #8D38C9; font-weight: bold;">With</span> pvt<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">ReDim</span> PivotFieldNames(1 <span style="color: #8D38C9; font-weight: bold;">To</span> .VisibleFields.Count) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> .VisibleFields.Count<br />
&nbsp; &nbsp; &nbsp; &nbsp; PivotFieldNames(i) = .VisibleFields(i).Name<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i<br />
&nbsp; &nbsp; ChosenName = GetChoiceFromChooserForm(PivotFieldNames, <span style="color: #800000;">&quot;Choose a Pivot Field&quot;</span>)<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> ChosenName = vbNullString <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #E56717; font-weight: bold;">Exit</span> <span style="color: #E56717; font-weight: bold;">Sub</span><br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> pvtField = .PivotFields(ChosenName)<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">With</span> pvtField<br />
&nbsp; &nbsp; &nbsp; &nbsp; Union(.DataRange, lo.ListColumns(.SourceName).DataBodyRange).<span style="color: #8D38C9; font-weight: bold;">Select</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; MsgBox Title:=.SourceName, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Prompt:=<span style="color: #800000;">&quot;The SourceName for &quot;</span> &amp; ChosenName &amp; <span style="color: #800000;">&quot; is:&quot;</span> &amp; vbCrLf &amp; vbCrLf &amp; .SourceName<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
&nbsp; &nbsp; StartingCell.<span style="color: #8D38C9; font-weight: bold;">Select</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Sub</span></div></div>
<p>This type of code can be useful when the PivotField names have been changed drastically from their underlying SourceNames, especially if the SourceNames are cryptic, similar, and there&#8217;s lots of them.  In the picture below the SourceNames in the table were &#8220;Field 1&#8243;, &#8220;Field 2&#8243;, etc., but were changed to meaningful names like &#8220;Continent&#8221; in the pivot table.</p>
<p><a href="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0014_flexible_ChooserForm1.jpg"><img src="http://yoursumbuddy.com/wp-content/uploads/2012/03/post_0014_flexible_ChooserForm1.jpg" alt="" title="flexible ChooserForm - Pivot Field picker with Source Names" width="1168" height="578" class="alignnone size-full wp-image-643" /></a></p>
<p>Here&#8217;s the <a href="http://yoursumbuddy.com/downloads/post_0014_flexible_ChooserForm_1.zip" title="Flexible ChooserForm 1 sample file">sample workbook</a> for your downloading pleasure.</p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/a-flexible-vba-chooser-form/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Best Min Function, I Think</title>
		<link>http://yoursumbuddy.com/the-best-min-function-i-think/</link>
		<comments>http://yoursumbuddy.com/the-best-min-function-i-think/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 07:35:39 +0000</pubDate>
		<dc:creator>Doug Glancy</dc:creator>
				<category><![CDATA[Formulas]]></category>

		<guid isPermaLink="false">http://yoursumbuddy.com/?p=586</guid>
		<description><![CDATA[<p><p><a href="http://yoursumbuddy.com/the-best-min-function-i-think/">The Best Min Function, I Think</a></p><p>The Best Min Function, I Think A few weeks ago I wrote a Min array function to determine the minimum of a subset of items in a table. It was not the best Min function, in fact it didn&#8217;t work. &#8230; <a href="http://yoursumbuddy.com/the-best-min-function-i-think/">Continue reading <span class="meta-nav">&#8594;</span></a></p></p><p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://yoursumbuddy.com/the-best-min-function-i-think/">The Best Min Function, I Think</a></p><h1><a title="Permalink to The Best Min Function, I Think" href="http://yoursumbuddy.com/the-best-min-function-i-think/"rel="bookmark">The Best Min Function, I Think</a></h1>
<p>A few weeks ago I wrote a Min array function to determine the minimum of a subset of items in a table.  It was not the best Min function, in fact it didn&#8217;t work.  I&#8217;d based it on the Max function I&#8217;d written moments earlier &#8211; a rookie mistake &#8211; and it resulted in zero when it shouldn&#8217;t have.  I fixed it, but the fix was ugly.  Then I realized I could use an If statement in an array formula, which helped a lot.  Then I read this <a href="http://www.dailydoseofexcel.com/archives/2010/03/23/maxif-and-minif-with-multiple-variables/" title="DDOE Maxif and Minif With Multiple Variables" target="_blank">informative and lively post</a>.</p>
<p>I&#8217;ll summarize what I learned, and propose my own Best Min Function, using the interactive workbook below.</p>
<p><iframe width="800" height="600" frameborder="0" scrolling="no" src="https://r.office.microsoft.com/r/rlidExcelEmbed?su=-2945953654735389335&#038;Fi=SDD71DDEC264BBBD69!270&#038;ak=t%3d0%26s%3d0%26v%3d!APW8Ewh_BCJftUg&#038;kip=1&#038;AllowTyping=True&#038;ActiveCell='January%20highs%20and%20lows'!I2&#038;wdHideGridlines=True&#038;wdDownloadButton=True"></iframe></p>
<h2>The Workbook</h2>
<p>The table on the left contains record high and low Fahrenheit temperatures from various cities around the world, listed by continent.  (Column B contains the countries.  You can unhide it.)  </p>
<p>The formulas are in the table in the top right.  They all look for the lowest of the record lows by continent.</p>
<p>Below the formulas are a couple of cells which trigger a couple of pitfalls of the Min function.  Below that are text versions of the formulas.</p>
<h2>The Formulas</h2>
<p>The first formula, &#8220;multiplication,&#8221; is my original failure.  The conditions (record type and continent) and the record lows are all multiplied:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">{=MIN((tblRecLows[Record Type]=&quot;Low&quot;)*(tblRecLows[Continent]=H$1)*<br />
(tblRecLows[Record]))}</div></div>
<p>As described in the post linked above, this only works for Min if at least one value is equal to or less than zero.  Multiplying arrays of conditions like this will always yield some zeros &#8211; whenever all the conditions aren&#8217;t met &#8211; and so the minimum can never be higher than zero.</p>
<p>This list low temps is illustrates the problem well.  For some continents the record low is negative, but for others it&#8217;s positive.  You can see that this formula fails for continents where the record low is positive.  For example Africa should show 30 degrees, but it shows zero.</p>
<p>My fix was to force all the numbers in the table to be negative, by subtracting the maximum record temperature from each number, find the minimum, and then add the maximum back.  This eliminates the zero problem&#8230;</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">{=MIN((tblRecLows[Record Type]{=&quot;Low&quot;)*(tblRecLows[Continent]{=H$1)*<br />
(tblRecLows[Record]-(MAX(tblRecLows[Record])+1)))+(MAX(tblRecLows[Record])+1)}</div></div>
<p>&#8230; but it&#8217;s ugly.  And anyways, both multiplication versions fail if there is any stray text in your list.  I noticed this because Florence had &#8220;NA&#8217;s&#8221; for both high and low records.  The multiplication chokes on the text value, just as it would on 2 * &#8220;NA&#8221;, and the formula fails.  You can see this by changing the &#8220;Has Text&#8221; in the &#8220;Potential Pitfalls&#8221; section to True.  Both formulas yield #VALUE.</p>
<p>So, as faithful readers of DDOE already knew &#8211; at least if their memories are better than mine &#8211; If statements are the way to go.  The &#8220;nested If&#8221; and the &#8220;Elias one-if&#8221; versions above work because they return an array filled either with temperatures that meet all the criteria, or Falses.  The Min function ignores the Falses, and so returns the correct minimum.</p>
<p>Now for the second pitfall:  Empty cells in your list are a problem because an <a href="http://stackoverflow.com/questions/1119614/return-empty-cell-from-formula-in-excel" title="Stack Overflow - If statement to return empty cell" target="_blank"> IF statement cannot return a null</a>.  It converts blank cells to zeroes which, you guessed it, become the result of the Min function if there&#8217;s no lower number.</p>
<p>You can see this by changing the &#8220;Has Blanks&#8221; in the &#8220;Potential Pitfalls&#8221; section to True and following the instructions.  You&#8217;ll see that the &#8220;nested if&#8221; and &#8220;Elias one-if&#8221; both fail for Africa, and will for any warm continent with a blank cell.</p>
<p>The proposed &#8220;Best Min&#8221; solves this problem by adding a criteria of non-blank cells.  (It also eliminates the &#8220;>0&#8243; check of the multiplied conditions from Elias&#8217;s version as it seems to evaluate to the same thing.)</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">{MIN(IF(((tblRecLows[Record Type]{=&quot;Low&quot;)*(tblRecLows[Continent]{=H$1)*<br />
(tblRecLows[Record]&lt;&gt;&quot;&quot;)),tblRecLows[Record]))}</div></div>
<p>There is a runner-up at the end of the list: a GetPivotData formula looking into a pivot table, or perhaps just a pivot table itself (you&#8217;ll see it if you scroll down).  It might be my first choice if if didn&#8217;t require refreshing.</p>
<h2>One last thought</h2>
<p> I just realized that the Max function is subject to the exact same false-zero-minimum problems if all values are equal to or below zero, the inverse of the Min issue.</p>
<p><a href="http://yoursumbuddy.com">yoursumbuddy - Doug Glancy&#039;s Excel Site</a></p>]]></content:encoded>
			<wfw:commentRss>http://yoursumbuddy.com/the-best-min-function-i-think/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

