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

<channel>
	<title>Gobán Saor &#187; VBA</title>
	<atom:link href="http://blog.gobansaor.com/category/vba/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.gobansaor.com</link>
	<description>A country datasmith.</description>
	<lastBuildDate>Fri, 27 Jan 2012 10:22:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.gobansaor.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/67e164f5d51c2b3115a7819b84505c13?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Gobán Saor &#187; VBA</title>
		<link>http://blog.gobansaor.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.gobansaor.com/osd.xml" title="Gobán Saor" />
	<atom:link rel='hub' href='http://blog.gobansaor.com/?pushpress=hub'/>
		<item>
		<title>PowerPivot VBA Refresh Code &#8211; Bug Fix</title>
		<link>http://blog.gobansaor.com/2011/11/22/powerpivot-vba-refesh-code-bug-fix/</link>
		<comments>http://blog.gobansaor.com/2011/11/22/powerpivot-vba-refesh-code-bug-fix/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 17:05:05 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[Automate PowerPivot refresh]]></category>
		<category><![CDATA[PowerPivot VBA Bug Fix]]></category>
		<category><![CDATA[PowerPivot VBA Refresh]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2310</guid>
		<description><![CDATA[Just a quick post to alert those of you using my PowerPivot Refresh code to a bug in its &#8220;refresh a single table&#8221; logic. Under certain circumstances, linked tables (i.e. those on the &#8220;many&#8221; side of a relationship) will fail to &#8230; <a href="http://blog.gobansaor.com/2011/11/22/powerpivot-vba-refesh-code-bug-fix/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2310&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/guitavares/1703252007/"><img class="alignleft size-full wp-image-2311" title="" src="http://gobansaor.files.wordpress.com/2011/11/bug.jpg?w=500" alt=""   /></a>Just a quick post to alert those of you using my PowerPivot Refresh code to a bug in its &#8220;refresh a single table&#8221; logic. Under certain circumstances, linked tables (i.e. those on the &#8220;many&#8221; side of a relationship) will fail to refresh if specified individually (fine when part of a refresh all). S<a href="http://blog.gobansaor.com/2011/09/09/hammering-away-at-automated-powerpivot-refresh/#comment-7886">ee here for the details behind the bug</a>, and thanks again to Rob Parker for bringing it to my attention. I&#8217;ve updated the sample code with the fix, <a href="http://www.gobansaor.com/excel-based-bi">download it here</a>.</p>
<p>I&#8217;ve also tested the code against the just released <a href="http://www.microsoft.com/download/en/details.aspx?id=28150">SQLServer 2010 RC0 version of PowerPivot </a>and it appears to work.</p>
<p>I&#8217;ve updated the equivalent PPREFRESH code in HAMMER and this is now part of the tool&#8217;s latest release (V1.3.4(Beta)). My previous post,<a href="http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/"> Excel as a Book of Record</a>, previewed the most important new commands available in this release. Alongside those, I&#8217;ve also added the following:</p>
<ul>
<li>ISTABLE, if the previous COMMAND&#8217;s result  or the previous argument is not a table, this will abend the command sequence.</li>
<li>ISARG, as above, but this time checks for an argument (a HAMMER parameter may either be a table, a command or an argument- aka, an ARG).</li>
<li>ISOK, previous argument must be the string value &#8220;OK&#8221;.</li>
<li>TABLESARETHESAME, will fail if the last two tables are not identical. Intended mainly for automated regression testing.</li>
<li>ARGSARETHESAME, as above. but this time for ARGS.</li>
<li>_GUID, will return a globally unique identifier.</li>
</ul>
<p><a href="http://www.gobansaor.com/microetl">Download the latest version of HAMMER from here …</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2310/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2310&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/11/22/powerpivot-vba-refesh-code-bug-fix/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/11/bug.jpg" medium="image" />
	</item>
		<item>
		<title>Excel as a book of record.</title>
		<link>http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/</link>
		<comments>http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 12:48:06 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[AmazonAWS]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[Steam Powered Server]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[Excel JSON]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[VBA JSON]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2264</guid>
		<description><![CDATA[In the past I&#8217;ve talked about Excel as a tool to develop Really Simple Systems. Such &#8220;systems&#8221; usually occupy the middle ground between continuing to do a task by hand or  investing time/money in using a packaged/bespoke &#8220;proper system&#8221;. When &#8230; <a href="http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2264&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/book_of_record/" rel="attachment wp-att-2279"><img class="alignleft size-full wp-image-2279" title="book_of_record" src="http://gobansaor.files.wordpress.com/2011/11/book_of_record.jpg?w=500" alt=""   /></a>In the past I&#8217;ve talked about Excel as a tool to develop <a href="http://blog.gobansaor.com/2011/04/19/really-simple-systems/">Really Simple Systems</a>. Such &#8220;systems&#8221; usually occupy the middle ground between continuing to do a task by hand or  investing time/money in using a packaged/bespoke &#8220;proper system&#8221;.</p>
<p>When such systems are primarily reporting in emphasis, the justification for using Excel is usually straight forward and compelling (and getting even more compelling with the appearance on the scene of Excel 2010&#8242;s  PowerPivot.) But, alarm bells sound across the world of professional IT when Excel is proposed as a &#8220;book of record&#8221; i.e. when it&#8217;s to be used to store and maintain a business critical dataset. And, with some considerable justification, the nightmare that is linked (or even worse, shared) workbooks is very real indeed. But yet, businesses continue to do so, and do so quite successfully.</p>
<p>I myself record my business as a series of Excel documents (Invoices, Timesheets, Expenses) in a set of folders (Financial Years subdivided into major customers).  Essentially a <a class="zem_slink" title="Document-oriented database" href="http://en.wikipedia.org/wiki/Document-oriented_database" rel="wikipedia">document-oriented database</a>.</p>
<p>In the past I simply then used a VBA powered workbook to open the required &#8220;documents&#8221; and extracted the data necessary for whatever report I required (VAT, year-end etc.).  To better automate (i.e. less bespoke VBA) this task I&#8217;ve have made changes to <a href="http://www.gobansaor.com/microetl">HAMMER</a> to help with this and with similar tasks for clients.</p>
<p>The following list of commands will be added to the next release of HAMMER. (In the meantime these new functions <a href="http://bit.ly/rss_example1">can be previewed here</a> &#8230;)</p>
<h2>LISTOFFILES</h2>
<p>This command takes a single argument, the folder to search, and will return a table of files in that folder and in any sub-folders. The result can then be used to select a list of files for further processing.</p>
<p>Example:</p>
<p>=HAMMER(&#8220;C:\a\rss&#8221;,&#8221;LISTOFFILES&#8221;)</p>
<p><a href="http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/listoffiles/" rel="attachment wp-att-2267"><img class="aligncenter size-full wp-image-2267" title="listoffiles" src="http://gobansaor.files.wordpress.com/2011/11/listoffiles.png?w=500&#038;h=93" alt="" width="500" height="93" /></a></p>
<h2>_XLTOJSONDOC</h2>
<p>This command takes a list of workbooks, opens each one, checks for a list of named ranges and generates a <a class="zem_slink" title="JSON" href="http://en.wikipedia.org/wiki/JSON" rel="wikipedia">JSON</a> document. The command is intended to be called from within a VBA macro (as opening and closing workbook breaks the &#8220;no side effects&#8221; rule of UDFs). Most &#8220;_&#8221; commands such as &#8220;_MD5&#8243; etc. are likewise intended for &#8220;programming use&#8221;, but any command beginning with &#8220;_XL&#8221; must be restricted to macro (i.e. non-UDF) use.</p>
<p>See the example workbook FetchInventory for an example of this function in action. The function takes one argument (the name of the document to load) and expects a table where the last column is the full name of the workbook to open. Any columns in the source table will be copied to the new &#8220;JSON document&#8221; table with an additional column called &#8220;Document&#8221; which will hold a JSON document representing the key-name pairs and table(s) extracted from the workbook.</p>
<p>On opening a workbook, it is searched for a named range with the name of document concatenated with &#8220;_fields&#8221; (e.g. INVENTORY_fields). The value of this range is expected to be a CSV list of fields and tables to load. A single Excel &#8220;document&#8221; could contain multiple logical documents (each specified by its own &#8220;_fields&#8221; list) .</p>
<p>See the PartsInventory_bin4 for an example of a multi-document workbook (INVENTORY and EXAMPLE). The EXAMPLE document in this workbook also demonstrates the various types of tables handled.</p>
<p>Example:</p>
<p>lJSONObjects = oHammer.HAMMER(&#8220;C:\a\rss\StockTake1&#8243;,&#8221;LISTOFFILES&#8221;,&#8221;Select name,fullname from table2 limit 1&#8243;,&#8221;SQL&#8221;,&#8221;INVENTORY&#8221;,&#8221;_XLTOJSONDOC&#8221;)</p>
<p>lReturn = oHammer.HAMMERToRange(lJSONObjects,&#8221;Sheet2!A27&#8243;)</p>
<p>&#8230; will output</p>
<p><a href="http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/documentrow/" rel="attachment wp-att-2270"><img class="aligncenter size-full wp-image-2270" title="documentrow" src="http://gobansaor.files.wordpress.com/2011/11/documentrow.png?w=500&#038;h=72" alt="" width="500" height="72" /></a></p>
<h2>JSONDOCVIEW</h2>
<p>This command is where the previous commands are leading to, i.e. extracting some real information value from your documents. It converts JSON documents into Excel friendly tables. It is, in essence, a Map function as in <a href="http://en.wikipedia.org/wiki/MapReduce">MapReduce</a>. In a previous example I used a <a href="http://blog.gobansaor.com/2011/05/05/excel-document-oriented-database-with-python-map-sql-reduce/">Python Map and a SQL Reduce</a>, here, both Map and Reduce are via SQL (the command uses a series of SQL commands to perform its task).</p>
<p>Before I describe the function let me explain why I use an intermediate JSON format. I could just extract the data directly from each document and either store directly in Excel or create tables in SQLite of Access to hold this data. And in fact, that&#8217;s what I would have done in the past (see<a href="http://blog.gobansaor.com/2010/03/02/excel-as-a-document-oriented-nosql-database/">Excel as a document-oriented NoSQL database</a>). Now , however, I tend to favour using a free-format (i.e. no need for a fixed database schema) structure like a JSON document, so as the source documents evolve over time (which tends to happen not just during design stages but as the system matures) this will not break older documents.</p>
<p>So, for example, original Invoice workbooks might not have a backing time-sheet while newer Invoices do. As long as new and old documents share a core sub-set of data fields they can continue to be analysed together.</p>
<p>The command takes 5 arguments and a driving table (a record so far for HAMMER commands, most have a max of two arguments). The driving table&#8217;s last column is assumed to contain the JSON document to process, columns prior to this (if any) will be output unchanged for each resulting row.</p>
<p>The first argument specifies the name of the &#8220;inner&#8221; table to fetch (if any). Most real life documents consist of header details (the &#8220;outer&#8221;document) and one or more tables (&#8220;inner&#8221; details). Invoices, time-sheets,  stock-takes, all tend to follow this pattern. This command will effectively join each document&#8217;s outer details to a single inner table (if more than 1 inner table, a call for each one is required).</p>
<p>The second (field list in SQL format) and third (<a href="http://en.wikipedia.org/wiki/Where_(SQL)#Predicates">SQL where predicate format</a>) arguments specify what inner fields to extract (if blank, then all) and what restrictions to impose (if any). So &#8220;InvNo, Date&#8221;,&#8221;InvNo &gt; 12&#8243; would only fetch documents where the InvNo &gt; 12 and only include the InvNo and Date fields.</p>
<p>The fourth and fifth arguments do the same for the outer table (i.e. Header data).</p>
<p>If any of the columns specified  (inner or outer) can not be found, or if the predicates (inner or outer) result in no selection, no error is returned, the document simply returns no rows. Likewise if an inner table is specified and no such table exists, then no rows are returned for that document &#8211; in other words this is not an outer join, which is not usually a problem as in most cases a &#8220;header&#8221; without detail lines is meaningless. If an outer join is required, then extract the headers (outers) and details (inner tables(s)) separately and join using SQL.</p>
<p>Example:</p>
<p>=HAMMER(&#8220;Select Name,FullName,Document from invoice_docs&#8221;,&#8221;SQL&#8221;,&#8221;table_2&#8243;, &#8220;[PART NUMBER],QTY&#8221;, &#8220;QTY &gt;30&#8243;, &#8220;Bin_Number&#8221;, &#8220;Bin_Number &gt; 1&#8243;, &#8220;JSONDOCVIEW&#8221;)</p>
<p>would result in:</p>
<p><a href="http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/jsonview/" rel="attachment wp-att-2271"><img class="aligncenter size-full wp-image-2271" title="jsonview" src="http://gobansaor.files.wordpress.com/2011/11/jsonview.png?w=500&#038;h=64" alt="" width="500" height="64" /></a></p>
<p>For more complex JSON objects use the <a href="http://blog.gobansaor.com/2011/08/14/hammer-inside/">JSON command</a> to incrementally parse the text or use the VBA JSON module within<a href="http://www.gobansaor.com/microetl"> microETL</a>. But for most situations (especially if you control the expected format) JSONDOCVIEW should handle it.</p>
<p>As JSON is fast becoming the preferred transport format for web and mobile applications having the ability to parse and produce JSON form within Excel is very useful. It is possible, for example, to use a simple web technology such as <a href="http://bit.ly/jsonwidget">http://robla.net/jsonwidget/</a> to craft another type of Really Simple System. This time with the collection happening on the web (most likely using <a href="http://aws.amazon.com/articles/1434">AWS S3 pre-signed forms</a>, so no HTML server required &#8211; keep it simple) but with the control and reporting remaining within Excel (a variation on my<a href="http://blog.gobansaor.com/2011/03/16/steam-powered-powerpivot/"> Steam Powered Server</a> idea).</p>
<p>For an example of a <a href="http://bit.ly/rss_example1">really simple system  download this</a>.</p>
<p><a href="http://blog.gobansaor.com/2011/11/22/powerpivot-vba-refesh-code-bug-fix/">Latest version of HAMMER including the above commands now released &#8230;</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2264/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2264&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/11/book_of_record.jpg" medium="image">
			<media:title type="html">book_of_record</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/11/listoffiles.png" medium="image">
			<media:title type="html">listoffiles</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/11/documentrow.png" medium="image">
			<media:title type="html">documentrow</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/11/jsonview.png" medium="image">
			<media:title type="html">jsonview</media:title>
		</media:content>
	</item>
		<item>
		<title>HAMMER Alongside, as a COM Server</title>
		<link>http://blog.gobansaor.com/2011/10/07/hammer-alongside-as-a-com-server/</link>
		<comments>http://blog.gobansaor.com/2011/10/07/hammer-alongside-as-a-com-server/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 16:09:00 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[.NET Com Server]]></category>
		<category><![CDATA[PowerPivot ETL]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2242</guid>
		<description><![CDATA[Although it has always been possible to call HAMMER from within VBA via the Application.Run method, this is a somewhat clunky way of doing so and it can also be very inefficient, particularly for tight loops. But now, with this release &#8230; <a href="http://blog.gobansaor.com/2011/10/07/hammer-alongside-as-a-com-server/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2242&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2011/10/07/hammer-alongside-as-a-com-server/alongside_clear/" rel="attachment wp-att-2244"><img class="alignleft size-medium wp-image-2244" title="Alongside_clear" src="http://gobansaor.files.wordpress.com/2011/10/alongside_clear.png?w=225&#038;h=300" alt="" width="225" height="300" /></a>Although it has always been <a href="http://blog.gobansaor.com/2011/07/18/vba-multithreading-net-integration-via-hammer/">possible to call HAMMER from within VBA</a> via the Application.Run method, this is a somewhat clunky way of doing so and it can also be very inefficient, particularly for tight loops. But now, with this release (V 1.2.0 (Beta) ) core functionality is exposed as a COM Server, which means easier and more efficient interfacing between VBA and the .NET multi-threaded enabled world of the datasmith&#8217;s HAMMER.</p>
<p>I call this &#8220;HAMMER Alongside&#8221;, to differentiate it from <a href="http://blog.gobansaor.com/2011/08/14/hammer-inside/">HAMMER Inside</a> where I use HAMMER internals to craft stand alone XLLs. With this COM Server method, the standard HAMMER add-in (installed or just-in-time registered) is needed alongside either a VBA add-in or a VBA enabled workbook. The extra &#8220;moving parts&#8221; are easily justified by the extra flexibility that this method allows (particularly to those with a reasonable grasp of VBA, but perhaps lacking any familiarity with the .NET world).</p>
<p>By learning a small amount of IronPython (<a href="http://www.ironpython.info/index.php/Main_Page">here&#8217;s a good starting place</a>) it&#8217;s relatively easy to hook up VBA to any .NET library through HAMMER, without having to invest time and money in learning heavy duty development environments such as Visual Studio. Using <a href="http://blog.gobansaor.com/2011/06/17/hammer-and-threads/">&#8220;Internal Threads</a>, it&#8217;s also possible to take advantage of .NETs multi-threading capability from VBA. (Note: both these options require .NET4).</p>
<p>So with VBA becoming a first-class language with regards to HAMMER, why offer Python as an alternative scripting choice? Well, one reason is to offer a means to access .NET&#8217;s power as per the last paragraph. But, the primary reason, is related to the ability of HAMMER transformations to be &#8220;detached&#8221; from Excel and run via HAMMER&#8217;s command line tools. The .NET 4 version of the command line tool supports Python, so it is possible to initially build out a micro-ETL transformation within Excel (using Python to perform the business logic alongside SQL) and then transfer that logic to the command-line tools with a minimum of modification.</p>
<p>This could be useful , for example, when a PowerPivot model moves to the server, its related HAMMER-powered micro-ETL processing could do likewise (most enterprise ETL tools support call-outs to command-line processes).</p>
<p>The <a class="zem_slink" title="Component Object Model" href="http://en.wikipedia.org/wiki/Component_Object_Model" rel="wikipedia">COM server</a> can be accessed from VBA only via late-binding like so:</p>
<p style="padding-left:30px;"><span class="Apple-style-span" style="font-size:14px;line-height:23px;">Set comServ = CreateObject(&#8220;hammerCOMServerV1&#8243;)</span></p>
<p>The server&#8217;s methods are:</p>
<ul>
<li>hammer(&#8230;) &#8211; works the same way as the UDF version.</li>
<li>hammerVersion() &#8211; returns HAMMER version, again the same as UDF version.</li>
<li>hammerVersionOK(version) &#8211; e.g.  isOK= comServ.hammerVersionOK(120) will return TRUE if the current version is &gt;= V1.2.0</li>
<li>arrayResize(anArray) enables the creation of &#8220;toFit&#8221; UDFs.</li>
<li>arrayToSheet(anArray) likewise for &#8220;toSheet&#8221; UDFs.</li>
<li>arrayToRange(anArray,pasteToWhereString)<a href="http://blog.gobansaor.com/2011/10/04/hammer-on-the-range/"> enables &#8220;toRange&#8221; UDF</a>s.</li>
<li>hammer_ppRefresh_inline(optional table,optional timeout) &#8211; refreshes a PowerPivot model, again the same as its UDF equivalent.</li>
</ul>
<p><span class="Apple-style-span" style="color:#444444;font-size:14px;line-height:23px;"><a href="http://www.gobansaor.com/microetl">Download the latest version of HAMMER from here &#8230;</a></span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2242/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2242/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2242/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2242/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2242/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2242/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2242/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2242/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2242/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2242/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2242/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2242/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2242/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2242/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2242&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/10/07/hammer-alongside-as-a-com-server/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/10/alongside_clear.png?w=225" medium="image">
			<media:title type="html">Alongside_clear</media:title>
		</media:content>
	</item>
		<item>
		<title>HAMMERing away at Automated PowerPivot Refresh</title>
		<link>http://blog.gobansaor.com/2011/09/09/hammering-away-at-automated-powerpivot-refresh/</link>
		<comments>http://blog.gobansaor.com/2011/09/09/hammering-away-at-automated-powerpivot-refresh/#comments</comments>
		<pubDate>Fri, 09 Sep 2011 16:49:01 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[Denali CTP3]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[Automate PowerPivot]]></category>
		<category><![CDATA[XMLA]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2104</guid>
		<description><![CDATA[See below for an updated version of the VBA code that automates the refresh of PowerPivot models. Having spent the last week delving deeper into the process I&#8217;ve made a few changes. The original code doesn&#8217;t work if more than &#8230; <a href="http://blog.gobansaor.com/2011/09/09/hammering-away-at-automated-powerpivot-refresh/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2104&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://gobansaor.wordpress.com/2011/09/09/hammering-away-at-automated-powerpivot-refresh/code-spelunking/" rel="attachment wp-att-2106"><img class="alignleft size-medium wp-image-2106" title="Delving Deep into PowerPivot Refresh" src="http://gobansaor.files.wordpress.com/2011/09/code-spelunking.png?w=300&#038;h=233" alt="" width="300" height="233" /></a>See below for an updated version of the VBA code that automates the refresh of PowerPivot models. Having spent the last week delving deeper into the process I&#8217;ve made a few changes.</p>
<p>The original code doesn&#8217;t work if more than one PowerPivot model is opened; the new method uses a combination of DMV (tabular views of AS engine&#8217;s metadata) Sessions and Object Activity (in particular  looking for &#8216;Permissions&#8217; issued to a workbook&#8217;s sessions).</p>
<p>I&#8217;ve also allowed for a single table refresh. Again, this required some more DMV queries to determine the DimensionID associated with the table.</p>
<p>Excel linked tables can be refreshed (i.e. the <a class="zem_slink" title="XML for Analysis" href="http://en.wikipedia.org/wiki/XML_for_Analysis" rel="wikipedia">XMLA</a> will run OK) but it has no effect, as this doesn&#8217;t trigger a fetch of new data from the workbook. To automate linked table refreshes means using the dreaded SendKeys, nasty, but works after a fashion.</p>
<p>Another interesting observation, the refresh operation works fine without the PowerPivot add-in being enabled (but the associated DLLs would have been still visible and presumably used). Not sure what use that knowledge is, but interesting none the less.</p>
<p>So far so good, seems to be working; but <a href="http://blog.gobansaor.com/2011/09/01/automating-powerpivot-refresh-operation-from-vba-the-code/#comment-7316">as Marco pointed out, this is not supported </a> (but is documented and would be perfectly valid to use against a &#8216;normal&#8217; AS model). So, test, test again and make sure you have a backup of any important workbooks.</p>
<p>I&#8217;ve also managed to get the code working in VB.NET and have ported it into my <a href="http://www.gobansaor.com/microetl">HAMMER micro ETL tool</a>. In fact, having the ability to quickly and easily fetch and render DMV views using HAMMER helped enormously in identifying what DMV queries would help with the multi-model and DimensionID problems.</p>
<p>The xll (a 32bit and a 64bit version) of the next HAMMER release is included alongside the sample workbook (go to Hammer sheet and press &#8220;Enable HAMMER&#8221; button, or use the setup xls if you wish to install). You&#8217;ll need .NET 4 to run this version of HAMMER.</p>
<p>I&#8217;ve tested against Denali CPT3  (but should work with PowerPivot V1) XP SP3 32bit; 64 bit should work too (let me know if not).</p>
<p>To enable actions such as PowerPivot refreshes (which require access to the Excel Object model) I&#8217;ve made a few breaking changes and added some new commands.</p>
<ul>
<li>BREAKING CHANGE, the main HAMMER function is no longer thread enabled (accessing the Excel Object model from within a threading UDF is not to be recommended). If you&#8217;re sure you&#8217;re thread-safe use the hammerThreadEnabled function, if you don&#8217;t know what I&#8217;m talking about, don&#8217;t <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  <a href="http://blog.gobansaor.com/2011/06/17/hammer-and-threads/">Internal Threads</a> are not affected by this.</li>
<li>BREAKING CHANGE, commands are now case-senstive, nothing really to do with the PowerPivot changes, just something I&#8217;ve been meaning to do for sometime.</li>
<li>PPCONNECTION (New command) &#8211; will set up an ADODB connection within HAMMER to enable ADO queries against PowerPivot DMVs. Once established can  be used by subsequent HAMMER calls.</li>
<li>ADOCONECTION (New Command) &#8211; like above but for any ADODB connection, requires a valid connection string. Also, once established, can  be used by subsequent HAMMER calls.</li>
<li>ADO (Modified Command) &#8211; can still use a connection string for once-off connections but if  an ADOCONNECTION is in force will use that instead.</li>
<li>HAMMER_ppREFRESH (New Helper function) &#8211; spawns a background thread to refresh the PowerPivot model and refresh associated pivots. Background thread may be still be running when function returns. Takes two optional arguments, table (if a single refresh is required) and timeout (in seconds, to allow for long running refresh).</li>
<li> HAMMER_ppREFRESH_inline (New Helper function) &#8211; like above but operates as a normal UDF, will not return until action is complete. In theory breaks the UDF no-side-effects rule, but appears to work fine! Also, this is the function to use if calling via VBA&#8217;s Application.Run command.</li>
<li>PPREFRESH (New command) &#8211; performs a PowerPivot model refresh but doesn&#8217;t do a connection refresh.  Main use-case is for use within VBA code to allow for finer control.</li>
</ul>
<p><a href="http://www.gobansaor.com/excel-based-bi">Download the latest Power Pivot refresh code.</a></p>
<div><strong><span style="font-size:x-small;">For the latest versions and articles on HAMMER follow the <a href="http://blog.gobansaor.com/category/hammer/" rel="nofollow">HAMMER tag</a> on my blog &#8230;</span></strong></div>
<div><span style="font-size:xx-small;"><span class="Apple-style-span" style="line-height:17px;"><strong><br />
</strong></span></span></div>
<div><span style="font-size:x-small;"><strong><a href="http://bit.ly/datasmith" rel="nofollow">To download the latest version of HAMMER, use this link</a>.</strong></span></div>
<div><span style="font-size:xx-small;"><span class="Apple-style-span" style="line-height:17px;"><strong><br />
</strong></span></span></div>
<div><span style="font-size:x-small;"><strong><a href="http://www.gobansaor.com/hammer" rel="nofollow">To see a list of commands implemented by HAMMER see here.</a></strong></span></div>
<div></div>
<div><a href='http://twitter.com/gobansaor' class='twitter-follow-button' data-text-color='#333333' data-link-color='#0060ff'>Follow @gobansaor</a></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2104/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2104&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/09/09/hammering-away-at-automated-powerpivot-refresh/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/09/code-spelunking.png?w=300" medium="image">
			<media:title type="html">Delving Deep into PowerPivot Refresh</media:title>
		</media:content>
	</item>
		<item>
		<title>Automating PowerPivot Refresh operation from VBA &#8211; The Code</title>
		<link>http://blog.gobansaor.com/2011/09/01/automating-powerpivot-refresh-operation-from-vba-the-code/</link>
		<comments>http://blog.gobansaor.com/2011/09/01/automating-powerpivot-refresh-operation-from-vba-the-code/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 12:59:02 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[Automate PowerPivot from VBA]]></category>
		<category><![CDATA[PowerPivot Refresh]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2079</guid>
		<description><![CDATA[In my last post I explained how I &#8216;d managed to automate the refresh of a PowerPivot model from within VBA. The example workbook below contains the test  code I used and a PowerPivot model based on two CSV files. &#8230; <a href="http://blog.gobansaor.com/2011/09/01/automating-powerpivot-refresh-operation-from-vba-the-code/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2079&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://gobansaor.wordpress.com/2011/09/01/automating-powerpivot-refresh-operation-from-vba-the-code/the-code/" rel="attachment wp-att-2085"><img class="alignleft size-full wp-image-2085" title="The Code" src="http://gobansaor.files.wordpress.com/2011/09/the-code.jpg?w=500" alt=""   /></a><a href="http://blog.gobansaor.com/2011/08/31/automating-powerpivot-refresh-operation-from-vba/">In my last post I explained how I &#8216;d managed to automate the refresh of a PowerPivot model from within VBA</a>. The example workbook below contains the test  code I used and a PowerPivot model based on two CSV files.</p>
<p>To try it out you&#8217;ll need to generate the CSV files first  and then adjust the Text connections within the PowerPivot model to point at your default Excel folder (usually MyDocuments).</p>
<p>This was developed against the latest PowerPivot CTP3 release, under XP SP3</p>
<p><del>Download the example workbook from here &#8230;  </del>UPDATE: <a href="http://blog.gobansaor.com/2011/09/09/hammering-away-at-automated-powerpivot-refresh/">New version of code available here &#8230;</a></p>
<a href='http://twitter.com/gobansaor' class='twitter-follow-button' data-text-color='#333333' data-link-color='#0060ff'>Follow @gobansaor</a>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2079/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=2079&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/09/01/automating-powerpivot-refresh-operation-from-vba-the-code/feed/</wfw:commentRss>
		<slash:comments>50</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/09/the-code.jpg" medium="image">
			<media:title type="html">The Code</media:title>
		</media:content>
	</item>
		<item>
		<title>VBA Multithreading, .NET integration via HAMMER</title>
		<link>http://blog.gobansaor.com/2011/07/18/vba-multithreading-net-integration-via-hammer/</link>
		<comments>http://blog.gobansaor.com/2011/07/18/vba-multithreading-net-integration-via-hammer/#comments</comments>
		<pubDate>Mon, 18 Jul 2011 17:00:22 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[IronPython]]></category>
		<category><![CDATA[Threads]]></category>
		<category><![CDATA[VBA .NET integration]]></category>
		<category><![CDATA[VBA Multithreaded]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=1978</guid>
		<description><![CDATA[In a previous post I urged all potential datasmiths to learn a scripting language (I suggested Python). But what of VBA, the granddaddy of the scripting world? Well yes, if you have a need to automate Excel then you must learn &#8230; <a href="http://blog.gobansaor.com/2011/07/18/vba-multithreading-net-integration-via-hammer/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1978&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2011/07/18/vba-multithreading-net-integration-via-hammer/vbaxl/" rel="attachment wp-att-1979"><img class="alignleft size-full wp-image-1979" title="vbaXL" src="http://gobansaor.files.wordpress.com/2011/07/vbaxl.png?w=500" alt=""   /></a>In a<a href="http://blog.gobansaor.com/2011/06/29/those-with-a-datasmiths-hammer-see-every-problem-as-a-table/"> previous post</a> I urged all potential datasmiths to learn a scripting language (I suggested Python). But what of VBA, the granddaddy of the scripting world? Well yes, if you have a need to automate Excel then you must learn VBA. VBA is to Excel as JavaScript is to the modern browser, its tight integration with Excel&#8217;s Object Model and its superb debugging facilities makes it the optimal choice for automating Excel.</p>
<p>VBA is now a one trick pony (Office automation), but Python opens all sorts of API scripting and product automation doors. My use of <a class="zem_slink" title="IronPython" href="http://ironpython.net/" rel="homepage">IronPython</a> as HAMMER&#8217;s scripting language is one such door, a door to the otherwise mainly-closed-to-VBA world of multi-threading and easy .NET library integration.</p>
<p>The HAMMER function can be called from VBA using the Application.Run command like so&#8230;</p>
<p><em>retArray = Application.Run(&#8220;DATASMITH.HAMMER&#8221;,inArray,&#8221;Select dept,count(*) from table1&#8243;,&#8221;SQL&#8221;)</em></p>
<p>&#8230; the 1st parameter is the function name, parameter two is the 1st argument to the function, parameter three is the 2nd and so on.</p>
<p>By utilising HAMMER&#8217;s IronPython functionality (requires NET 4.0 runtime), VBA routines can access the full power of the <a class="zem_slink" title=".NET Framework" href="http://msdn.microsoft.com/netframework" rel="homepage">.NET platform</a> with data passed back and forth using tables. Admittedly for many complex .NET utilities utilising VB.NET or C# may be a better approach (due to better IDE and debugging features of such languages) but for standard library calls, IronPython is an ideal option. It also has the benefit that the &#8220;code&#8221; can be stored within the workbook.</p>
<p>HAMMER also offers the power of multi-threading to VBA via its<a href="http://blog.gobansaor.com/2011/06/17/hammer-and-threads/"> internal threading functionality</a> (requires Excel &gt;= 2007 and Net4.0 runtime). The multi-threading example in the hammerThreads.xlsx workbook could easily be wrapped in VBA code, perhaps to allow it to be controlled by a user-form.</p>
<p>I&#8217;ve added two new commands specially designed for use within VBA scripted HAMMER scenarios:</p>
<ul>
<li>APPDB &#8211; Opens an application-wide shared in-memory database. This will allow tables (and Python objects) created in one function call to be accessible in an other function call (assuming both issue the APPDB command as their 1st command). This replicates the functionality of microETL which by default exposes a application-wide SQLite in-memory instance and a common Python workspace.</li>
<li>CLOSEAPPDB &#8211; This will close and clear the shared c#-SQLite and IronPython instances. Equivalent of microETL&#8217;s xLiteReset() function.</li>
</ul>
<p>Be careful not to&#8230;</p>
<ul>
<li>use the APPDB instance from in-cell UDF calls to HAMMER that are likely to be scheduled as multi-threaded (the helper functions HammerToSheet &amp; HammerToFit are safe, as they are always single-threaded),</li>
<li>or use within &#8220;internal threaded&#8221; HAMMER commands</li>
</ul>
<p><span class="Apple-style-span" style="color:#444444;font-family:Georgia, 'Bitstream Charter', serif;font-size:14px;line-height:23px;">&#8230;as although c#-SQLite is thread safe, the implementation logic is not.</span></p>
<p><a href="http://www.gobansaor.com/hammer">Here’s a list of the HAMMER commands implemented so far …</a></p>
<p><a href="http://bit.ly/datasmith">You can download the latest version of HAMMER here …</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/1978/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/1978/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/1978/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/1978/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/1978/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/1978/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/1978/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/1978/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/1978/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/1978/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/1978/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/1978/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/1978/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/1978/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1978&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/07/18/vba-multithreading-net-integration-via-hammer/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/07/vbaxl.png" medium="image">
			<media:title type="html">vbaXL</media:title>
		</media:content>
	</item>
		<item>
		<title>SQL noSQL no Python no VBA.</title>
		<link>http://blog.gobansaor.com/2011/06/20/sql-nosql-no-python-no-vba/</link>
		<comments>http://blog.gobansaor.com/2011/06/20/sql-nosql-no-python-no-vba/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 19:13:23 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[microETL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[noVBA]]></category>
		<category><![CDATA[SQLite Excel]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=1848</guid>
		<description><![CDATA[I&#8217;ve uploaded another version of HAMMER; this adds some new features and also takes some away. The removed features are Python and multi-threading support from the 2003 version of the add-in. Calling it the 2003 version isn&#8217;t entirely accurate (it&#8217;s actually called &#8230; <a href="http://blog.gobansaor.com/2011/06/20/sql-nosql-no-python-no-vba/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1848&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2011/06/20/sql-nosql-no-python-no-vba/thor-clear/" rel="attachment wp-att-1850"><img class="alignleft size-full wp-image-1850" title="Thor-clear" src="http://gobansaor.files.wordpress.com/2011/06/thor-clear.png?w=500" alt=""   /></a>I&#8217;ve uploaded another version of HAMMER; this adds some new features and also takes some away. The removed features are Python and multi-threading support from the 2003 version of the add-in. Calling it the 2003 version isn&#8217;t entirely accurate (it&#8217;s actually called datasmith-noPython.xll) as this version will also work for Excel 2007/2010 32bit and for older versions (maybe even &#8217;97!). It should really be called the .NET 2.0 version as the features removed from this version depend on the NET 4.0 runtime (IronPython 2.7 and multi-threading). I&#8217;ll eventually build a .NET4 version for Excel 97-2003 with Python included, but this will still be missing the multi-threading features.</p>
<p>So, the version that the setup.xls will install if it detects a sub-2007 version of Excel, will offer<strong> SQL</strong> and <strong>noSQL</strong> (JOIN,UNION etc.) but <strong>no Python</strong> or <strong>multi-threading</strong>.</p>
<p>So what about new features? <a href="http://blog.gobansaor.com/2010/03/02/excel-as-a-document-oriented-nosql-database/">Excel being the original noSQL  database</a>, I continue to add more noSQL commands for those who wish to avoid SQL or find its syntax somewhat long-winded. The JOIN  &amp; LOJOIN (outer join) commands are good examples, simply load two tables with the column names that you wish to join on, sharing the same names, simple.  Another example is the REDUCE (aka GROUPBY aka DISTINCT) command I&#8217;ve added this version. It essentially performs a SELECT &#8230; FROM &#8230; GROUP BY; again load or generate a table, then follow with a list of the columns you wish to &#8216;reduce&#8217; the table by, plus any aggregates you wish to perform. Examples:</p>
<ul>
<li>=HAMMER(myHugeList,&#8221;dept,sum(overtime)&#8221;,&#8221;REDUCE&#8221;)</li>
<li>=HAMMER(AccessLogs!A1:C9999,&#8221;areaAccessed,byWhom&#8221;,&#8221;REDUCE&#8221;)</li>
<li>=HAMMER(invHead,invLine,&#8221;JOIN&#8221;,&#8221;count(invID),sum(netAmt)&#8221;,&#8221;REDUCE&#8221;)</li>
</ul>
<p><span class="Apple-style-span" style="font-size:14px;line-height:23px;">If noSQL is not your cup of tea and you wish to utilise the full power of a SQL database; a new command &#8220;OPENDB&#8221; will allow you to open an existing (or create a new) SQLite database file. This will allow SQLite data sources to be accessed and written to via standard in-cell formula, no VBA required! The command expects the previous argument to be the database name. If no such argument exists it will create a temporary on-disk database. This command usually only makes sense as the 1st command as it&#8217;ll close and wipe any previously opened databases. If no &#8220;OPENDB&#8221; command is issued (i.e. the default) an in-memory database (aka :memory:)  is used . Examples:</span></p>
<ul>
<li>=HAMMER(&#8220;C:\data\myDB.db&#8221;,&#8221;OPENDB&#8221;,A10:C:9910) will copy the data for range A10:C9910 and save in a table called table3 in the myDB.db SSQLite database.</li>
<li>=HAMMER(&#8220;C:\data\myDB.db&#8221;,&#8221;OPENDB&#8221;,&#8221;SELECT * from table3&#8243;) will fetch the same data back into Excel.</li>
</ul>
<p><span class="Apple-style-span" style="font-size:14px;line-height:23px;">Wow steady on, what if there&#8217;s a need to store or fetch data from disk without using SQLite? No problem, use the &#8220;TOCSV&#8221; command, outputs the last table loaded or generated in CSV format to the file name specified. (There&#8217;s also a &#8220;SQLTOCVS&#8221; command which expects a SQL statement to specify the data to extract followed by the file name to extract to).</span></p>
<p><span class="Apple-style-span" style="font-size:14px;line-height:23px;">Two other commands &#8220;CSV&#8221; and &#8220;TSV&#8221; will load comma and tab separated data into HAMMER.  Although the CSV functionality is useful within Excel, the main driver for these command is to enable HAMMER to work outside Excel as a command-line data processor; you heard it here first folks! </span></p>
<p><span class="Apple-style-span" style="font-size:14px;line-height:23px;">I&#8217;ve also added the 1st set of my helper functions, these two functions are only available in the 2007/2010 versions as they use multi-threading. The two functions are:</span></p>
<ul>
<li>hammerToFit &#8211; wraps HAMMER, but will auto-resize the array area (or create a brand new array-selection if none) to fit the returned table. Note: to achieve this, the HAMMER function will be called twice if the existing array area needs adjusting.</li>
<li>hammerToSheet &#8211; again wraps HAMMER, but will paste the resulting table to a new sheet.</li>
</ul>
<p><span class="Apple-style-span" style="font-size:14px;line-height:23px;">Although both helper functions utilise threads to achieve these little tricks (hence they&#8217;re not available sub-2007) when HAMMER functionality is called via these wrappers the function operates as a single threaded function &#8211; there&#8217;s a good reason for this which I&#8217;ll explain some other time.<a href="http://blog.gobansaor.com/2011/06/17/hammer-and-threads/"> Internal HAMMER threading</a> does however still work.</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://www.gobansaor.com/hammer">Here’s a list of the HAMMER commands implemented so far …</a></p>
<p><a href="http://bit.ly/datasmith">Download the latest version of HAMMER here &#8230;</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/1848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/1848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/1848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/1848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/1848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/1848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/1848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/1848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/1848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/1848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/1848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/1848/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/1848/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/1848/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1848&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/06/20/sql-nosql-no-python-no-vba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/06/thor-clear.png" medium="image">
			<media:title type="html">Thor-clear</media:title>
		</media:content>
	</item>
		<item>
		<title>The Datasmith&#8217;s Hammer</title>
		<link>http://blog.gobansaor.com/2011/06/10/the-datasmiths-hammer/</link>
		<comments>http://blog.gobansaor.com/2011/06/10/the-datasmiths-hammer/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 17:47:38 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[microETL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[Excel MapReduce]]></category>
		<category><![CDATA[IronPython Excel]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=1782</guid>
		<description><![CDATA[Although my microETL add-in is very powerful, it can be a bit intimidating for those without a programming background. It was after all, designed for my needs primarily and being a professional programmer I tend to see the world from that perspective. &#8230; <a href="http://blog.gobansaor.com/2011/06/10/the-datasmiths-hammer/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1782&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2011/06/10/the-datasmiths-hammer/datasmithhammer/" rel="attachment wp-att-1788"><img class="alignleft size-full wp-image-1788" title="datasmithhammer" src="http://gobansaor.files.wordpress.com/2011/06/datasmithhammer.png?w=500" alt=""   /></a>Although my <a href="http://www.gobansaor.com/microetl">microETL</a> add-in is very powerful, it can be a bit intimidating for those without a programming background. It was after all, designed for my needs primarily and being a professional programmer I tend to see the world from that perspective. Hence microETL&#8217;s ability to forge vast and complex datasets in parallel to those of Excel; to share those datasets not just with Excel and VBA but also with the powerful tool that is <a class="zem_slink" title="CPython" href="http://en.wikipedia.org/wiki/CPython" rel="wikipedia">CPython</a>. But microETLs genesis was not as an all-powerful ETL tool but as means to quickly and accurately handle tabular data in Excel. The original xLite (which begat microETL) started out with just two functions, Join two tables or Left Outer Join two tables. That was it, but it was still useful.</p>
<p>I&#8217;ve been intending for some time to build an offshoot of microETL that would be less powerful but perhaps more approachable and have fewer moving parts. This week I finished it, still needs some more testing, but the basic product is in place. It&#8217;s a single file add-in (a .xll) , called DATASMITH. At its heart is a single function called HAMMER, there will be other helper functions that in the main will wrap the HAMMER function, but in essence it is the datasmith&#8217;s HAMMER.</p>
<p>If microETL is a datasmith&#8217;s forge or indeed a mirco-foundry,HAMMER is a datasmith&#8217;s everyday portable tool (with perhaps Excel as the anvil, and your CPUs as the fire?). Talking of CPUs; multi-core CPUs are now the norm and since version 2007, Excel can utilise such multi-cores. MicroETL being VBA-based cannot however take advantage of this, to do so requires an .xll add-in; another reason to build the HAMMER.</p>
<p>So what will this new functionality look like:</p>
<h4>Examples:</h4>
<p>=<strong>HAMMER(Invoices[#All],InvoiceLine[#All],&#8221;JOIN&#8221;)</strong></p>
<p>&#8230;will take the two ranges (you need the [#All] to pick-up the header and data sections of a 2007/2010 Excel Table) and join them using the columns with the same name as the join fields. The JOIN command expects the last two preceding arguments to be tables (aka arrays with a header line).</p>
<p>=<strong>HAMMER(&#8220;SALES&#8221;,DeptSales!A1:F2101,&#8221;SELECT * from table2 where dept=&#8217;:1&#8242;&#8221;,&#8221;SQL&#8221;)</strong></p>
<p>&#8230; the 1st argument is loaded as Arg(1) (:1 in SQL), the 2nd argument is loaded (being an array) into a table named<em> table2</em>; if they were the other way round, it would be<em> table1</em> and Arg(2). The 3rd argument is loaded as Arg(3) and the 4th is a command: SQL. SQL looks back at the preceding argument (Arg(3) in this case) and executes its contents as SQLite SQL. If the preceding argument was a table, it would expect to find a list of SQL statements for execution in the first column. The output of the last issued SELECT statement is then returned to Excel as an array.</p>
<p>=<strong>HAMMER(DeptTargets!A1:D20,DeptSales!A1:F2101,SalesTagetScript,&#8221;PYTHON&#8221;)</strong></p>
<p>&#8230;this is similar to the previous SQL example but this time the command is PYTHON which will execute the Python Script passed in via the command&#8217;s preceding argument. The script will most likely return a table to Excel, but it could also, if not the last argument, create a table associated with its position, in this case <em>table4</em>, which could then be accessed by subsequent PYTHON or SQL scripts.</p>
<p>Up to 25 arguments can be passed, the last table produced is returned to Excel (either via a load, which wouldn&#8217;t be terribly useful, or more likely as a result of a command such as JOIN, SQL or PYTHON). HAMMER functions can of course be nested and can also issue <a href="http://blog.gobansaor.com/2011/06/17/hammer-and-threads/">&#8220;internal&#8221; HAMMER requests</a>. The &#8220;flow&#8221; of commands is from left to right, with the preceding args usually setting the stage for subsequent commands. Alongside the all-powerful SQL and PYTHON commands, I&#8217;ll most likely add a set of &#8220;noSQL&#8221; offerings such as JOIN, LOJOIN (left-outer), DISTINCT, REDUCE (a SELECT .. GROUP BY&#8230; with PYTHON as the MAP?), UNION, INTERSECT. These will likely also be available through helper functions such as =JOIN(ThisTable,ThatTable).</p>
<p>Unlike microETL, there&#8217;s no persistence across function calls i.e. HAMMER will play by Excel&#8217;s Functions <strong><em>no-side-effects</em></strong> rule. Each call to a function will build up and tear down its in-memory SQLite environment (including calls to HAMMER from within PYTHON).(UPDATE: Specify the 1st COMMAND as &#8220;APPDB&#8221; to simulate microETL&#8217;s persistence across function calls) <del> Likewise each call to PYTHON will be a separate engine instance</del>. Likewise each call to a HAMMER function will create its own PYTHON engine. Tables  and Python artefacts created by prior &#8220;steps&#8221; in a single HAMMER call are available to subsequent steps.</p>
<p>HAMMER embeds Python under the guise of <a class="zem_slink" title="IronPython" href="http://ironpython.net/" rel="homepage">IronPython</a>, so a lot of the power and speed of CPython will not be available, but on the other hand, the full power of the .NET CLR will be, not a bad swap.</p>
<p>And a huge advantage, HAMMER will be an asynchronous function (i.e. will run in its own thread). This will allow multiple long running transforms to be handled within the same Excel instance, a major shortcoming of microETL. This requires Excel 2007 or 2010, but will still work synchronously for Excel 97-2003. Having said that, there&#8217;s a requirement for Net4.o for IronPython so this add-in is more suited for modern versions of Excel and for OS &gt;= XP SP3.</p>
<p>HAMMER is <a href="http://office.microsoft.com/en-us/excel-help/introducing-array-formulas-in-excel-HA001087290.aspx">an array function</a>, yeah I know, normal folk tend to steer clear of Excel arrays. Which is to be expected, they&#8217;re not the most intuitive end-user-facing construct that the industry has ever come up with. But, they are the &#8220;Excel way&#8221; for passing tables in and out of formulas and, once mastered, open up a new world of power to Excel users. I will be adding helper functions to make using arrays a bit easier (an autoSize wrapper function, that&#8217;ll resize the selection area if it&#8217;s too small or too big, at the cost of a 2nd pass at the enclosed functions, might also port microETL&#8217;s SQL &#8220;paste&#8221; functionality).</p>
<p><del>I had intended to have an example to download with this post, but have discovered a last-minute bug that needs fixing. So it&#8217;ll be most likely next week before I&#8217;ve a version to show.</del></p>
<p>UPDATE:</p>
<p>I&#8217;ve managed to sort out the bug, so here&#8217;s an example&#8230;</p>
<p><a href="http://bit.ly/datasmith">http://bit.ly/datasmith</a></p>
<p><a href="http://www.gobansaor.com/hammer">Here’s a list of the HAMMER commands implemented so far …</a></p>
<p>Use setup.xls to install (or simply open in Excel), see IrelandFOIexample_hammer (2007/2010) for examples (there&#8217;s also a copy of the same functionality via microETL in IrelandFOIexample_microETL.xls &#8211; note the speed difference).  There&#8217;s Excel 2007/2010 32bit and  Excel 2010 64bit versions included and there&#8217;s also an un-tested 2003 version.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/1782/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/1782/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/1782/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/1782/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/1782/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/1782/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/1782/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/1782/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/1782/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/1782/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/1782/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/1782/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/1782/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/1782/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1782&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/06/10/the-datasmiths-hammer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/06/datasmithhammer.png" medium="image">
			<media:title type="html">datasmithhammer</media:title>
		</media:content>
	</item>
		<item>
		<title>Data Wrangler</title>
		<link>http://blog.gobansaor.com/2011/06/04/data-wrangler/</link>
		<comments>http://blog.gobansaor.com/2011/06/04/data-wrangler/#comments</comments>
		<pubDate>Sat, 04 Jun 2011 13:57:29 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[Ireland]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[microETL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[data wrangler]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=1754</guid>
		<description><![CDATA[A few weeks ago I came across (thanks to @lismiss) Data Wrangler; a very promising data cleansing tool from the Stanford Visualization Group. Not only is Data Wrangler a web-service (which the group intend to open source) but it also allows transformations to &#8230; <a href="http://blog.gobansaor.com/2011/06/04/data-wrangler/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1754&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2011/06/04/data-wrangler/data-wrangler/" rel="attachment wp-att-1755"><img class="alignleft size-full wp-image-1755" title="data-wrangler" src="http://gobansaor.files.wordpress.com/2011/06/data-wrangler.jpg?w=500" alt=""   /></a>A few weeks ago I came across (thanks to <a href="http://www.twitter.com/lismiss">@lismiss</a>) <a href="http://vis.stanford.edu/wrangler/">Data Wrangler</a>; a very promising data cleansing tool from the <a href="http://vis.stanford.edu/">Stanford Visualization Group</a>. Not only is Data Wrangler a web-service (which the group intend to open source) but it also allows transformations to be &#8220;recorded&#8221; in either Python or JavaScript (<a href="http://vis.stanford.edu/wrangler/blog/2/">see here</a>). It was this Python scripting feature that really caught my attention; would be very useful to be able to hack away at a dataset using the service, then transfer the script to microETL&#8217;s PyScript to adjust and integrate with Excel and SQL.</p>
<p>The demo video and test datasets give a good overview of the tool but the proof of the pudding is in trying out some real world dirty data; I chose a fine example of the art of Freedom Of Information datasets, issued by a Republic of Ireland government department. As an example of how not to do something (unless your intention is to make the recipient regret asking for the FOI in the first place) this is excellent. (I suppose we should be grateful it&#8217;s in Excel not Word or PDF or even PowerPoint). You can download it here <a href="http://bit.ly/Ireland_FOI_example" target="_blank">http://bit.ly/Ireland_FOI_example</a> (the data as released is in the FOI sheet).</p>
<p>As I said, Data Wrangler is promising, but needs some more work (to be fair, the group warns it&#8217;s a work in progress). The tool choked on the FOI dataset, too many columns I think, so not ready for the real world yet but I&#8217;ll be keeping an eye on its progress. Don&#8217;t let my experience put you off, it looks more than capable of handling smaller but still quite messy datasets.</p>
<p>If you&#8217;ve downloaded my example workbook, you&#8217;ll see how I managed to cleanse the data using <a href="http://www.gobansaor.com/microetl">microETL&#8217;s</a> Python &amp; SQL scripting functionality (the PyScript is in the Python sheet, with the SQLScript in the Control sheet). I could have cleansed the data using pure Excel and some VBA  and perhaps I would have if this was a format requiring parsing on a regular basis; I could then save the transformation as a single file macro-enabled workbook, ideal for sharing, no need for add-ins etc. But it was a once-off, and even if it wasn&#8217;t, it&#8217;s quite likely the format supplied in answer to a subsequent FOI request would be different. This is the sort of work that microETL&#8217;s Python &amp; SQL scripting is designed for; quick and dirty data wrangling, but with the ability ro persist, and modify the resulting transformations if so required.</p>
<p>If you wish to try out this example, there&#8217;s<a href="http://bit.ly/microetl_latest"> a new version of microETL (Alpha1.08) available for download</a>. You&#8217;ll notice a new folder structure (the usual sub-folders are now under a single sub-folder call microETL) to make installation of the add-in somewhat neater; and there&#8217;s also a setup.xls that&#8217;ll do all the hard work of installing (and un-installing) the microETL add-in. Note: you still need to manually install Python 2.7 to enable the PyScript&#8217;ing functionality.</p>
<p style="text-align:left;padding-left:30px;"><a href="http://www.gobansaor.com?dw-post" target="_blank">If you need help with your Excel, ETL or  data cleansing tasks, I can help</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/1754/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/1754/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/1754/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/1754/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/1754/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/1754/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/1754/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/1754/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/1754/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/1754/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/1754/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/1754/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/1754/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/1754/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1754&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/06/04/data-wrangler/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/06/data-wrangler.jpg" medium="image">
			<media:title type="html">data-wrangler</media:title>
		</media:content>
	</item>
		<item>
		<title>Attach a SQLite database into Excel&#8217;s memory via microETL</title>
		<link>http://blog.gobansaor.com/2011/05/20/attach-a-sqlite-database-into-excels-memory-via-microetl/</link>
		<comments>http://blog.gobansaor.com/2011/05/20/attach-a-sqlite-database-into-excels-memory-via-microetl/#comments</comments>
		<pubDate>Fri, 20 May 2011 11:05:17 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[excel]]></category>
		<category><![CDATA[microETL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[SQLite Attach]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=1690</guid>
		<description><![CDATA[In my previous post I described the various methods of accessing SQLite databases from within Excel using microETL. Via comments on the post, Michael Römer suggested a change to how microETL loads into memory an external SQLite database (not only &#8230; <a href="http://blog.gobansaor.com/2011/05/20/attach-a-sqlite-database-into-excels-memory-via-microetl/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1690&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2011/05/20/attach-a-sqlite-database-into-excels-memory-via-microetl/datatool-clear-2/" rel="attachment wp-att-1692"><img class="alignleft size-medium wp-image-1692" title="datatool-clear" src="http://gobansaor.files.wordpress.com/2011/05/datatool-clear.png?w=210&#038;h=122" alt="" width="210" height="122" /></a>In <a href="http://blog.gobansaor.com/2011/05/11/accessing-sqlite-databases-from-excel-via-microetl/">my previous post</a> I described the various methods of accessing SQLite databases from within Excel using <a href="http://www.gobansaor.com/microetl">microETL</a>. Via comments on the post, Michael Römer suggested a change to how microETL loads into memory an external SQLite database (not only suggested, but also provided the C code changes to enable the change; thanks Michael).</p>
<p>The existing <em><strong>xLiteLoadUnLoad(filename[,unload]) </strong></em>function loads a SQLite file into &#8220;main&#8221; i.e. the primary database (which is usually a :memory: db) overwriting any existing data. Michael&#8217;s suggestion was to allow loading into another in-memory database with a different alias; thus keeping the main database intact but allowing the benefits of in-memory access to the externally attached database. This feature has now been added.</p>
<p>I&#8217;ve kept the existing<strong> xLiteLoadUnLoad</strong> as is, but added a new optional argument to the xLiteAttachDB function so.</p>
<ul>
<li><strong> <em><strong>xliteAttachDB(databaseName,alias)  </strong></em></strong><em>becomes</em><strong><em><strong> <em><strong>xliteAttachDB(databaseName,alias,[loadInMemory=False])</strong></em></strong></em></strong><em><em>. </em></em>The optional loadInMemory argument defaults to FALSE, so acts like the old version (i.e. issues a standard SQLite Attach statement). But if set to TRUE; the function will first Attach a &#8220;:memory: database&#8221; named as the<strong> alias</strong>, then will load the external database file into that in-memory database. Once this happens the on-disk database is not referenced, so any changes will not be reflected back to disk. To enable changes to be persisted to disk, I&#8217;ve added another new function&#8230;</li>
<li><strong>xLiteDBSaveAs(alias,outDatabaseFile)</strong> will save a copy of the database named <strong>alias</strong> (with could be &#8220;main&#8221; if you wished to backup the default in-memory database) to the file<strong> outDatabaseFile</strong>. I&#8217;ve also added a &#8230;</li>
<li><strong>xLiteDetachDB(alias) </strong>to issue a SQLite DETACH statement. You might ask why not simply use the SQL() function to issue DETACH (or indeed ATTACH) statements? Statements such as ATTACH/DETACH cannot be issued by the SQL() functions as its pre-processor (for table() functionality) wraps SQL statements in a SAVEPOINT (nested SQL transaction). You can however use the fastSQL() or xliteRawSQL() functions to issue such commands.</li>
</ul>
<p><span class="Apple-style-span" style="font-size:14px;line-height:23px;">There&#8217;s another (this time breaking) change to the SQLScript TIMER  (<a href="http://blog.gobansaor.com/2011/03/27/expand-excels-horizons-look-to-the-cloud/">see here &#8230;</a>) command. The existing function used an ActiveX control (the Internet Explorer control as a provider for JavaScript timer functionality); ActiveX controls do not work under 64bit Excel, so I&#8217;ve reverted back to using Application.OnTime as my timer mechanism. The breaking change is the 3rd argument, which previously expected a value indicating the number of thousands-of-a-second to wait, now it represents whole seconds.</span></p>
<p>To download the latest version see the <a href="http://www.gobansaor.com/microetl">http://www.gobansaor.com/microetl</a> page.</p>
<p><strong>Update:</strong></p>
<p>For another method of loading SQLite databases within Excel/VBA see my new .NET-centric micro ETL tool  <a href="http://blog.gobansaor.com/category/hammer/">http://blog.gobansaor.com/category/hammer/</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/1690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/1690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/1690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/1690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/1690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/1690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/1690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/1690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/1690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/1690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/1690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/1690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/1690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/1690/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&amp;blog=110633&amp;post=1690&amp;subd=gobansaor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2011/05/20/attach-a-sqlite-database-into-excels-memory-via-microetl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>53.204039 -6.574340</georss:point>
		<geo:lat>53.204039</geo:lat>
		<geo:long>-6.574340</geo:long>
		<media:content url="http://1.gravatar.com/avatar/b714f82b5e24beb3b74779615b6ad969?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">gobansaor</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2011/05/datatool-clear.png?w=300" medium="image">
			<media:title type="html">datatool-clear</media:title>
		</media:content>
	</item>
	</channel>
</rss>
