<?xml version="1.0" encoding="utf-8"?>
<!-- generator="wordpress/2.1.3" -->
<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/"
	>

<channel>
	<title>Daily Dose of Excel</title>
	<link>http://www.dailydoseofexcel.com</link>
	<description>Daily posts of Excel tips...and other stuff</description>
	<pubDate>Fri, 09 May 2008 04:03:35 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.1.3</generator>
	<language>en</language>
			<item>
		<title>Using a Class Property to do more than just Assign or Query a Value</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/05/08/using-a-class-property-to-do-more-than-just-assign-or-query-a-value/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/05/08/using-a-class-property-to-do-more-than-just-assign-or-query-a-value/#comments</comments>
		<pubDate>Fri, 09 May 2008 04:03:35 +0000</pubDate>
		<dc:creator>Tushar Mehta</dc:creator>
		
		<category><![CDATA[VBA Basics]]></category>

		<category><![CDATA[VBA]]></category>

		<category><![CDATA[Classes]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/05/08/using-a-class-property-to-do-more-than-just-assign-or-query-a-value/</guid>
		<description><![CDATA[The purpose of this article is to introduce various capabilities of a class property.  It is not meant to serve as an introduction to classes and objects.  See the references section for introductory pages.
The typical use of a Class Property is to assign a value or to query its value as in the [...]]]></description>
			<content:encoded><![CDATA[<p>The purpose of this article is to introduce various capabilities of a class property.  It is not meant to serve as an introduction to classes and objects.  See the references section for introductory pages.</p>
<p>The typical use of a Class Property is to assign a value or to query its value as in the example below that defines the radius of a circle.  This code would go in a class module named clsCircle.</p>
<div class="syntax_hilite">
<div id="vb-19">
<div class="vb"><span style="color: #0000DD;">Option</span> <span style="color: #0000DD;">Explicit</span><br />
<span style="color: #0000DD;">Dim</span> LclRadius <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Radius<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; Radius = LclRadius<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Let</span> Radius<span style="color:#008800;">&#40;</span>uRadius <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; LclRadius = uRadius<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p>
Here are three things to consider.  First, there are two different procedures, one to query the value and another to assign it.  Second, there’s no requirement that there be only one statement in the Get or the Let procedure.  In fact, there could be just about any number of statements in either procedure.  Third, there’s no rule that both the Get and the Let procedures be present.  These three together mean there's a lot more one can do beyond the basic use of a property.  In this document we will explore some of the possibilities.  There is one critical weakness in how properties work and we will explore a workaround towards the end of this document.</p>
<h2>Validating a property value</h2>
<p>The first improvement is to validate the value of a property.  In the case of a circle, the radius cannot be negative.  So, we can enhance the code to ensure that it is not.</p>
<div class="syntax_hilite">
<div id="vb-20">
<div class="vb"><span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Let</span> Radius<span style="color:#008800;">&#40;</span>uRadius <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> uRadius&gt;= <span style="color: #cc66cc;">0</span> <span style="color: #0000DD;">Then</span> LclRadius = uRadius _<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Else</span> <span style="color: #0000DD;">MsgBox</span> <span style="color: #ff0000;">"Radius cannot be assigned a negative value"</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p></p>
<h2>Creating a Write-Once-Read-Many attribute</h2>
<p>We can modify the above code to allow the Radius property to be assigned a value only once.</p>
<div class="syntax_hilite">
<div id="vb-21">
<div class="vb"><span style="color: #0000DD;">Dim</span> LclRadius <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span>, RadiusAssigned <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Boolean</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Radius<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; Radius = LclRadius<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Let</span> Radius<span style="color:#008800;">&#40;</span>uRadius <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> RadiusAssigned <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">MsgBox</span> <span style="color: #ff0000;">"Radius, a 'write-once' attribute, already has a value"</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Exit</span> <span style="color: #0000DD;">Property</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> uRadius&gt;= <span style="color: #cc66cc;">0</span> <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; LclRadius = uRadius<br />
&nbsp; &nbsp; &nbsp; &nbsp; RadiusAssigned = True<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">MsgBox</span> <span style="color: #ff0000;">"Radius cannot be assigned a negative value"</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p></p>
<h2>Verify that a Property has been initialized</h2>
<p>We can use the same concept as above to verify that a property has been initialized.  Thus, the property value is returned only after it has been initialized.</p>
<div class="syntax_hilite">
<div id="vb-22">
<div class="vb"><span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Radius<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> RadiusAssigned <span style="color: #0000DD;">Then</span> Radius = LclRadius _<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Else</span> <span style="color: #0000DD;">MsgBox</span> <span style="color: #ff0000;">"Radius property is uninitialized"</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p></p>
<h2>A “Virtual” Property</h2>
<p>A property doesn’t have to have a variable associated with it.  The Radius property has a private LclRadius variable that holds its value.  But that is not strictly necessary.  Consider a circle's Diameter property.  Since it is simply twice the radius there is no need for a separate variable to contain the diameter.</p>
<div class="syntax_hilite">
<div id="vb-23">
<div class="vb"><span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Diameter<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; Diameter = Radius * <span style="color: #cc66cc;">2</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Let</span> Diameter<span style="color:#008800;">&#40;</span>uDiameter <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; Radius = uDiameter / <span style="color: #cc66cc;">2</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p></p>
<h2>Using Properties inside the Class Module</h2>
<p>The above example also illustrates another useful point.  Even though the variable LclRadius is available to all the procedures of the class one can always use the actual property itself.  In fact, unless there is a compelling reason not to, one should always use the property since this has the benefit that any additional code for the property (such as the validation of the radius) will be correctly executed.</p>
<h2>A Public vs. a Private Property</h2>
<p>There may a valid reason for creating a property such that it is available to other members of the class but not to a client.  This is accomplished by declaring the corresponding Get or Let procedure private.  Consider the Diameter property from above.  Clearly, it makes good sense for the client to know the diameter of the circle.  So, the Get procedure should be public (the default).  Also suppose we decide that the client cannot change the diameter (all changes should be through the Radius property).  At the same time, we decide that procedures inside the class itself should be allowed to change the Diameter property.  We accomplish this by making the Let procedure private as in:</p>
<div class="syntax_hilite">
<div id="vb-24">
<div class="vb"><span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Diameter<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; Diameter = Radius * <span style="color: #cc66cc;">2</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
<span style="color: #0000DD;">Private</span> <span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Let</span> Diameter<span style="color:#008800;">&#40;</span>uDiameter <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; Radius = uDiameter / <span style="color: #cc66cc;">2</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p>
Now, code within the class can set the Diameter value with something like:</p>
<div class="syntax_hilite">
<div id="vb-25">
<div class="vb">Diameter = <span style="color: #cc66cc;">2</span></div>
</div>
</div>
<p>
However, a client would be unable to do something like the below since it would result in a compile time error “Method or Data Member not found”</p>
<div class="syntax_hilite">
<div id="vb-26">
<div class="vb">aCircle.Diameter = <span style="color: #cc66cc;">2</span></div>
</div>
</div>
<p></p>
<h2>Referring to an instance of the class (the Me object)</h2>
<p>The Me keyword is the way code inside the class module can refer to the instance of the object created from the class.  One could call it a “self reference,” I suppose.  Me is the equivalent of a client referring to a variable of the class.  VBE’s Intellisense capability will show the same properties and methods that a client would be able to use.</p>
<p>The use of Me is relevant in the context of a private property since a procedure in the class module can refer to a private property such as Diameter above.  However, assigning a value to the Diameter of the Me object would fail since Diameter is publicly read-only.</p>
<h2>Read-only Property</h2>
<p>Since the Get and Let property procedures are separate entities, one can always exclude one (or the other).  To implement a read-only property, simply exclude the Let procedure.  In the case of the circle class, once the client specifies the radius, other properties such as the area or the perimeter are easy to calculate.  However, if we assume that the client cannot specify the area (or perimeter) directly, we can create read-only properties with</p>
<div class="syntax_hilite">
<div id="vb-27">
<div class="vb"><span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Area<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; Area = Application.WorksheetFunction.Pi<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> * Radius ^ <span style="color: #cc66cc;">2</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Perimeter<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; Perimeter = <span style="color: #cc66cc;">2</span> * Application.WorksheetFunction.Pi<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> * Radius<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p>
Similarly, one can implement a write-only property by creating the Let procedure but excluding the corresponding Get procedure.</p>
<h2>Property with an argument</h2>
<p>Just like a subroutine or a function can have one or more arguments passed to it, so can a property.  Suppose we want to provide a property that returns the length of the arc corresponding to a specified angle.  The length of the arc is calculated as the perimeter / (2*Pi) * angle of the arc, which is also the same as radius * angle of the arc.  So, we would get the property</p>
<div class="syntax_hilite">
<div id="vb-28">
<div class="vb"><span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> ArcLen<span style="color:#008800;">&#40;</span>ArcAngleInRadians <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; ArcLen = Perimeter * ArcAngleInRadians _<br />
&nbsp; &nbsp; &nbsp; &nbsp; / <span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">2</span> * Application.WorksheetFunction.Pi<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #007F00;">'The above illustrates how one property can use another property _</span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #0000DD;">to</span> <span style="color: #0000DD;">return</span> a calculated value.&nbsp; Of course, the length of an arc _<br />
&nbsp; &nbsp; &nbsp;<span style="color: #0000DD;">is</span> also the simpler _<br />
&nbsp; &nbsp; ArcLen = Radius * ArcAngleInRadians<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p>
Similarly, a Let procedure can also have an argument list.  In the case of a property where the Get procedure has zero arguments, the corresponding Let procedure already has 1 argument, the value of the Let assignment.  Similarly, when the Get procedure has an argument list, the corresponding Let procedure has 1 more argument than the Get procedure.  The value of the Let statement is the last argument.  So, if we were to allow the client to specify the radius of a circle through the ArcLen property – keeping in mind that while it helps demonstrate this capability it is not really a good idea for a ‘production’ system – we might have something like:</p>
<div class="syntax_hilite">
<div id="vb-29">
<div class="vb"><span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Let</span> ArcLen<span style="color:#008800;">&#40;</span>ArcAngleInRadians <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span>, uArcLen <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; Radius = uArcLen / ArcAngleInRadians<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p></p>
<h2>Raising an Error</h2>
<p>Just as we can raise an error in any procedure in our code modules, one can also raise an error in a class module.  Suppose we decide to replace our Radius property’s Get procedure so that it raises an error if Radius is uninitialized.</p>
<div class="syntax_hilite">
<div id="vb-30">
<div class="vb"><span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Radius<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> RadiusAssigned <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Radius = LclRadius<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Err</span>.Raise <span style="color: #0000DD;">vbObjectError</span> + <span style="color: #cc66cc;">513</span>, <span style="color: #ff0000;">"clsCircle.Radius"</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">"clsCircle.Radius: Radius property is uninitialized"</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p>
Now, if we were to query the value of the Radius property before assigning a value to it, we would get a runtime error.</p>
<h2>Sample Use of the circle’s properties</h2>
<p>In a standard module, enter the code below and then execute it.  It creates a circle of radius 1 and then displays its diameter, area, perimeter, and the length of the arc corresponding to 1/4th the circle.  </p>
<div class="syntax_hilite">
<div id="vb-31">
<div class="vb"><span style="color: #0000DD;">Option</span> <span style="color: #0000DD;">Explicit</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Sub</span> testCircle<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> aCircle <span style="color: #0000DD;">As</span> clsCircle<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> aCircle = <span style="color: #0000DD;">New</span> clsCircle<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">With</span> aCircle<br />
&nbsp; &nbsp; .Radius = <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">MsgBox</span> <span style="color: #ff0000;">"Diameter="</span> &amp; .Diameter &amp; <span style="color: #ff0000;">", Area="</span> &amp; .Area _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &amp; <span style="color: #ff0000;">", Perimeter="</span> &amp; .Perimeter _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &amp; <span style="color: #ff0000;">", ArcLen(Pi()/2)="</span> _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp; aCircle.ArcLen<span style="color:#008800;">&#40;</span>Application.WorksheetFunction.Pi<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> / <span style="color: #cc66cc;">2</span><span style="color:#008800;">&#41;</span>&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">With</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<h2>Difference between Set and Let property procedures</h2>
<p>Suppose we have another class, clsPoint, that contains 2 properties, the X and Y coordinates of the point.</p>
<div class="syntax_hilite">
<div id="vb-32">
<div class="vb"><span style="color: #0000DD;">Option</span> <span style="color: #0000DD;">Explicit</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Dim</span> LclX <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span>, LclY <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> X<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span>: X = LclX: <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Let</span> X<span style="color:#008800;">&#40;</span>uX <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span>: LclX = uX: <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Y<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span>: Y = LclY: <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Let</span> Y<span style="color:#008800;">&#40;</span>uY <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Double</span><span style="color:#008800;">&#41;</span>: LclY = uY: <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p>
Now, in our clsCircle class, we could specify the center of our circle as:</p>
<div class="syntax_hilite">
<div id="vb-33">
<div class="vb"><span style="color: #0000DD;">Dim</span> LclCenter <span style="color: #0000DD;">As</span> clsPoint<br />
&nbsp;<br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Center<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> clsPoint<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> Center = LclCenter<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Set</span> Center<span style="color:#008800;">&#40;</span>uCenter <span style="color: #0000DD;">As</span> clsPoint<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> LclCenter = uCenter<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p>
Note that the Get procedure can Set the property.  However, if we used a Let procedure and tried to Set the module variable, it would not work.  Try it.  Instead, one must use a Set procedure as in the above example.</p>
<p>We can now extend the testCircle subroutine (it’s in the standard module).</p>
<div class="syntax_hilite">
<div id="vb-34">
<div class="vb"><span style="color: #0000DD;">Option</span> <span style="color: #0000DD;">Explicit</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Sub</span> testCircle<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> aCircle <span style="color: #0000DD;">As</span> clsCircle<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> aCircle = <span style="color: #0000DD;">New</span> clsCircle<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">With</span> aCircle<br />
&nbsp; &nbsp; .Radius = <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">MsgBox</span> <span style="color: #ff0000;">"Diameter="</span> &amp; .Diameter &amp; <span style="color: #ff0000;">", Area="</span> &amp; .Area _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &amp; <span style="color: #ff0000;">", Perimeter="</span> &amp; .Perimeter _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &amp; <span style="color: #ff0000;">", ArcLen(Pi()/2)="</span> _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp; aCircle.ArcLen<span style="color:#008800;">&#40;</span>Application.WorksheetFunction.Pi<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> / <span style="color: #cc66cc;">2</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">With</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> myCenter <span style="color: #0000DD;">As</span> clsPoint<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> myCenter = <span style="color: #0000DD;">New</span> clsPoint<br />
&nbsp; &nbsp; <span style="color: #0000DD;">With</span> myCenter<br />
&nbsp; &nbsp; .X = <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; .Y = <span style="color: #cc66cc;">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">With</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">With</span> aCircle<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> .Center = myCenter<br />
&nbsp; &nbsp; <span style="color: #0000DD;">MsgBox</span> .Center.X &amp; <span style="color: #ff0000;">", "</span> &amp; .Center.Y<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">With</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<h2>Creating private “property variables”</h2>
<p>One of the biggest weaknesses in the current implementation of a class is that any variable associated with a property must be declared at the module level.  This makes the variable visible to and, worse modifiable by, any code anywhere in the module.  Essentially, the variable is global to the entire module.</p>
<p>One generic way to make a variable persistent but not global is to declare it as static inside a procedure.  That, of course, does not work with a Property since typically there are two procedures associated with a property (a Get and a Let or a Get and a Set).  But, what if our property procedures called a common private procedure?  Then, we could declare our local variables in this common procedure.</p>
<p>Create a function that declares the variable(s) associated with a property as static within its own scope.  Now, the only way to access the variable is through the function – and the function can contain all the code required to assign or query a property value.</p>
<div class="syntax_hilite">
<div id="vb-35">
<div class="vb"><span style="color: #0000DD;">Private</span> <span style="color: #0000DD;">Function</span> myCenter<span style="color:#008800;">&#40;</span>GetVal <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Boolean</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Optional</span> uCenter <span style="color: #0000DD;">As</span> clsPoint<span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> clsPoint<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Static</span> LclCenter <span style="color: #0000DD;">As</span> clsPoint<br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> GetVal <span style="color: #0000DD;">Then</span> <span style="color: #0000DD;">Set</span> myCenter = LclCenter _<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Else</span> <span style="color: #0000DD;">Set</span> LclCenter = uCenter<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Function</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> Center<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> clsPoint<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> Center = myCenter<span style="color:#008800;">&#40;</span>True<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
<span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Set</span> Center<span style="color:#008800;">&#40;</span>uCenter <span style="color: #0000DD;">As</span> clsPoint<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; myCenter False, uCenter<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span></div>
</div>
</div>
<p>
The variable LclCenter above is private to myCenter.  No procedure in the module can directly access LclCenter.  All access has to be through myCenter; we have cut off unrestricted access to the variable.</p>
<p>One can verify the above works by simply running the testCircle code (without making any changes to it).  You will get the same result.</p>
<p>I had hoped that with the .Net declaration of a property one would be able to declare variables local to it but unfortunately it remains impossible.  The result of the below is a syntax error on the dim X... statement indicating the declaration is not allowed in the Property.</p>
<div class="syntax_hilite">
<div id="vb-36">
<div class="vb"><span style="color: #0000DD;">Private</span> Class Class1<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Public</span> <span style="color: #0000DD;">Property</span> aProp<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">dim</span> X <span style="color: #0000DD;">as</span> <span style="color: #0000DD;">boolean</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Get</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Get</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Set</span><span style="color:#008800;">&#40;</span><span style="color: #0000DD;">ByVal</span> value<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Set</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> Class</div>
</div>
</div>
<p></p>
<h2>Summary</h2>
<p>There’s a lot one can do with a class property beyond just associating it with a variable.  The list includes, but is not limited to, introducing data validation as well as implement write-once or read-only (or write-only) properties.  One can also restrict the scope of variables associated with a property.</p>
<p>This document shared some ideas on the subject.  For those wondering, yes, I can think of some possibilities that were not discussed here.  Of course, I am sure there are even more possibilities that I haven’t thought of.</p>
<h2>References</h2>
<p>There is much information on the subject of classes and objects.  Just search Google.  Two introductory topics I found -- and I don't know how the compare with other information on the subject -- are Dick Kusleika's blog post at<a href="http://www.dailydoseofexcel.com/archives/2004/09/28/classes-creating-custom-objects/"> http://www.dailydoseofexcel.com/archives/2004/09/28/classes-creating-custom-objects/</a> and Chip Pearson's introduction to the subject at<a href="http://www.cpearson.com/excel/Classes.aspx"> http://www.cpearson.com/excel/Classes.aspx</a>  Chip addresses a couple of the issues addressed above as well as topics I opted to exclude from this article.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/05/08/using-a-class-property-to-do-more-than-just-assign-or-query-a-value/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Double Clicking Through a List</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/05/06/double-clicking-through-a-list/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/05/06/double-clicking-through-a-list/#comments</comments>
		<pubDate>Wed, 07 May 2008 04:00:27 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[CodeCritic]]></category>

		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/05/06/double-clicking-through-a-list/</guid>
		<description><![CDATA[I have a cell with data validation.  It's set as an in-cell dropdown list and contains two items: Yes and No.  I want to make it so that I can double click on that cell to toggle between yes and no.  But wait, that's not good enough.  What about longer lists? [...]]]></description>
			<content:encoded><![CDATA[<p>I have a cell with data validation.  It's set as an in-cell dropdown list and contains two items: Yes and No.  I want to make it so that I can double click on that cell to toggle between yes and no.  But wait, that's not good enough.  What about longer lists?  Yes, I want something that will iterate through all the items on a data validation list by double clicking.  Dare I dream.</p>
<p>Here's my first go at it.  I figure it's going to need some work, like what happens when the user double clicks on something that's not a range, but it's a start.  I've basically handled two types of lists: the kind where you hard code values separated by commas (international issue here?), and the the range reference.  Oh, and I need to test named ranges, but I think they'll work.</p>
<div class="syntax_hilite">
<div id="vb-38">
<div class="vb"><span style="color: #0000DD;">Private</span> <span style="color: #0000DD;">Sub</span> Worksheet_BeforeDoubleClick<span style="color:#008800;">&#40;</span><span style="color: #0000DD;">ByVal</span> Target <span style="color: #0000DD;">As</span> Range, Cancel <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Boolean</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> dv <span style="color: #0000DD;">As</span> Validation<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> sDv1 <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> vaList <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Variant</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> i <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> vOldValue <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Variant</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">On</span> <span style="color: #0000DD;">Error</span> <span style="color: #0000DD;">Resume</span> <span style="color: #0000DD;">Next</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Set</span> dv = Target.Validation<br />
&nbsp; &nbsp; &nbsp; &nbsp; sDv1 = dv.Formula1<br />
&nbsp; &nbsp; <span style="color: #0000DD;">On</span> <span style="color: #0000DD;">Error</span> <span style="color: #0000DD;">GoTo</span> <span style="color: #cc66cc;">0</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">Len</span><span style="color:#008800;">&#40;</span>sDv1<span style="color:#008800;">&#41;</span>&gt; <span style="color: #cc66cc;">0</span> <span style="color: #0000DD;">Then</span> <span style="color: #007F00;">'only if the cell has dv</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> dv.<span style="color: #0000DD;">Type</span> = xlValidateList <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Cancel = True <span style="color: #007F00;">'don't do the default action</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vOldValue = Target.Value<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vaList = GetValidList<span style="color:#008800;">&#40;</span>dv.Formula1<span style="color:#008800;">&#41;</span> <span style="color: #007F00;">'return single dim array</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">For</span> i = <span style="color: #0000DD;">LBound</span><span style="color:#008800;">&#40;</span>vaList<span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">To</span> <span style="color: #0000DD;">UBound</span><span style="color:#008800;">&#40;</span>vaList<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> vaList<span style="color:#008800;">&#40;</span>i<span style="color:#008800;">&#41;</span> = Target.Value <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> i = <span style="color: #0000DD;">UBound</span><span style="color:#008800;">&#40;</span>vaList<span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Target.Value = vaList<span style="color:#008800;">&#40;</span><span style="color: #0000DD;">LBound</span><span style="color:#008800;">&#40;</span>vaList<span style="color:#008800;">&#41;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Target.Value = vaList<span style="color:#008800;">&#40;</span>i + <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Exit</span> <span style="color: #0000DD;">For</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Next</span> i<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> Target.Value = vOldValue <span style="color: #0000DD;">Then</span> <span style="color: #007F00;">'if cell was blank</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Target.Value = vaList<span style="color:#008800;">&#40;</span><span style="color: #0000DD;">LBound</span><span style="color:#008800;">&#40;</span>vaList<span style="color:#008800;">&#41;</span><span style="color:#008800;">&#41;</span> <span style="color: #007F00;">'go to first item</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Private</span> <span style="color: #0000DD;">Function</span> GetValidList<span style="color:#008800;">&#40;</span>sForm <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Variant</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> vArr <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Variant</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> vaReturn <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Variant</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> i <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> bIsRange <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Boolean</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">On</span> <span style="color: #0000DD;">Error</span> <span style="color: #0000DD;">Resume</span> <span style="color: #0000DD;">Next</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; vArr = Evaluate<span style="color:#008800;">&#40;</span>sForm<span style="color:#008800;">&#41;</span> <span style="color: #007F00;">'for range reference</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">On</span> <span style="color: #0000DD;">Error</span> <span style="color: #0000DD;">GoTo</span> <span style="color: #cc66cc;">0</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">IsError</span><span style="color:#008800;">&#40;</span>vArr<span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">Then</span> <span style="color: #007F00;">'for csv list</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; vArr = <span style="color: #0000DD;">Split</span><span style="color:#008800;">&#40;</span>sForm, <span style="color: #ff0000;">","</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; bIsRange = False<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; bIsRange = True<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp;<br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> bIsRange <span style="color: #0000DD;">Then</span> <span style="color: #007F00;">'conver to single dim array</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">ReDim</span> vaReturn<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">0</span> <span style="color: #0000DD;">To</span> <span style="color: #0000DD;">UBound</span><span style="color:#008800;">&#40;</span>vArr, <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span> - <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">For</span> i = <span style="color: #0000DD;">LBound</span><span style="color:#008800;">&#40;</span>vArr, <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">To</span> <span style="color: #0000DD;">UBound</span><span style="color:#008800;">&#40;</span>vArr, <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vaReturn<span style="color:#008800;">&#40;</span>i - <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span> = vArr<span style="color:#008800;">&#40;</span>i, <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Next</span> i<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; vaReturn = vArr<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; GetValidList = vaReturn<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Function</span></div>
</div>
</div>
<p></p>
<p>This code is in the sheet's class module (Sheet1 in my case).  Test it out if you like.  Let me know if you see any errors or better ways.</p>
<p>P.S.  Why is <code>Target.Validation</code> always something (that is, Not Nothing) even if the cell doesn't have validation?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/05/06/double-clicking-through-a-list/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Efficient Looping</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/29/efficient-looping/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/29/efficient-looping/#comments</comments>
		<pubDate>Tue, 29 Apr 2008 16:53:21 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[Arrays]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/29/efficient-looping/</guid>
		<description><![CDATA[In a previous post, I demonstrated how to use constants to improve your code.  Then everyone started beating up my loop.  The code wasn't solving a real life problem, so I just threw any old loop together.  It wasn't relevant because that's not what the post was about.  To fight back, [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://www.dailydoseofexcel.com/archives/2008/04/28/testing-strings-using-left/">previous post</a>, I demonstrated how to use constants to improve your code.  Then everyone started beating up my loop.  The code wasn't solving a real life problem, so I just threw any old loop together.  It wasn't relevant because that's not what the post was about.  To fight back, I created a <a href="http://www.dailydoseofexcel.com/archives/2008/04/28/testing-strings-using-left/#comment-32090">highly improbably backstory in the comments</a> to make my loop look at least as efficient as everyone else's.</p>
<p>But no matter how crazy my story was, I couldn't subvert <a href="http://www.dailydoseofexcel.com/archives/2008/04/28/testing-strings-using-left/#comment-32078">Peltier's comment about reading the range into an array</a>.  So I tried to see what kind of time differences we're talking about.  I wrote this code:</p>
<div class="syntax_hilite">
<div id="vb-40">
<div class="vb"><span style="color: #0000DD;">Sub</span> DoBoth<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> lStart <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> i <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; lStart = <span style="color: #0000DD;">Timer</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">For</span> i = <span style="color: #cc66cc;">1</span> <span style="color: #0000DD;">To</span> <span style="color: #cc66cc;">10</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FindTotals2<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Next</span> i<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Debug</span>.<span style="color: #0000DD;">Print</span> <span style="color: #0000DD;">Timer</span> - lStart<br />
&nbsp; &nbsp; lStart = <span style="color: #0000DD;">Timer</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">For</span> i = <span style="color: #cc66cc;">1</span> <span style="color: #0000DD;">To</span> <span style="color: #cc66cc;">10</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UseArray<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Next</span> i<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Debug</span>.<span style="color: #0000DD;">Print</span> <span style="color: #0000DD;">Timer</span> - lStart<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Sub</span> FindTotals2<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> rCell <span style="color: #0000DD;">As</span> Range<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Const</span> sFIND <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span> = <span style="color: #ff0000;">"Total"</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #0000DD;">For</span> <span style="color: #0000DD;">Each</span> rCell <span style="color: #0000DD;">In</span> Sheet1.Columns<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span>.Cells<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">Left</span>$<span style="color:#008800;">&#40;</span>rCell, <span style="color: #0000DD;">Len</span><span style="color:#008800;">&#40;</span>sFIND<span style="color:#008800;">&#41;</span><span style="color:#008800;">&#41;</span> = sFIND <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007F00;">'Do something</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Next</span> rCell<br />
&nbsp; &nbsp;<br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Sub</span> UseArray<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> vArr <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Variant</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> i <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Const</span> sFIND <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span> = <span style="color: #ff0000;">"Total"</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; vArr = Sheet1.Columns<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span>.Value<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">For</span> i = <span style="color: #0000DD;">LBound</span><span style="color:#008800;">&#40;</span>vArr<span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">To</span> <span style="color: #0000DD;">UBound</span><span style="color:#008800;">&#40;</span>vArr<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">Left</span>$<span style="color:#008800;">&#40;</span>vArr<span style="color:#008800;">&#40;</span>i, <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span>, <span style="color: #0000DD;">Len</span><span style="color:#008800;">&#40;</span>sFIND<span style="color:#008800;">&#41;</span><span style="color:#008800;">&#41;</span> = sFIND <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007F00;">'Do something</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Next</span> i<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<p>And got these results:</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/effloop1.gif" height="232" width="459" alt="" /></p>
<p>The array is quite a bit faster.  I don't think Timer is hyper-accurate, but relatively the differences are pretty clear.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/29/efficient-looping/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Testing Strings Using Left</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/28/testing-strings-using-left/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/28/testing-strings-using-left/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 16:44:48 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[VBA Basics]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/28/testing-strings-using-left/</guid>
		<description><![CDATA[The "wrong" way:


Sub FindTotals&#40;&#41;
&#160; &#160; 
&#160; &#160; Dim rCell As Range
&#160; &#160; 
&#160; &#160; For Each rCell In Sheet1.Columns&#40;1&#41;.Cells
&#160; &#160; &#160; &#160; If Left$&#40;rCell, 5&#41; = "Total" Then
&#160; &#160; &#160; &#160; &#160; &#160; 'Do something
&#160; &#160; &#160; &#160; End If
&#160; &#160; Next rCell
&#160; &#160; 
End Sub



The "right" way:


Sub FindTotals2&#40;&#41;
&#160; &#160; 
&#160; &#160; Dim rCell As [...]]]></description>
			<content:encoded><![CDATA[<p>The "wrong" way:</p>
<div class="syntax_hilite">
<div id="vb-43">
<div class="vb"><span style="color: #0000DD;">Sub</span> FindTotals<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> rCell <span style="color: #0000DD;">As</span> Range<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">For</span> <span style="color: #0000DD;">Each</span> rCell <span style="color: #0000DD;">In</span> Sheet1.Columns<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span>.Cells<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">Left</span>$<span style="color:#008800;">&#40;</span>rCell, <span style="color: #cc66cc;">5</span><span style="color:#008800;">&#41;</span> = <span style="color: #ff0000;">"Total"</span> <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007F00;">'Do something</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Next</span> rCell<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<p>The "right" way:</p>
<div class="syntax_hilite">
<div id="vb-44">
<div class="vb"><span style="color: #0000DD;">Sub</span> FindTotals2<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> rCell <span style="color: #0000DD;">As</span> Range<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Const</span> sFIND <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span> = <span style="color: #ff0000;">"Total"</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">For</span> <span style="color: #0000DD;">Each</span> rCell <span style="color: #0000DD;">In</span> Sheet1.Columns<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span>.Cells<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">Left</span>$<span style="color:#008800;">&#40;</span>rCell, <span style="color: #0000DD;">Len</span><span style="color:#008800;">&#40;</span>sFIND<span style="color:#008800;">&#41;</span><span style="color:#008800;">&#41;</span> = sFIND <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007F00;">'Do something</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Next</span> rCell<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<p>Both "right" and "wrong" are in quotes because, like many best practices, it can be a matter of taste and preference.  In the second method, I can change the string in one place and I'm done.  In the first, if I change the string, I also have to change the second argument of Left$().</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/28/testing-strings-using-left/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Printing First Page of Email in Outlook</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/23/printing-first-page-of-email-in-outlook/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/23/printing-first-page-of-email-in-outlook/#comments</comments>
		<pubDate>Wed, 23 Apr 2008 16:41:28 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[Automation]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/23/printing-first-page-of-email-in-outlook/</guid>
		<description><![CDATA[I print out my email.  No, I'm not one of the Luddites that prints out every email (or has his secretary do it) because he doesn't understand how to work his email machine.  My system for organization is loosely based on Getting Things Done and its derivative 43 Folders.  Everything I have [...]]]></description>
			<content:encoded><![CDATA[<p>I print out my email.  No, I'm not one of the Luddites that prints out every email (or has his secretary do it) because he doesn't understand how to work his email machine.  My system for organization is loosely based on <a href="http://www.davidco.com/">Getting Things Done</a> and its derivative <a href="http://www.davidco.com/">43 Folders</a>.  Everything I have to do is represented by at least one piece of paper.  So don't try to convince me to quit printing my email, because it's not going to happen.</p>
<p>If I get an email that requires some action in the future, I need one of these pieces of paper to represent that future action.  Until recently, I would print the email to serve that purpose.  As you already know, email can get quite long and that means I can end up with 10 sheets of paper where I only needed one.  When you deal with accountants and lawyers, it's even worse because each of their messages in the thread has a page of disclaimers.  Oddly, Outlook's print dialog doesn't let you specify a page range.  There are some <a href="http://www.outlook-tips.net/archives/2005/20050927.htm">work arounds</a>, but none of them are suitable for me.  I read all my email in plain text and I reply in plain text (HTML is for web pages, not email).  Since I'm using plain text, I use Outlook's built-in email editor rather than Word.</p>
<p>After I printed seven pages of an email today, I decided to finally write some code.  I put a button on my new email commandbar and hooked it up to this procedure:</p>
<div class="syntax_hilite">
<div id="vb-46">
<div class="vb"><span style="color: #0000DD;">Sub</span> PrintOnePage<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> mi <span style="color: #0000DD;">As</span> MailItem<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> sBody <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> wdApp <span style="color: #0000DD;">As</span> Word.Application<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Const</span> sORIG <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span> = <span style="color: #ff0000;">"&gt; -----Original Message-----"</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">TypeName</span><span style="color:#008800;">&#40;</span>Application.ActiveInspector.CurrentItem<span style="color:#008800;">&#41;</span> = <span style="color: #ff0000;">"MailItem"</span> <span style="color: #0000DD;">Then</span> <span style="color: #007F00;">'only mail</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007F00;">'create a forward to get the header</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Set</span> mi = Application.ActiveInspector.CurrentItem.Forward<br />
&nbsp; &nbsp; &nbsp; &nbsp; sBody = mi.Body<br />
&nbsp; &nbsp; &nbsp; &nbsp; sBody = <span style="color: #0000DD;">Mid</span><span style="color:#008800;">&#40;</span>sBody, <span style="color: #0000DD;">InStr</span><span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">1</span>, sBody, sORIG<span style="color:#008800;">&#41;</span>, <span style="color: #cc66cc;">5000</span><span style="color:#008800;">&#41;</span> <span style="color: #007F00;">'Remove inserted signature</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Set</span> wdApp = <span style="color: #0000DD;">New</span> Word.Application<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">With</span> wdApp.Documents.Add<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Range.<span style="color: #0000DD;">Text</span> = sBody<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .PageSetup.LeftMargin = <span style="color: #cc66cc;">18</span> <span style="color: #007F00;">'.25&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .PageSetup.RightMargin = <span style="color: #cc66cc;">18</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .PageSetup.TopMargin = <span style="color: #cc66cc;">18</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .PrintOut False, False, wdPrintFromTo, <span style="color: #ff0000;">""</span>, <span style="color: #ff0000;">"1"</span>, <span style="color: #ff0000;">"1"</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">With</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; wdApp.Quit False <span style="color: #007F00;">'don't save changes</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Set</span> wdApp = <span style="color: #0000DD;">Nothing</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; mi.<span style="color: #0000DD;">Close</span> olDiscard <span style="color: #007F00;">'don't save changes</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Set</span> mi = <span style="color: #0000DD;">Nothing</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<p>I didn't want to automate Word to do this, but I struggled with other options to limit it to one page.  I know that printing out of Outlook puts 60 lines on the first page.  However, when I tried to limit the text to the first 60 vbNewLine's, it didn't quite work out.  I started to think that maybe Outlook doesn't put a vbNewLine after each line, but rather after each paragraph.  I'm still not sure why that didn't work.  So I resigned to automate Word and use it's page range feature to limit the print out.</p>
<p>I limit this to MailItems although it may work on other objects.  I didn't want to test it.  The MailItem I work with is a forwarded copy of the original.  When I forward an email it puts the header information at the top of each email in the thread, so I get some needed information on my print out.  Unfortunately, it also puts my signature in there, so I have to strip that part out by starting the string at the Original Message part.  And I limit the string to 5,000 because that should be more than one page and there's no need to transfer more than that.</p>
<p>I kept getting a type mismatch error when using Word's PrintOut method.  At first I thought it was because I was omitting optional arguments, but that really shouldn't be the case when I'm early binding.  I seem to remember a problem with optional arguments using late binding - specifically that you have to include all optional arguments up until the one you want to include, then none after that.  But I was still getting the error.  Inexplicably, Word wants Strings for page numbers.  You'll notice that my page numbers are in quotes.</p>
<p>Finally, I close Word without saving changes and discard the forwarded copy of the email.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/23/printing-first-page-of-email-in-outlook/feed/</wfw:commentRss>
		</item>
		<item>
		<title>VBE Bookmark add-in for Office 2000-2007</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/21/vbe-bookmark-add-in-for-office-2000-2007/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/21/vbe-bookmark-add-in-for-office-2000-2007/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 19:44:00 +0000</pubDate>
		<dc:creator>Ron de Bruin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Downloads]]></category>

		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/21/vbe-bookmark-add-in-for-office-2000-2007/</guid>
		<description><![CDATA[Hi all
New page on my site with a very useful add-in from Jim Rech.
http://www.rondebruin.nl/vbebookmarks.htm
VBEBookmarks.dll is a simple COM Add-in created by Jim Rech for the Microsoft Office 2000-2007 Visual
Basic Editor which lets you bookmark up to five locations in VBA projects for easy navigation among them.
Have fun
Ron de Bruin
http://www.rondebruin.nl/tips.htm
]]></description>
			<content:encoded><![CDATA[<p>Hi all</p>
<p>New page on my site with a very useful add-in from Jim Rech.<br />
<a href="http://www.rondebruin.nl/vbebookmarks.htm">http://www.rondebruin.nl/vbebookmarks.htm</a></p>
<p>VBEBookmarks.dll is a simple COM Add-in created by Jim Rech for the Microsoft Office 2000-2007 Visual<br />
Basic Editor which lets you bookmark up to five locations in VBA projects for easy navigation among them.</p>
<p>Have fun</p>
<p>Ron de Bruin<br />
<a href="http://www.rondebruin.nl/tips.htm">http://www.rondebruin.nl/tips.htm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/21/vbe-bookmark-add-in-for-office-2000-2007/feed/</wfw:commentRss>
		</item>
		<item>
		<title>I&#8217;ve Arrived</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/14/ive-arrived/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/14/ive-arrived/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 21:56:29 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[MVP]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/14/ive-arrived/</guid>
		<description><![CDATA[I'm in Seattle for the MVP Summit.  This hotel is great.  I just downed a whole jar of complimentary Macademia nuts and...  What's this thing that looks like a menu?  Damn!
I'm off to register and score some of the Rock Bottom brew.  I'll be sure to have one for those [...]]]></description>
			<content:encoded><![CDATA[<p>I'm in Seattle for the MVP Summit.  This hotel is great.  I just downed a whole jar of complimentary Macademia nuts and...  What's this thing that looks like a menu?  Damn!</p>
<p>I'm off to register and score some of the Rock Bottom brew.  I'll be sure to have one for those of you who couldn't make it this year.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/14/ive-arrived/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mike Won!</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/13/mike-won/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/13/mike-won/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 03:02:18 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[MVP]]></category>

		<category><![CDATA[Books]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/13/mike-won/</guid>
		<description><![CDATA[Mike from the Northeast won the 4-year anniversary contest.  A copy of Dalgleish's Excel Pivot Table Recipes is soon to be rushing to his house from wherever Amazon rushes stuff.  In the contest, I asked for your favorite non-Excel blogs, and here are some of them:
Office Live Small Business... - Why are Microsoft [...]]]></description>
			<content:encoded><![CDATA[<p>Mike from the Northeast won <a href="http://www.dailydoseofexcel.com/archives/2008/03/31/can-you-believe/">the 4-year anniversary contest.</a>  A copy of <a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&#038;tag=dailydoseofex-20&#038;camp=1789&#038;creative=9325&#038;path=http://www.amazon.com/gp/product/1590596293?v=glance%26n=283155%26s=books%26v=glance">Dalgleish's Excel Pivot Table Recipes</a> is soon to be rushing to his house from wherever Amazon rushes stuff.  In the contest, I asked for your favorite non-Excel blogs, and here are some of them:</p>
<p><a href="http://myofficelivecommunity.com/discuss/blogs/officelivecommunity/default.aspx">Office Live Small Business...</a> - Why are Microsoft brand names a whole paragrah?  Just say it already!<br />
<a href="http://fakesteve.blogspot.com/">The Secret Diary of Steve Jobs</a><br />
<a href="http://www.newyorker.com/online/blogs/sashafrerejones">Sasha Frere-Jones</a><br />
<a href="http://beyondthirty.com/101-things-in-1001-days/">101-things-in-1001-days</a> - I was going to do that once - too hard.<br />
<a href="http://pogue.blogs.nytimes.com/">Pogue's Posts</a><br />
<a href="http://stuffwhitepeoplelike.wordpress.com/">Stuff White People Like</a> - A little racism for variety.<br />
<a href="http://infosthetics.com/">Information Aesthetics</a><br />
<a href="http://hotair.com/">Hot Air</a><br />
<a href="http://blogs.msdn.com/oldnewthing/">Old New Thing</a><br />
<a href="http://seanmacnair.blogspot.com/">Sean MacNair</a> - Kiss over Zep?  C'mon!<br />
<a href="http://wwar1.blogspot.com/">Experiences of an English Soldier</a><br />
<a href="http://gizmodo.com/">Gizmodo</a> - I quit reading gadget sites for some reason. Maybe it's time to start again.<br />
<a href="http://blog.nbc.com/CreedThoughts/">Creed Thoughts</a> - Possibly my favorite non-Simpsons show</p>
<p>I haven't read many of these blogs and don't endorse them.  But I casually glanced at them and will probably give them a second look.</p>
<p>I'm heading to Seattle tomorrow for the MVP Summit.  If you read blogs by other Excel MVPs, you know we like to drink at the Rock Bottom.  As is my tradition, I got a new pair of shoes right before the summit.  I bought Sketchers this time because I'm trying to look younger.  It must be a mid-life crisis thing.  Now if I could just learn to balance on a skateboard.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/13/mike-won/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tab Groups</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/07/tab-groups/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/07/tab-groups/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 01:59:36 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[Wishlist]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/07/tab-groups/</guid>
		<description><![CDATA[Scott wishes:
G’day Dick,
My wish list would be to have the functionality to group excel tabs within a workbook.  So instead of having 20+ tabs going along the bottom of the screen you could group (similar to TabScrip in VBA ) them into a common theme.  Maybe group all the raw data tabs, input [...]]]></description>
			<content:encoded><![CDATA[<p>Scott wishes:</p>
<blockquote><p>G’day Dick,</p>
<p>My wish list would be to have the functionality to group excel tabs within a workbook.  So instead of having 20+ tabs going along the bottom of the screen you could group (similar to TabScrip in VBA ) them into a common theme.  Maybe group all the raw data tabs, input sheets, output reports, State summaries, Yearly reports, etc.</p>
<p>Now, if you have some finance VBA code that already does it……then here’s your chance to make a wish come true.   </p>
<p>Cheers matey.</p></blockquote>
<p>I couldn't find a picture of TabScrip, and if he meant TabStrip, then I don't know what he's talking about.   You can color your tabs to group them.  You can't move the tabs to any other position except the bottom, as far as I know.</p>
<p>I have a few workbooks that have a lot of tabs.  In those rare situations I wish for better navigation of tabs.  If you right click on the VCR buttons to the left of the tabs, you can quickly select a tab.  If you have more than 16 tabs, you can't see them all.  Instead you get a "More Sheets" options that brings up an unsortable dialog.</p>
<p>First, I'd like that right click list to go all the way to the top of the screen.  Don't stop at 16, stop at 30 or some other number that gives me more options.  If I do need to open the dialog, I want three sort options: the order they appear in the workook; alphabetical order; and zOrder (the order in which they were last accessed).  I guess that's six sorts with ascending and descending options.  I don't really need this because I only have a handful of really big workbooks.  But it would be handy in those cases.</p>
<p>What do you think about Scott's wish or tabs in general?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/07/tab-groups/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Copy Paste to External Application</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/05/copy-paste-to-external-application/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/05/copy-paste-to-external-application/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 21:12:25 +0000</pubDate>
		<dc:creator>Rob van Gelder</dc:creator>
		
		<category><![CDATA[Automation]]></category>

		<category><![CDATA[Windows API]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/05/copy-paste-to-external-application/</guid>
		<description><![CDATA[Sometimes I find myself copy-pasting between Excel and another application.
In this example, I have a table of three columns: First Name, Last Name, Birth Date.
My external application has 3 text boxes, one for each of those values.
I can't just copy the 3 cells from Excel and paste them to my App, because they would all [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes I find myself copy-pasting between Excel and another application.<br />
In this example, I have a table of three columns: First Name, Last Name, Birth Date.<br />
My external application has 3 text boxes, one for each of those values.</p>
<p>I can't just copy the 3 cells from Excel and paste them to my App, because they would all end up in the first text box!<br />
But, by running VBA SendKeys with a specially crafted string, I can send keystrokes for tabbing to the 2nd and 3rd text boxes.</p>
<p>I also need to activate the SendKeys procedure only when my cursor is positioned correctly, or things could get messy.</p>
<p>My approach is to run a macro that sits there listening for F6 before activating SendKeys.<br />
I've also included listening for the Esc key, just in case I change my mind.</p>
<div class="syntax_hilite">
<div id="vb-48">
<div class="vb"><span style="color: #0000DD;">Declare</span> <span style="color: #0000DD;">Function</span> GetAsyncKeyState <span style="color: #0000DD;">Lib</span> <span style="color: #ff0000;">"user32"</span> <span style="color:#008800;">&#40;</span><span style="color: #0000DD;">ByVal</span> vKey <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Integer</span><br />
&nbsp;<br />
<span style="color: #007F00;">' Virtual-Key Codes http://msdn2.microsoft.com/en-us/library/ms645540(VS.85).aspx</span><br />
<span style="color: #0000DD;">Const</span> VK_F6 = &amp;H75<br />
<span style="color: #0000DD;">Const</span> VK_ESC = &amp;H1B<br />
&nbsp;<br />
<span style="color: #0000DD;">Sub</span> Scanning<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> lngRow <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span>, <span style="color: #0000DD;">str</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span><br />
&nbsp;<br />
&nbsp; &nbsp; lngRow = Selection.row<br />
&nbsp; &nbsp; <span style="color: #0000DD;">str</span> = Cells<span style="color:#008800;">&#40;</span>lngRow, <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span> &amp; <span style="color: #0000DD;">vbTab</span> &amp; Cells<span style="color:#008800;">&#40;</span>lngRow, <span style="color: #cc66cc;">2</span><span style="color:#008800;">&#41;</span> &amp; <span style="color: #0000DD;">vbTab</span> &amp; _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Format</span><span style="color:#008800;">&#40;</span>Cells<span style="color:#008800;">&#40;</span>lngRow, <span style="color: #cc66cc;">3</span><span style="color:#008800;">&#41;</span>, <span style="color: #ff0000;">"dd-mmm-yyyy"</span><span style="color:#008800;">&#41;</span><br />
&nbsp;<br />
&nbsp; &nbsp; <span style="color: #0000DD;">MsgBox</span> <span style="color: #ff0000;">"Click OK, then click the First Name box on the external application, then press F6 on the keyboard"</span><br />
&nbsp; &nbsp; WaitAndSend <span style="color: #0000DD;">str</span>, VK_F6, VK_ESC<br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Sub</span> WaitAndSend<span style="color:#008800;">&#40;</span>SendString <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span>, ExecuteKey <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span>, CancelKey <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">DoEvents</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> GetAsyncKeyState<span style="color:#008800;">&#40;</span>CancelKey<span style="color:#008800;">&#41;</span> &lt;&gt; <span style="color: #cc66cc;">0</span> <span style="color: #0000DD;">Then</span> <span style="color: #0000DD;">Exit</span> <span style="color: #0000DD;">Do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> GetAsyncKeyState<span style="color:#008800;">&#40;</span>ExecuteKey<span style="color:#008800;">&#41;</span> &lt;&gt; <span style="color: #cc66cc;">0</span> <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">SendKeys</span> SendString, True<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Exit</span> <span style="color: #0000DD;">Do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Loop</span><br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/05/copy-paste-to-external-application/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting the Printer Port</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/05/getting-the-printer-port/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/05/getting-the-printer-port/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 16:13:15 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[Registry]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/05/getting-the-printer-port/</guid>
		<description><![CDATA[Do you know how windows appends that "on Ne01" to your ActivePrinter.  In the old days we had to loop through all the possible digits to find which one didn't error out.  Well no more!
Holger uses the registry to find the printer port.  Very clever.  However, if you have back slashes [...]]]></description>
			<content:encoded><![CDATA[<p>Do you know how windows appends that "on Ne01" to your ActivePrinter.  In the old days we had to <a href="http://groups.google.com/group/microsoft.public.excel.programming/browse_frm/thread/25481381390f0156">loop through all the possible digits</a> to find which one didn't error out.  Well no more!</p>
<p><a href="http://groups.google.com/group/microsoft.public.excel.programming/browse_frm/thread/a147b11f25324cac/cc0ace7224820999?lnk=st&#038;q=holger+excel+unc+strprinter#cc0ace7224820999">Holger uses the registry</a> to find the printer port.  Very clever.  However, if you have back slashes in your regestry key name, the scripting shell object won't work for retrieving them.  To the shell, back slashes are path separators, so it's trying to navigate down some path that doesn't exist.</p>
<p>To overcome that problem, you can use Registration Manipulation Classes.</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/regmanip.gif" height="364" width="449" alt="" /></p>
<p>If <strike>your</strike> you're a late binding kind of a guy, use <code>CreateObject("RegObj.Registry")</code> in your code.  With this dll, we can loop through all of the keys in a folder, like so:</p>
<div class="syntax_hilite">
<div id="vb-50">
<div class="vb"><span style="color: #0000DD;">Function</span> GetPrinterPort<span style="color:#008800;">&#40;</span>sPrinterName <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> objReg <span style="color: #0000DD;">As</span> RegObj.Registry<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> objRootKey <span style="color: #0000DD;">As</span> RegObj.RegKey<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> sKey <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> objVal <span style="color: #0000DD;">As</span> RegObj.RegValue<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> sData <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">String</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> vData <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Variant</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; sKey = <span style="color: #ff0000;">"\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices\"</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> objReg = <span style="color: #0000DD;">New</span> RegObj.Registry<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> objRootKey = objReg.RegKeyFromString<span style="color:#008800;">&#40;</span>sKey<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">For</span> <span style="color: #0000DD;">Each</span> objVal <span style="color: #0000DD;">In</span> objRootKey.Values<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> objVal.<span style="color: #0000DD;">Name</span> = sPrinterName <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sData = objVal.Value<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Exit</span> <span style="color: #0000DD;">For</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Next</span> objVal<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">Len</span><span style="color:#008800;">&#40;</span>sData<span style="color:#008800;">&#41;</span>&gt; <span style="color: #cc66cc;">0</span> <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; vData = <span style="color: #0000DD;">Split</span><span style="color:#008800;">&#40;</span>sData, <span style="color: #ff0000;">","</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; GetPrinterPort = vData<span style="color:#008800;">&#40;</span><span style="color: #0000DD;">UBound</span><span style="color:#008800;">&#40;</span>vData<span style="color:#008800;">&#41;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; GetPrinterPort = <span style="color: #ff0000;">""</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> objReg = <span style="color: #0000DD;">Nothing</span><br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Function</span></div>
</div>
</div>
<p></p>
<p>I haven't tested that extensively, so use caution.</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/regmanip2.gif" height="155" width="459" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/05/getting-the-printer-port/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Investing in Lean</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/03/investing-in-lean/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/03/investing-in-lean/#comments</comments>
		<pubDate>Fri, 04 Apr 2008 02:38:00 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[Financial Functions]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/03/investing-in-lean/</guid>
		<description><![CDATA[I'm a big fan of the Toyota Production System.  I was thinking that I should find a mutual fund that invests in lean companies, but I couldn't find one.  I searched for "best lean companies" to see if I could get a list, and found Who Are the Best Lean Companies at leanblog.org, [...]]]></description>
			<content:encoded><![CDATA[<p>I'm a big fan of the Toyota Production System.  I was thinking that I should find a mutual fund that invests in lean companies, but I couldn't find one.  I searched for "best lean companies" to see if I could get a list, and found <a href="http://www.leanblog.org/2007/07/who-are-best-lean-companies.html">Who Are the Best Lean Companies</a> at leanblog.org, a blog I read every day.</p>
<p>I took all of the companies in the top 10 for whom I could find <a href="http://bigcharts.marketwatch.com/historical/">historical data</a>.  I compared buying one share of each of those companies to buying one "share"  of the S&#038;P500 over the same period.  The lean companies outperformed the index.</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/leaninvest.gif" height="237" width="323" alt="" /></p>
<p><code>D9: =RATE(C1-B1,0,-B9,C9)*365</code><br />
<code>D11: =RATE(C1-B1,0,-B11,C11)*365</code></p>
<p>Are those formulas right?  I'm trying to get an annual return.</p>
<p>I couldn't stock-pick my way out of a paper bag (I'm looking at you <a href="http://finance.yahoo.com/q?s=BKE">Buckle</a>; I'm looking at you <a href="http://finance.yahoo.com/q?s=ICPXQ.PK">Inacom</a>), so don't take investing advice from me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/03/investing-in-lean/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Updating Stock Quotes</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/04/01/updating-stock-quotes/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/04/01/updating-stock-quotes/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 02:49:29 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[External Data]]></category>

		<category><![CDATA[Classes]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/04/01/updating-stock-quotes/</guid>
		<description><![CDATA[I answer about four questions a month on the newsgroups.  I'm off to a roaring start in April, but I don't like my answer much.  I never know just how "correct" an answer to give.  So I gave an answer that I felt was appropriate for the original poster and I'll give [...]]]></description>
			<content:encoded><![CDATA[<p>I answer about four questions a month on the <a href="http://www.cpearson.com/excel/DirectConnect.htm">newsgroups</a>.  I'm off to a roaring start in April, but I don't like my answer much.  I never know just how "correct" an answer to give.  So I gave an answer that I felt was appropriate for the original poster and I'll give a slightly different answer here.</p>
<p>The OP has an external query pulling stock quotes from Yahoo! Finance.  He's using their csv download option, but just querying the csv rather than downloading it and loading it into Excel.  One problem with that is that it puts all of the data in one column.  If there's a built-in way to fix that, I don't know it.  The other problem is that the list of companies he wants to see is variable and lives in a range of cells.  I actually don't know if these are his problems, but I like to pretend.</p>
<p>My objectives are to create a web query to Yahoo, add a parameter that points to a range, and parse the data into multiple columns.  Does that sound like fun?  Well, I'm doing it anyway.</p>
<p>I can't create the query the old fashioned way.  The web query user interface is like a browser; if you try to point to a CSV file, the browser wants to download it.  So I create a web query to whatever table is on whatever page that happens to open up.  Basically, I'm creating a query that I will later edit to point to where I want.</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/yahooquote1.gif" height="443" width="568" alt="" /></p>
<p>I pick any old arrow on the Dell website and create a query.  I get a message that my query doesn't return any data, but I just OK past that message because I know I'll be making changes.  Next I go to the VBE, and specifically the Immediate Window, to change my query.</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/yahooquote2.gif" height="159" width="598" alt="" /></p>
<p>The part you can't see says this:</p>
<p><code>wshquotes.QueryTables(1).Connection = "URL;http://quote.yahoo.com/d/quotes.csv?s=^GSPC[""EnterTicker"",""Ticker""]&#038;f=nl1c"</code></p>
<p>If this URL isn't exactly what you want, don't worry.  <a href="http://alexle.net/archives/196">Alex has done all the legwork</a> that will allow you to get whatever data you want.  For me, I'm getting the name, last, and change for the S&#038;P500 Index plus whatever else I enter.  The "whatever else I enter" part is the parameter and is the name/prompt pair of strings inside the square brackets.  When I Refresh the QueryTable, it asks me for a Ticker.  I enter MSFT and the web query returns some data.</p>
<p>I have a parameter, but it doesn't point to a range, so that's next.  The range B1:B10 will hold whatever ticker symbols I want and D1 will put them in the format I need for the URL.</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/yahooquote3.gif" height="336" width="597" alt="" /></p>
<p>The formula in D1 is <code>="+"&#038;B1&#038;IF(NOT(ISBLANK(B2)),"+"&#038;B2,"")&#038;IF(NOT(ISBLANK(B3)),"+"&#038;B3,"")&#038;IF(NOT(ISBLANK(B4)),"+"&#038;B4,"")<br />
&#038;IF(NOT(ISBLANK(B5)),"+"&#038;B5,"")&#038;IF(NOT(ISBLANK(B6)),"+"&#038;B6,"")&#038;IF(NOT(ISBLANK(B7)),"+"&#038;B7,"")&#038;IF(NOT(ISBLANK(B8)),"+"&#038;B8,"")<br />
&#038;IF(NOT(ISBLANK(B9)),"+"&#038;B9,"")&#038;IF(NOT(ISBLANK(B10)),"+"&#038;B10,"")</code></p>
<p>Inspiring, huh?  If a ticker exists, it puts a "+" in front of it and adds it to the list.  Now I can click on the Query Parameters button on the External Data Toolbar and point to D1.</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/yahooquote4.gif" height="271" width="498" alt="" /></p>
<p>I also click on the Data Range Properties button and check the box to make the table automatically refresh.</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/yahooquote5.gif" height="433" width="384" alt="" /></p>
<p>OK, I have a parameterized web query that refreshes automatically.  Unfortunately, it gives me this</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/yahooquote6.gif" height="124" width="375" alt="" /></p>
<p>Everything in one column.  Yuck.  Time to get fancy.  I know that Text to Columns will parse the results, but I'm not going to manually do that every time the QueryTable refreshes.  Fortunately, QueryTables have events.  Two events, to be precise.  I'll be using the AfterRefresh event.  I'll bet you can guess what the other one is.</p>
<p>Other than out brief jaunt into the Immediate Window, we've been pretty much in Excel's UI up until now.  It's time to step through the looking glass into VBA and (gasp) class modules.  Open the VBE (Alt+F11) and add a class module and a module to your project.  Name the class module (F4) CQTEvents and name the module MEntryPoints.  In your class module, put this code:</p>
<div class="syntax_hilite">
<div id="vb-53">
<div class="vb"><span style="color: #0000DD;">Option</span> <span style="color: #0000DD;">Explicit</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Private</span> WithEvents mobjQTable <span style="color: #0000DD;">As</span> QueryTable<br />
&nbsp;<br />
<span style="color: #0000DD;">Private</span> <span style="color: #0000DD;">Sub</span> Class_Terminate<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> mobjQTable = <span style="color: #0000DD;">Nothing</span><br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Public</span> <span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Get</span> QTable<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">As</span> QueryTable<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> QTable = mobjQTable<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Public</span> <span style="color: #0000DD;">Property</span> <span style="color: #0000DD;">Set</span> QTable<span style="color:#008800;">&#40;</span>objQTable <span style="color: #0000DD;">As</span> QueryTable<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> mobjQTable = objQTable<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Property</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Private</span> <span style="color: #0000DD;">Sub</span> mobjQTable_AfterRefresh<span style="color:#008800;">&#40;</span><span style="color: #0000DD;">ByVal</span> Success <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Boolean</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; Application.DisplayAlerts = False<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; mobjQTable.ResultRange.TextToColumns _<br />
&nbsp; &nbsp; &nbsp; &nbsp; Destination:=mobjQTable.ResultRange.Cells<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; DataType:=xlDelimited, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; TextQualifier:=xlTextQualifierDoubleQuote, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; Comma:=True<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; Application.DisplayAlerts = True<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<p>Of course I never use public variables in a class because I'm a class module snob.  So I have a private variable declared WithEvents that exposes the events of the QueryTable variable.  Because it's a private variable, I need public get and set statements so code outside of the class can access it.  Finally, I create the AfterRefresh event (using the code pane drop downs) and simply call the TextToColumns method to parse out the QueryTable results.  If you try to TextToColumns into a range that already contains data, you'll get a message.  I use DisplayAlerts to avoid that.</p>
<p>The only thing left is to tell my class which QueryTable I care about.  I do that in the standard module with this code:</p>
<div class="syntax_hilite">
<div id="vb-54">
<div class="vb"><span style="color: #0000DD;">Option</span> <span style="color: #0000DD;">Explicit</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Public</span> clsQTEvents <span style="color: #0000DD;">As</span> CQTEvents<br />
&nbsp;<br />
<span style="color: #0000DD;">Sub</span> Auto_Open<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> clsQTEvents = <span style="color: #0000DD;">New</span> CQTEvents<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> clsQTEvents.QTable = wshQuotes.QueryTables<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Sub</span> Auto_Close<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> clsQTEvents = <span style="color: #0000DD;">Nothing</span><br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<p>That's so easy I don't even have to explain it.  Run Auto_Open and wait for your QueryTable to refresh.  Then go fix your typos and you're all set.  And you thought class module were difficult.  If you're following along at home, be sure to do this during trading hours.  Having those one minute updates where nothing changes isn't too exciting.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/04/01/updating-stock-quotes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Can You Believe</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/03/31/can-you-believe/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/03/31/can-you-believe/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 03:06:34 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/03/31/can-you-believe/</guid>
		<description><![CDATA[That I started this blog four years ago.  I can't.  It seems more like six and a half.  Here's some stats:

That's about 26 posts per month and about 8 comments per day.  I'm no Nick Hodge, but hey.






As is my wont, I'll be having an anniversary give-away.  I just like [...]]]></description>
			<content:encoded><![CDATA[<p>That I started this blog four years ago.  I can't.  It seems more like six and a half.  Here's some stats:</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/fourann.gif" height="132" width="595" alt="" /></p>
<p>That's about 26 posts per month and about 8 comments per day.  I'm no <a href="http://www.nickhodge.co.uk/blog/?p=1742">Nick Hodge</a>, but hey.</p>
<table>
<tr>
<td><a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;tag=dailydoseofex-20&amp;camp=1789&amp;creative=9325&amp;path=http://www.amazon.com/gp/product/1590596293?v=glance%26n=283155%26s=books%26v=glance"><img src="http://images.amazon.com/images/P/1590596293.01.MZZZZZZZ.jpg" alt="Excel Pivot Table Recipes" /></a></td>
<td><a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;tag=dailydoseofex-20&amp;camp=1789&amp;creative=9325&amp;path=http://www.amazon.com/gp/product/0470191112?v=glance%26n=283155%26s=books%26v=glance"><img src="http://images.amazon.com/images/P/0470191112.01.MZZZZZZZ.jpg" alt="Excel Pivot Table Recipes" /></a></td>
</tr>
</table>
<p>As is my wont, I'll be having an anniversary give-away.  I just like to give back to all the people who read, comment, and click on the advertisements.  This year you get a choice between <a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;tag=dailydoseofex-20&amp;camp=1789&amp;creative=9325&amp;path=http://www.amazon.com/gp/product/0470191112?v=glance%26n=283155%26s=books%26v=glance">RibbonX: Customizing the Office 2007 Ribbon</a> and <a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;tag=dailydoseofex-20&amp;camp=1789&amp;creative=9325&amp;path=http://www.amazon.com/gp/product/1590596293?v=glance%26n=283155%26s=books%26v=glance">Excel PivotTables Recipes</a>.  To enter</p>
<ul>
<li>Send me an email with a link to your favorite non-Excel blog, which book you prefer, and a subject of "Four More Years".</li>
<li>If you use a different subject or your email doesn't contain a link or you don't pick a prize, you're out.</li>
<li>I must receive the email by 12:00AM Central Daylight Time, April 7th, 2008.</li>
<li>You must send the email from the same email account with which you registered on this site.  If you're not registered, you can't win.  If you used a fake email to register, just include that fake email address in your message so I can confirm you're registered.</li>
<li>This list of eligible entrants will be entered into an Excel spreadsheet, a random number will be entered next to his name, and the list will be sorted on the random number.  Whoever is at the top, wins.</li>
<li>I'll probably list some of the more interesting blogs, but I won't associate them with your name, so don't be afraid to send in ParisHiltonWatch.com</li>
<li>One email per registered reader.</li>
<li>The winner will get to choose between a copy of <a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;tag=dailydoseofex-20&amp;camp=1789&amp;creative=9325&amp;path=http://www.amazon.com/gp/product/0470191112?v=glance%26n=283155%26s=books%26v=glance">RibbonX: Customizing the Office 2007 Ribbon</a> or <a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;tag=dailydoseofex-20&amp;camp=1789&amp;creative=9325&amp;path=http://www.amazon.com/gp/product/1590596293?v=glance%26n=283155%26s=books%26v=glance">Excel PivotTables Recipes</a>.</li>
<li>To be eligible, the entrant must live in a place that Amazon.com will ship to and where the shipping will be less than the cost of the book.</li>
<li>Any other rules that make this contest less of a burden on me or that I may choose to enact retroactively or otherwise makes the give-away legal and easy are hereby included.</li>
</ul>
<p>Thanks for reading!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/03/31/can-you-believe/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Excel and Music</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/03/31/excel-and-music/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/03/31/excel-and-music/#comments</comments>
		<pubDate>Mon, 31 Mar 2008 13:31:05 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[Links]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/03/31/excel-and-music/</guid>
		<description><![CDATA[Finally, a legitimate use for Excel
Excel &#038; Music
I get all of them except the "Milkshake" one.
]]></description>
			<content:encoded><![CDATA[<p>Finally, a legitimate use for Excel</p>
<p><a href="http://beyond30.wordpress.com/2008/03/31/excel-music/">Excel &#038; Music</a></p>
<p>I get all of them except the "Milkshake" one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/03/31/excel-and-music/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Limits</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/03/28/limits/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/03/28/limits/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 20:27:27 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/03/28/limits/</guid>
		<description><![CDATA[I recently ran into a problem with an application I developed over a year ago.  I had pre-formatted 100 rows in a template, some just formatting, some conditional formatting.  "We'll never need 100 rows", I said.  One hundred ninety-six rows later and I feel like the Patent Commissioner who said everything has [...]]]></description>
			<content:encoded><![CDATA[<p>I recently ran into a problem with an application I developed over a year ago.  I had pre-formatted 100 rows in a template, some just formatting, some conditional formatting.  "We'll never need 100 rows", I said.  One hundred ninety-six rows later and I feel like the <a href="http://www.patentstation.com/mdm/p142.htm">Patent Commissioner who said everything has already been invented.</a></p>
<p>Should I have picked 1000?  Should I have formatted the whole column?  I wasn't trying to be stingy, I just doubled what I though was the most rows we'd ever use.  What do you do?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/03/28/limits/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Two popular tools updated.</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/03/28/two-popular-tools-updated/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/03/28/two-popular-tools-updated/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 19:03:03 +0000</pubDate>
		<dc:creator>jkpieterse</dc:creator>
		
		<category><![CDATA[Links]]></category>

		<category><![CDATA[MVP]]></category>

		<category><![CDATA[Miscellany]]></category>

		<category><![CDATA[Downloads]]></category>

		<category><![CDATA[Add-ins]]></category>

		<category><![CDATA[Names]]></category>

		<category><![CDATA[Finding Data]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/03/28/two-popular-tools-updated/</guid>
		<description><![CDATA[Hi All,
As many of you know I give away a number of tools for Excel through my site www.jkp-ads.com. Today I have updated the two most popular downloads:
Name Manager (which I created together with Charles Williams, www.decisionmodels.com):
Most important change: the unused names filter now includes objects in its search, as well as VBA code. It [...]]]></description>
			<content:encoded><![CDATA[<p>Hi All,</p>
<p>As many of you know I give away a number of tools for Excel through my site <a href="http://www.jkp-ads.com">www.jkp-ads.com</a>. Today I have updated the two most popular downloads:</p>
<p><a href="http://www.jkp-ads.com/officemarketplacenm-en.asp">Name Manager</a> (which I created together with Charles Williams, <a href="http://www.decisionmodels.com">www.decisionmodels.com</a>):</p>
<p>Most important change: the unused names filter now includes objects in its search, as well as VBA code. It makes the filter much slower, but way more useful in my opinion. Also, I have added the Greek character set so Name Manager doesn't (wrongfully) think range names with Greek characters are corrupt.</p>
<p>So far, Name Manager has been downloaded about 50,000 times since I posted it on my site.</p>
<p><a href="http://www.jkp-ads.com/officemarketplaceff-en.asp">Flexfind</a></p>
<p>I have updated the user interface of Flexfind so (in my opinion) it is easier to use. Also, I have mimicked the find all behaviour of Excel: if you select multiple items in the found items list, Flexfind will create a (multiple) selection of areas of the found cells.</p>
<p>Flexfind is less popular than Name Manager, the download count is at about 23,000.</p>
<p>Enjoy!</p>
<p>Of course I am open to any comments, suggestions and -most importantly- lots of praise <img src='http://www.dailydoseofexcel.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Regards,<br />
Jan Karel Pieterse<br />
<a href="http://www.jkp-ads.com">www.jkp-ads.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/03/28/two-popular-tools-updated/feed/</wfw:commentRss>
		</item>
		<item>
		<title>External Data Worksheets</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/03/25/external-data-worksheets/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/03/25/external-data-worksheets/#comments</comments>
		<pubDate>Tue, 25 Mar 2008 18:08:12 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[Wishlist]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/03/25/external-data-worksheets/</guid>
		<description><![CDATA[Someone sent me an email last week suggesting I have a Wishlist category where we could discuss features we hope MS will someday incorporate into Excel.  I think that's a fine idea.  If you like, send me an email with your wish.  If I find it sufficiently interesting, I'll post it for [...]]]></description>
			<content:encoded><![CDATA[<p>Someone sent me an email last week suggesting I have a Wishlist category where we could discuss features we hope MS will someday incorporate into Excel.  I think that's a fine idea.  If you like, <a href="mailto: dkusleika@gmail.com&#038;subject=ExcelWishlist">send me an email</a> with your wish.  If I find it sufficiently interesting, I'll post it for others to comment.</p>
<p>For my first wish, I'd like a sheet in my workbook dedicated to External Data.  I think someone on <a href="http://smurfonspreadsheets.wordpress.com/">Simon's blog</a> suggested this in a comment once (maybe Harlan).  The worksheet would be a recordset of an external data source and nothing else.  Users would not be able to type anything outside the recordset or change much about the sheet.  Here's the kicker: Excel would keep the sheet and the external data source in sync.  When you write to a cell on the sheet, the external data would be updated.  If the recordset isn't updateable, you wouldn't be able to write to the cells.  If you try to put a string in a cell that's linked to an external data field designated Integer, you would get an error.  Basically it would be like datasheet view in Access.  Now I handle all this will class modules and ado, but it would be nice to stay within Excel's object model to accomplish the same thing.  Not to mention the UI.</p>
<p>One prediction I made at the recent <a href="http://www.exceluserconference.com/">Excel Users Conference</a> in Sydney is that Excel and Access will be one product in our lifetime (well mine anyway).  Have you seen Access 2007?  Do those dropdowns in datasheet view look familiar?  "But Access is a database", you say.  No, not really.  Access is the front end to a database.  In my world, Excel is usually the front end to a database.  It's not that I don't like Access, there are just people who are better at it than me, so I generally avoid that kind of work.  The recent datasheet view changes in Access 2007 brings that prediction one step closer.  My external data worksheet wish would bring it closer still.  The only question that remains is whether to call it Accel or Excess.  I prefer the latter.</p>
<p>You can leave your own wish in a comment (or email as noted above), comment on my wish, or leave a comment with what you would name the new combination Excel/Access product.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/03/25/external-data-worksheets/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Random Sorts</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/03/23/random-sorts/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/03/23/random-sorts/#comments</comments>
		<pubDate>Mon, 24 Mar 2008 02:54:54 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[VBA Basics]]></category>

		<category><![CDATA[VBA]]></category>

		<category><![CDATA[List and Table Functions]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/03/23/random-sorts/</guid>
		<description><![CDATA[Red wants to have a kind-of lottery for his students.  He will award them prizes based on a random drawing, but wants to weight each student based on the number of assignments turned in.  Normally, I would accomplish this by typing the name of each student in column A one time for every [...]]]></description>
			<content:encoded><![CDATA[<p>Red wants to have a kind-of lottery for his students.  He will award them prizes based on a random drawing, but wants to weight each student based on the number of assignments turned in.  Normally, I would accomplish this by typing the name of each student in column A one time for every assignment he turned in.  If John turned in three assignments, I'd type his name three times.  In column B, I'd put a <code>RAND()</code> function and fill it down.  Then I'd sort by column B.  I'd get something that looks like this:</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/randsort1.gif" height="235" width="184" alt="" /></p>
<p>That's all well and good, but it's missing a few things.  If I'm giving away three prizes, Sue wins them all unless I manually exclude her.  But the worst part is that it happens too fast.  Excel calculates so fast that it's not entertaining to calculate in front of a group (unless you're Charles Williams, of course).  I wanted to come up with something that doesn't allow ties, calculates more slowly, and is generally more friendly.  Here's my first stab</p>
<p><img src="http://www.dailydoseofexcel.com/blogpix/randsort2.gif" height="301" width="634" alt="" /></p>
<p>Behind the button, I have this code:</p>
<div class="syntax_hilite">
<div id="vb-56">
<div class="vb"><span style="color: #0000DD;">Public</span> <span style="color: #0000DD;">Sub</span> DrawNext<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> rNames <span style="color: #0000DD;">As</span> Range, rCell <span style="color: #0000DD;">As</span> Range<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> rLastICell <span style="color: #0000DD;">As</span> Range<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> i <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; FillNames<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> rLastICell = wshDraws.Range<span style="color:#008800;">&#40;</span><span style="color: #ff0000;">"I65536"</span><span style="color:#008800;">&#41;</span>.<span style="color: #0000DD;">End</span><span style="color:#008800;">&#40;</span>xlUp<span style="color:#008800;">&#41;</span>.Offset<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">0</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">If</span> rLastICell.Row&gt; <span style="color: #cc66cc;">2</span> <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Set</span> rLastICell = rLastICell.Offset<span style="color:#008800;">&#40;</span>-<span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Set</span> rNames = wshDraws.Range<span style="color:#008800;">&#40;</span><span style="color: #ff0000;">"I2"</span>, rLastICell<span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">For</span> <span style="color: #0000DD;">Each</span> rCell <span style="color: #0000DD;">In</span> rNames.Cells<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">For</span> i = <span style="color: #cc66cc;">1</span> <span style="color: #0000DD;">To</span> <span style="color: #cc66cc;">50</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rCell.Offset<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span>.Value = <span style="color: #0000DD;">Rnd</span> * <span style="color: #cc66cc;">1000</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Next</span> i<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Next</span> rCell<br />
&nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span><br />
&nbsp;<br />
<span style="color: #0000DD;">Private</span> <span style="color: #0000DD;">Sub</span> FillNames<span style="color:#008800;">&#40;</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> rNames <span style="color: #0000DD;">As</span> Range<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> rCell <span style="color: #0000DD;">As</span> Range, rEntry <span style="color: #0000DD;">As</span> Range<br />
&nbsp; &nbsp; <span style="color: #0000DD;">Dim</span> i <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span>, j <span style="color: #0000DD;">As</span> <span style="color: #0000DD;">Long</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> rNames = wshDraws.Range<span style="color:#008800;">&#40;</span><span style="color: #ff0000;">"I2"</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Set</span> rEntry = wshDraws.Range<span style="color:#008800;">&#40;</span><span style="color: #ff0000;">"A2:A31"</span><span style="color:#008800;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; wshDraws.Range<span style="color:#008800;">&#40;</span><span style="color: #ff0000;">"I2:J65536"</span><span style="color:#008800;">&#41;</span>.ClearContents<br />
&nbsp; &nbsp; j = <span style="color: #cc66cc;">0</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000DD;">For</span> <span style="color: #0000DD;">Each</span> rCell <span style="color: #0000DD;">In</span> rEntry.Cells<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">If</span> <span style="color: #0000DD;">Not</span> <span style="color: #0000DD;">IsEmpty</span><span style="color:#008800;">&#40;</span>rCell.Value<span style="color:#008800;">&#41;</span> <span style="color: #0000DD;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">For</span> i = <span style="color: #cc66cc;">1</span> <span style="color: #0000DD;">To</span> rCell.Offset<span style="color:#008800;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span><span style="color:#008800;">&#41;</span>.Value<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rNames.Offset<span style="color:#008800;">&#40;</span>j<span style="color:#008800;">&#41;</span>.Value = rCell.Value<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; j = j + <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">Next</span> i<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000DD;">End</span> <span style="color: #0000DD;">If</span><br />
&nbsp; &nbsp; <span style="color: #0000DD;">Next</span> rCell<br />
&nbsp; &nbsp; <br />
<span style="color: #0000DD;">End</span> <span style="color: #0000DD;">Sub</span></div>
</div>
</div>
<p></p>
<p>The user enters the information in columns A and B, up to 30 students.  The code fills column I with one instance of each name for each assignment.  Then for each name it fills in a random number between 0 and 999.  For show, it fills each cell 50 times to make it look like it's really doing some work.</p>
<p>In column C, I have this array formula</p>
<p><code>=MAX((rNames=A2)*(rDraws))</code></p>
<p>and in column D, this</p>
<p><code>=IF(RANK(C2,$C$2:$C$31)>3,"",CHOOSE(RANK(C2,$C$2:$C$31),"1st Place","2nd Place","3rd Place"))</code></p>
<p>There's not a lot of error checking and far too many literals in the code, but it's a start.</p>
<p><a href="http://www.dailydoseofexcel.com/excel/Lottery.zip">Download Lotter.zip</a>.  Yes, it's 2003 format.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/03/23/random-sorts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Excel User Conference Download</title>
		<link>http://www.dailydoseofexcel.com/archives/2008/03/18/excel-user-conference-download/</link>
		<comments>http://www.dailydoseofexcel.com/archives/2008/03/18/excel-user-conference-download/#comments</comments>
		<pubDate>Wed, 19 Mar 2008 01:50:35 +0000</pubDate>
		<dc:creator>Dick Kusleika</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.dailydoseofexcel.com/archives/2008/03/18/excel-user-conference-download/</guid>
		<description><![CDATA[Download Presenter Notes and Sample Files
If you didn't attend, these files will be of limited value.  But there they are if you want them.
As I mentioned at the conference, I will be reformatting my laptop hard drive this weekend.  My folder problem that I've been blaming on Groove, isn't Groove's fault (I think), [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dailydoseofexcel.com/excel/final.zip">Download Presenter Notes and Sample Files</a></p>
<p>If you didn't attend, these files will be of limited value.  But there they are if you want them.</p>
<p>As I mentioned at the conference, I will be reformatting my laptop hard drive this weekend.  My folder problem that I've been blaming on Groove, isn't Groove's fault (I think), but I'm due for a data enema anyway.  I've downloaded <a href="http://www.belarc.com/free_download.html">Belarc Advisor</a> to get a list of installed programs.  I will only be installing Excel 2000, <strike>2203</strike>2003, and 2007.  I eschewed 97 a while ago and I'm going to get rid of XP too.  Any other tips before I embark on this magical journey?</p>
<p>Software to install (* means I want to know what you use):<br />
Office 2000<br />
Office 2003<br />
Office 2007<br />
TaxACT*<br />
CDex<br />
Canoscan<br />
FileZilla<br />
VB6<br />
Foxit Reader<br />
Alleycode<br />
Aptana<br />
InstantRails<br />
StarCaddy<br />
JetAudio<br />
Firefox<br />
RealVNC*<br />
SnagIt<br />
PDFCreator*<br />
Irfanview*<br />
VBScroll</p>
<p>Not making the cut:<br />
Adobe Reader<br />
Avast antivirus (I'm going without)<br />
Copernic Desktop (any good desktop searches out there?)<br />
Virtual PC (maybe next beta)<br />
Lifecam (never use it, shouldn't have bought it)<br />
Google Earth<br />
Google Sketchup<br />
Street and Trips*<br />
VS.Net (I'll have to put it on eventually)<br />
Subverstion<br />
TortioseSVN</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dailydoseofexcel.com/archives/2008/03/18/excel-user-conference-download/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
