<?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</title>
	<atom:link href="http://blog.gobansaor.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.gobansaor.com</link>
	<description>A country datasmith.</description>
	<lastBuildDate>Tue, 22 May 2012 19:23:46 +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</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>Excel as a Google Visualization API Data Source</title>
		<link>http://blog.gobansaor.com/2012/05/08/excel-as-a-google-visualization-api-data-source/</link>
		<comments>http://blog.gobansaor.com/2012/05/08/excel-as-a-google-visualization-api-data-source/#comments</comments>
		<pubDate>Tue, 08 May 2012 16:11:56 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[Steam Powered Server]]></category>
		<category><![CDATA[Google Charts]]></category>
		<category><![CDATA[Google SpreadSheets]]></category>
		<category><![CDATA[Google Visualization API]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2586</guid>
		<description><![CDATA[Google&#8217;s Visualization API is impressive and very easy to use. Okay, it&#8217;s closed source and must be served from Google&#8217;s servers, but if you&#8217;re happy using say, Google Spreadsheets, that&#8217;s unlikely to concern you. The Guardian&#8217;s Miso Project, might one &#8230; <a href="http://blog.gobansaor.com/2012/05/08/excel-as-a-google-visualization-api-data-source/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2586&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2012/05/08/excel-as-a-google-visualization-api-data-source/visualization-api-clear/" rel="attachment wp-att-2587"><img class="alignleft size-medium wp-image-2587" title="visualization API -clear" src="http://gobansaor.files.wordpress.com/2012/05/visualization-api-clear.png?w=159&h=300" alt="" width="159" height="300" /></a><a href="https://developers.google.com/chart/interactive/docs/index">Google&#8217;s Visualization API</a> is impressive and very easy to use. Okay, it&#8217;s closed source and must be served from Google&#8217;s servers, but if you&#8217;re happy using say, Google Spreadsheets, that&#8217;s unlikely to concern you.</p>
<p>T<a href="http://www.guardian.co.uk/news/datablog/2012/apr/21/miso-project-data-visualisation">he Guardian&#8217;s Miso Project</a>, might one day provide us with a truly open visualisation alternative, so worth keeping an eye on it.</p>
<p>If you&#8217;ve not seen Google Charts in action do check out their <a href="http://code.google.com/apis/ajax/playground/?type=visualization">&#8220;playground&#8221;</a> and also, this <a href="http://www.youtube.com/watch?v=NZtgT4jgnE8">Building Interactive Dashboards video</a>, demonstrating <a href="https://developers.google.com/chart/interactive/docs/gallery/controls">some of the newer, and even easier to use, controls</a>.</p>
<p>Utilising Google Charts API could be an alternative method of publishing PowerPivot generated datasets when the option to use SharePoint is not available (or perhaps not affordable).</p>
<p>One way to do this would be to publish &#8220;tabular reports&#8221; to a Google Docs account using a <a href="http://blog.gobansaor.com/2011/03/16/steam-powered-powerpivot/">&#8220;steam-powered server&#8221;</a> approach. This actually could be a very powerful method of disseminating PowerPivot generated reports, particularly if mobile devices are the target (most Google Charts are now HTML5 enabled); and I&#8217;ll come back to this in a future post.</p>
<p>But, Google Charts can consume data from any server, and can do so very easily if that server implements its <a href="https://developers.google.com/chart/interactive/docs/dev/implementing_data_source">Data Source Protocol</a>. So, as a POC I&#8217;ve added such a server protocol to my <a href="http://blog.gobansaor.com/2012/03/16/odata-in-process-server-auto-refreshing-powerpivot-linked-excel-tables/">InProcess-oData server example</a>. The new end-point is /tq and like the /range endpoint expects to be followed by a valid range pointing at a table. See the example index.html file (no need for a server  just open in browser, having first started the InProcess-oData server on port 8081).</p>
<p>The protocol is not fully implemented (only supports <a class="zem_slink" title="JSONP" href="http://en.wikipedia.org/wiki/JSONP" rel="wikipedia" target="_blank">JSONP</a>, and only supports one request-at-a-time from any client), but it gives a flavour of what&#8217;s possible.  To use this you&#8217;ll need to download the latest version of HAMMER.</p>
<p>Ah, but what if your heart is set on all the SharePoint PowerPivot goodness (and the sight of all that JavaScript doesn&#8217;t appeal), but IT refuses to upgrade your ancient SharePoint farm  (or maybe even refuses to let SharePoint in any shape or form anywhere near their servers). Is all lost? Not at all, check this out, <a href="http://www.powerpivotpro.com/2012/04/cloud-powerpivot-free-trials-for-the-public/">a PowerPivot hosted service</a> (not just any old service, <a href="http://twitter.com/powerpivotpro">@powerpivotpro</a>&#8216;s service), now offering 30-day free trials.</p>
<p><a href="http://www.gobansaor.com/microetl">To download the latest version of HAMMER, go to this page on my website.</a></p>
<p><a href="http://blog.gobansaor.com/category/hammer/">Follow the HAMMER tag on  this blog for information on commands and examples (best start with the oldest and work forward …)</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2586/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2586&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2012/05/08/excel-as-a-google-visualization-api-data-source/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/2012/05/visualization-api-clear.png?w=159" medium="image">
			<media:title type="html">visualization API -clear</media:title>
		</media:content>
	</item>
		<item>
		<title>SAP RFC_READ_TABLE functionality in HAMMER</title>
		<link>http://blog.gobansaor.com/2012/04/28/sap-rfc_read_table-functionality-in-hammer-assistance-required/</link>
		<comments>http://blog.gobansaor.com/2012/04/28/sap-rfc_read_table-functionality-in-hammer-assistance-required/#comments</comments>
		<pubDate>Sat, 28 Apr 2012 16:17:43 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[RFC_READ_TABLE]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SAP to EXCEL]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2565</guid>
		<description><![CDATA[The code below is a typical VBA routine used to fetch data from SAP into Excel. It uses the &#8220;SAP.Functions&#8221; COM object as exposed by the SAP GUI Client, fetching the data via RFC_READ_TABLE; an automated SE16 in effect. The &#8230; <a href="http://blog.gobansaor.com/2012/04/28/sap-rfc_read_table-functionality-in-hammer-assistance-required/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2565&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2012/04/28/sap-rfc_read_table-functionality-in-hammer-assistance-required/sap-logo/" rel="attachment wp-att-2580"><img class="alignleft size-medium wp-image-2580" title="SAP Logo" src="http://gobansaor.files.wordpress.com/2012/04/sap-logo.png?w=300&h=155" alt="" width="300" height="155" /></a>The code below is a typical VBA routine used to fetch data from SAP into Excel.</p>
<p>It uses the &#8220;SAP.Functions&#8221; COM object as exposed by the SAP GUI Client, fetching the data via RFC_READ_TABLE; an automated <a href="http://www.youtube.com/watch?v=S09Q237hySo">SE16</a> in effect.</p>
<p>The credentials required are the same as those you would use to log into your desktop client, and whatever internal tables you can see via SE16, those same tables will be fetchable via RFC_READ_TABLE.</p>
<p>This automated fetching of data is ideal when some self-service reporting is a requirement (you know, standard DW extracts offer most of what you need, but there&#8217;s always something missing <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>I figured this would be a good candidate as a HAMMER command. Not just to take advantage of HAMMER&#8217;s natural table handling but also its multi-threading capability. Being able to spawn one or more background threads (or delegate to HAMMER.exe command line process(es) ) would be very handy for SAP datasmiths.</p>
<p>Problem is, the code below works, and I&#8217;ve converted it to VB.NET, made it more generic and added it as a HAMMER command; but I can&#8217;t test it, as I no longer have access to a <a class="zem_slink" title="SAP R/3" href="http://en.wikipedia.org/wiki/SAP_R/3" rel="wikipedia" target="_blank">SAP R3</a> Instance!</p>
<p>The command SAPREADTABLE takes three parameters:</p>
<ul>
<li>a CSV list of SAP logon credentials: System,Client,User,Password,Language</li>
<li>a CSV list of table information, 1st argument the table name, the rest field names e.g. KNA1,KUNNR,NAME1,NAME2,LAND1</li>
<li>a filter statement (like a SQL where) e.g. LAND1 in (&#8216;DE&#8217;,'NL&#8217;)</li>
</ul>
<p>Example:</p>
<p style="padding-left:30px;">&#8220;Test SYS,600,tom,pwd,EN&#8221;,&#8221;KNA1,KUNNR,NAME1&#8243;,&#8221;LAND1 = &#8216;DE&#8217;&#8221;</p>
<p>UPDATE: April 29, 2012</p>
<p><del>Could somebody with access to SAP R3 test this out for me?</del>  Done, tested (found a small bug, now fixed) and working (thanks to a kind person who allowed me access to a test server, you know who are, thanks again).</p>
<p>Fetch the modified latest version below (fixed bug that produced an extra blank column and extra blank row in result table, my typical &#8220;1 off&#8221; bug when converting from VBA to VB.NET, obviously I&#8217;ll never learn <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p>If you get a scary &#8220;ABEND &#8211; SYSTEM FAILURE&#8221; error, don&#8217;t panic you haven&#8217;t broken the company ERP system, it&#8217;s usually due to a malformed filter statement e.g. LAND1=&#8217;NL&#8217; (no spaces) rather than LAND1 = &#8216;NL&#8217;.</p>
<p><a href="http://www.gobansaor.com/microetl">To download the latest version of the code, go to this page on my website.</a></p>
<p><a href="http://blog.gobansaor.com/category/hammer/">Follow the HAMMER tag on  this blog for information on commands and examples (best start with the oldest and work forward &#8230;)</a></p>
<p>Need a pure VBA version, here it is :</p>
<p>SAP RFC_READ_TABLE VBA Example:</p>
<p><pre class="brush: vb;">

Option Explicit
Option Base 0

Public Function RFC_READ_TABLE(tableName, columnNames, filter)

Dim R3 As Object, MyFunc As Object, App As Object

' Define the objects to hold IMPORT parameters
Dim QUERY_TABLE As Object
Dim DELIMITER   As Object
Dim NO_DATA     As Object
Dim ROWSKIPS    As Object
Dim ROWCOUNT    As Object
' Where clause
Dim OPTIONS As Object
' Fill with fields to return.  After function call will hold
' detailed information about the columns of data (start position
' of each field, length, etc.
Dim FIELDS  As Object
' Holds the data returned by the function
Dim DATA    As Object
' Use to write out results
Dim ROW As Object

Dim Result As Boolean
Dim i As Long, j As Long, iRow As Long
Dim iColumn As Long, iStart As Long, iStartRow As Long, iField As Long, iLength As Long
Dim outArray, vArray, vField
Dim iLine As Long
Dim noOfElements As Long

'**********************************************
'Create Server object and Setup the connection
'use same credentials as SAP GUI login
On Error GoTo abend:
  Set R3 = CreateObject(&quot;SAP.Functions&quot;)
  R3.Connection.SYSTEM = &quot;&quot;
  R3.Connection.Client = &quot;&quot;
  R3.Connection.User = &quot;&quot;
  R3.Connection.Password = &quot;&quot;
  R3.Connection.Language = &quot;EN&quot;

  If R3.Connection.logon(0, True) &lt;&gt; True Then
   RFC_READ_TABLE = &quot;ERROR - logon to SAP Failed&quot;
   Exit Function
  End If
'**********************************************

'*****************************************************
'Call RFC function RFC_READ_TABLE
'*****************************************************

  Set MyFunc = R3.Add(&quot;RFC_READ_TABLE&quot;)
   Set QUERY_TABLE = MyFunc.exports(&quot;QUERY_TABLE&quot;)
   Set DELIMITER = MyFunc.exports(&quot;DELIMITER&quot;)
   Set NO_DATA = MyFunc.exports(&quot;NO_DATA&quot;)
   Set ROWSKIPS = MyFunc.exports(&quot;ROWSKIPS&quot;)
   Set ROWCOUNT = MyFunc.exports(&quot;ROWCOUNT&quot;)

   Set OPTIONS = MyFunc.Tables(&quot;OPTIONS&quot;)
   Set FIELDS = MyFunc.Tables(&quot;FIELDS&quot;)

   QUERY_TABLE.Value = tableName
   DELIMITER.Value = &quot;&quot;
   NO_DATA = &quot;&quot;
   ROWSKIPS = &quot;0&quot;
   ROWCOUNT = &quot;0&quot;
   OPTIONS.Rows.Add
   OPTIONS.Value(1, &quot;TEXT&quot;) = filter ' where filter

    vArray = Split(columnNames, &quot;,&quot;) ' columns
    j = 1
    For Each vField In vArray
        If vField &lt;&gt; &quot;&quot; Then
            FIELDS.Rows.Add
            FIELDS.Value(j, &quot;FIELDNAME&quot;) = vField
            j = j + 1
        End If
    Next

   Result = MyFunc.CALL

   If Result = True Then
     Set DATA = MyFunc.Tables(&quot;DATA&quot;)
     Set FIELDS = MyFunc.Tables(&quot;FIELDS&quot;)
     Set OPTIONS = MyFunc.Tables(&quot;OPTIONS&quot;)
     R3.Connection.LOGOFF
   Else
     R3.Connection.LOGOFF
     MsgBox MyFunc.EXCEPTION
     Exit Function
   End If

  noOfElements = FIELDS.ROWCOUNT
  iRow = 0
  iColumn = 0
  ReDim outArray(0 To DATA.ROWCOUNT, 0 To noOfElements - 1)
  For Each ROW In FIELDS.Rows
    outArray(iRow, iColumn) = ROW(&quot;FIELDNAME&quot;)
    iColumn = iColumn + 1
  Next

'Display Contents of the table
'**************************************
iRow = 1
iColumn = 1

For iLine = 1 To DATA.ROWCOUNT

       For iColumn = 1 To FIELDS.ROWCOUNT
         iStart = FIELDS(iColumn, &quot;OFFSET&quot;) + 1
    '       If this is the last column, calculate the length differently than the other columns
         If iColumn = FIELDS.ROWCOUNT Then
            iLength = Len(DATA(iLine, &quot;WA&quot;)) - iStart + 1
         Else
             iLength = FIELDS(iColumn + 1, &quot;OFFSET&quot;) - FIELDS(iColumn, &quot;OFFSET&quot;)
        End If
    '       If the fields at the end of the record are blank, then explicitly set the value
        If iStart &gt; Len(DATA(iLine, &quot;WA&quot;)) Then
             outArray(iRow, iColumn - 1) = Null
        Else
            outArray(iRow, iColumn - 1) = Mid(DATA(iLine, &quot;WA&quot;), iStart, iLength)
        End If

       Next

       iRow = iRow + 1
Next

RFC_READ_TABLE = outArray
Exit Function

abend:

RFC_READ_TABLE = Err.Description

End Function

Public Sub Paste_sheet1()
Dim lArray
Dim lAdjust As Long

lArray = RFC_READ_TABLE(&quot;KNA1&quot;, &quot;KUNNR,NAME1,NAME2&quot;, &quot;LAND1 = 'DE'&quot;)
If TypeName(lArray) = &quot;String&quot; Then
    MsgBox &quot;Problem calling RFC is it here &quot; &amp; CStr(lArray)
Else

    ' adjust if zero based array
        If LBound(lArray, 1) = 0 Then lAdjust = 1 Else lAdjust = 0

    [Sheet1!A1].Resize(UBound(lArray, 1) + lAdjust, UBound(lArray, 2) + lAdjust) = lArray

End If

End Sub

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2565/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2565&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2012/04/28/sap-rfc_read_table-functionality-in-hammer-assistance-required/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/2012/04/sap-logo.png?w=300" medium="image">
			<media:title type="html">SAP Logo</media:title>
		</media:content>
	</item>
		<item>
		<title>Excel &#8211; as a fractional horsepower HTML5 server</title>
		<link>http://blog.gobansaor.com/2012/03/23/excel-as-a-fractional-horsepower-html5-server/</link>
		<comments>http://blog.gobansaor.com/2012/03/23/excel-as-a-fractional-horsepower-html5-server/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 15:53:04 +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[Steam Powered Server]]></category>
		<category><![CDATA[Datavore]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JoApp]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2523</guid>
		<description><![CDATA[You may have been wondering what&#8217;s the driving force behind the various changes I&#8217;ve made to HAMMER over the last few weeks,  namely threading support, a simple HTTP server and JavaScript. The driving force is to better position HAMMER (and &#8230; <a href="http://blog.gobansaor.com/2012/03/23/excel-as-a-fractional-horsepower-html5-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&#038;blog=110633&#038;post=2523&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2012/03/23/excel-as-a-fractional-horsepower-html5-server/html5/" rel="attachment wp-att-2527"><img class="alignleft size-medium wp-image-2527" title="HTML5" src="http://gobansaor.files.wordpress.com/2012/03/html5.png?w=300&h=300" alt="" width="300" height="300" /></a>You may have been wondering what&#8217;s the driving force behind the various changes I&#8217;ve made to HAMMER over the last few weeks,  namely threading support, a simple HTTP server and JavaScript. The driving force is to better position HAMMER (and through it, Excel) as a fractional horsepower HTTP server (<a href="http://blog.gobansaor.com/2012/03/02/when-hammer-met-swf/">see this post for more on fractional horsepower engines</a>). Features such as threading and JavaScript are useful for many things; threading, for example, makes debugging scripts easier (see the Debug sheet and code in<a href="http://blog.gobansaor.com/2012/03/16/odata-in-process-server-auto-refreshing-powerpivot-linked-excel-tables/"> the sample InProcess_oData workbook</a>) and also makes long running ETL processes easier to control and monitor. But, enabling the set-up of simple task-specific behind-the-firewall data servers, with as little ceremony as possible, is the ultimate goal.</p>
<p>But why, what purpose do these mini servers serve?</p>
<p>They&#8217;re obviously not intended as beyond-the-firewall public servers, they wouldn&#8217;t scale or be secure enough for such a task. Providing in-house feeds to other web enabled clients would be a more sutable task. For example, providing a feed from a &#8220;hub&#8221; workbook containing a <a class="zem_slink" title="PowerPivot" href="http://technet.microsoft.com/en-us/bi/ff604673.aspx" rel="homepage" target="_blank">PowerPivot</a> model to other &#8220;spoke&#8221; workbooks (PowerPivot enabled or not) &#8211; a poor man&#8217;s alternative to doing the same via a SharePoint farm, if you like.</p>
<p>But it&#8217;s another seemingly unrelated technology that&#8217;s really sparked my interest in perfecting the fractional horsepower server: <a title="HTML5" href="http://www.html5rocks.com/en/">HTML5</a>.</p>
<p>Generally when people think of HTML5 (if indeed they think of it at all), it&#8217;s mobile platforms that come to mind. (As it&#8217;s primarily Apple and Google, through their shared <a class="zem_slink" title="WebKit" href="http://www.webkit.org" rel="homepage" target="_blank">WebKit</a> browser core, that have driven the development and adoption of HTML5). So what has this to do with Excel and the boring, but oh so profitable world, of corporate IT? Well, next time you&#8217;re in any spot where the global mobile workforce gathers, airport waiting lounges, hotel lobbies, etc. look at the technology kit that they&#8217;re using.</p>
<p>Only a few years back, the vast majority would have had a Windows laptop, if indeed they had any &#8220;data processing&#8221; device. Now, many, if not all, will either be using a smart-phone or a tablet device (iPhone or iPad but also increasingly Android powered phones/pads). All of these workers are still likely to have a laptop in a carry case or back in the hotel room, and certainly will have a laptop/desktop or their workplace desks. But on the move mobile is where it&#8217;s going.</p>
<p>So how do front-line datasmiths respond to this? Currently many of us build reporting solutions and <a href="http://blog.gobansaor.com/2011/11/05/excel-as-a-book-of-record/">really-simple-systems</a> using Excel as the delivery agent, moving all or part of this to a mobile delivery agent will inevitably become increasingly attractive and/or demanded.</p>
<p>MS is already responding to this, e.g. PowerPivot and standard Excel spreadsheets are capable of being rendered via SharePoint&#8217;s Excel Services. But what if you don&#8217;t have access to a SharePoint farm, or you need a more robust UI, such as could currently be built using a VBA/.NET add-in? This is where HTML5 and fractional horsepower servers come in.</p>
<p>For me, there are two aspects of HTML5 that I think will make developing and deploying such &#8220;systems&#8221; possible and relatively easy:</p>
<ul>
<li>In built graphics and animation support within HTML5 supporting browsers, this makes it easier to display and build business charts and dashboards (se<a href="http://code.google.com/apis/ajax/playground/?type=visualization">e Google&#8217;s chart API playground to see what&#8217;s possible</a>).</li>
<li><a href="http://www.html5rocks.com/en/features/storage">Local off-line storage.</a></li>
</ul>
<p>It&#8217;s HTML5&#8242;s local storage, that&#8217;s makes a fraction horsepower server scenario possible. In traditional web apps, it&#8217;s assumed that:</p>
<ul>
<li>1st the client is always connected to a server,</li>
<li>and that the server provides both the layout (html, javascript, css) and all the data (REST APIs etc.) that the web app consumes.</li>
</ul>
<p>Now with HTML5 apps, the client doesn&#8217;t need to be always connected to its main server or to its data server(s). It can go offline, or it can stay connected to its main server (perhaps a <a href="http://www.pcworld.com/businesscenter/article/220118/amazon_s3_offers_complete_website_hosting.html">public-internet-facing S3 hosted domain</a>), and every now and then make contact with one or more data servers (which can be safely positioned behind the firm&#8217;s firewall).</p>
<p>An example:</p>
<p>A firm&#8217;s Sales Reps come into the office every Friday for wash-up meetings, to record sale completions and to get their journey-plans for the following week.</p>
<p>Each rep has a desktop computer, where they interface with the firm&#8217;s various systems. One such set of &#8220;systems&#8221; are PowerPivot based models that report on the year&#8217;s forecasts and actual sales.  Part of the process of preparing for a sales visit is creating a set of sales reports for each customer to be visited, last year sales, this year&#8217;s targets, and so on, sourced from the various PowerPivot models. Although the production of the reports is largely automated via Excel macros, currently the resulting sheets have to be printed.</p>
<p>There&#8217;s been talk of company supplied laptops for years and the budget for them has now at long last materialised. The reps however, have expressed a preference for using iPads when customer-facing, mainly because the sales conversation often require not only presenting the prepared sales reports and charts but also flicking through many of the 100 odd product manuals. Being able to hand around an iPad with high quality glossy images (and videos) of this year&#8217;s new products, plus a sales projection chart for the same products, is, they contend, a winner.</p>
<p>A simple mobile sales reporting app is therefore developed (using <a href="http://joapp.com/">the JoApp framework</a> and <a href="http://code.google.com/apis/chart/">Google&#8217;s Chart API</a> and <a href="https://github.com/StanfordHCI/datavore">this pure JavaScript columnar database</a>) to cater for the type of sales reports the reps require. The existing Excel automation code is enhanced with a HAMMER server. The reps new iPads&#8217; web-apps are configured to automatically download prepared and ad-hoc reports when they log-in to the office network.</p>
<p>This has worked so well, the reps now want the ability to feed back sales target changes, that they also wish to record on their iPads via another really-simple-system, to their personal Sales Plan workbooks.</p>
<p>Is this as simple as using a &#8220;pure&#8221; spreadsheets solution, no, but it&#8217;s nearly as simple as building a VBA/.NET powered Excel application to do the same. The problem with many Excel &#8220;applications&#8221; is that they often push Excel beyond its &#8220;comfort zone&#8221;. The benefit of a hybrid solution like above, is that Excel gets used where it&#8217;s really useful and powerful (reports and models, data gathering and dispersal) while at the same time taking advantage of the freedom and cost-benefits (and fun!) of the emerging mobile web.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2523/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2523/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2523/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2523/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2523/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2523/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2523/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2523/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2523/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2523/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2523/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2523/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2523/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2523/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2523&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2012/03/23/excel-as-a-fractional-horsepower-html5-server/feed/</wfw:commentRss>
		<slash:comments>3</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/2012/03/html5.png?w=300" medium="image">
			<media:title type="html">HTML5</media:title>
		</media:content>
	</item>
		<item>
		<title>oData in-process Server &#8211; auto refreshing PowerPivot linked Excel tables</title>
		<link>http://blog.gobansaor.com/2012/03/16/odata-in-process-server-auto-refreshing-powerpivot-linked-excel-tables/</link>
		<comments>http://blog.gobansaor.com/2012/03/16/odata-in-process-server-auto-refreshing-powerpivot-linked-excel-tables/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 17:33:07 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Excel ATOM ODATA]]></category>
		<category><![CDATA[ODATA]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2488</guid>
		<description><![CDATA[To test out the new threading facilities in HAMMER I picked on that perennial question that I get asked &#8220;Can your PowerPivot refresh code, refresh linked tables?&#8221; to provide me with a suitable task. As regards the original code, the &#8230; <a href="http://blog.gobansaor.com/2012/03/16/odata-in-process-server-auto-refreshing-powerpivot-linked-excel-tables/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2488&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="attachment_2491" class="wp-caption alignleft" style="width: 310px"><a href="http://blog.gobansaor.com/2012/03/16/odata-in-process-server-auto-refreshing-powerpivot-linked-excel-tables/ohdata/" rel="attachment wp-att-2491"><img class="size-medium wp-image-2491" title="Oh Data!" src="http://gobansaor.files.wordpress.com/2012/03/ohdata.jpg?w=300&h=183" alt="" width="300" height="183" /></a><p class="wp-caption-text">Oh Data!</p></div>
<p>To test out <a href="http://blog.gobansaor.com/2012/02/25/hammer-and-threads-redux-the-adventure-continues/">the new threading facilities in HAMMER </a>I picked on that perennial question that I get asked &#8220;Can <a href="http://blog.gobansaor.com/2011/11/22/powerpivot-vba-refesh-code-bug-fix/">your PowerPivot refresh code</a>, refresh linked tables?&#8221; to provide me with a suitable task.</p>
<p>As regards the original code, the answer is no; linked tables cannot be refreshed via the XMLA method I use. You could of course, simply automate the export of the Excel tables to, say, a CSV format and then refresh from the disk. Biggest problem with that approach is PowerPivot&#8217;s insistence on using absolute file addresses, which makes sharing the resulting workbook more cumbersome (requires that the saving folder on each machine be the same). Another solution is to use some variation on SendKeys to automate the &#8220;button push&#8221;, can be done, but pretty it&#8217;s not.</p>
<p>So what&#8217;s an automate&#8217;r to do? Use PowerPivot&#8217;s <a href="http://www.odata.org/">oData</a> import facility, that&#8217;s what.</p>
<p>In a previous example I had demonstrated <a href="http://blog.gobansaor.com/2011/09/21/exposing-an-excel-powerpivot-model-as-a-web-service/">using oData to provide a feed from a master-workbook to client work-books</a>, so I already had code in Python to generate a simple oData feed (it&#8217;s essentially an ATOM feed; yeah, the same format used by many blog engines (usually alongside RSS2.0), and offered as a output format by many web services, Twitter and Google Docs, for example).</p>
<p>Rather than using HTTPlistener (which is very powerful, but requires Admin privileges) this time I used HAMMER&#8217;s internal simple HHTP/1.0 socket based server (which is multi-threaded and uses callbacks to communicate with either Python or Javascript GET/POST handling functions). Using a PYTHONTHREAD command enabled me to spin of the oData-generating-code as an in-process server running on an independent thread; leaving the main Excel thread to fetch the necessary ranges from the workbook and then issue a PowerPivot refresh command (both of theses operations require being run single-threaded and in the main thread).</p>
<p>In PowerPivot itself, the range tables are fetched using a &#8220;127.0.0.1:8081/range/&#8221; endpoint.</p>
<p>So, for example, to fetch a table from a range whose top-left-hand-corner is Sheet2!A1, use the URL &#8220;127.0.0.1:8081/range/Sheet2!A1&#8243;.</p>
<p>For an Excel 2007/2010 table named InvoiceHeaders use &#8220;127.0.0.1:8081/range/InvoiceHeaders[%35All]&#8221; (the %35 is URL encoded &#8220;#&#8221;).</p>
<p>While the workbook is in &#8220;manual mode&#8221;, the in-process server will fetch on-demand any valid tabular range (but be careful not to &#8220;lock&#8221; the workbook, by, for example, editing a cell, while this is happening).</p>
<p>When in &#8220;automated refresh mode&#8221;, the VBA code will lock out any on-demand refreshes (it&#8217;s best in any case, to close PowerPivot&#8217;s window before doing any XMLA refreshes); then use the list of ranges provided to fetch the tables required, and initiate an auto-refresh.</p>
<p>Everything should go smoothly as long as the list matches exactly (case sensitive) the URLs assigned to tables with PowerPivot.</p>
<p>To try this out, download the latest version of HAMMER, go to the distribution folder, open the InProcess_oData workbook.</p>
<p>In the Control sheet, click the Enable HAMMER button, followed by the Start oData Server button. If you think port 8081 is likely to be already in use on your PC, go to the PythonCode sheet and change to a free port.</p>
<p>Then go to the Data sheet, change the tables, and refresh PowerPivot using the &#8220;arrow&#8221; button provided.</p>
<p>Make sure to click the Stop Server button, before exiting Excel, otherwise the port-listening thread will keep Excel alive in the background.</p>
<p>Of course, auto refreshing same-workbook &#8220;linked&#8221; tables is but one use this could be put to. Other possible uses would be taking advantage of Excel powers that the PowerPivot import facility still lack, such as XML Maps. Or, using 3rd party libraries or bespoke code to access &#8220;non-standard&#8221; (i.e. the majority that don&#8217;t use ATOM!) web services or data sources (such as XBRL).</p>
<p>Have fun&#8230;</p>
<div>
<p><strong><a href="http://www.gobansaor.com/microetl">To download the latest version of the code, go to this page on my website.</a></strong></p>
<p><strong><a href="http://blog.gobansaor.com/category/hammer/">Follow the HAMMER tag on  this blog for information on commands and examples (best start with the oldest and work forward &#8230;)</a></strong></p>
<div><strong><a href="http://www.gobansaor.com/hammer" rel="nofollow">To see a list of commands (WIP) implemented by HAMMER see here.</a></strong></div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2488/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2488/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2488/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2488/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2488/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2488/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2488/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2488/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2488/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2488/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2488/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2488/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2488/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2488/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2488&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2012/03/16/odata-in-process-server-auto-refreshing-powerpivot-linked-excel-tables/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/2012/03/ohdata.jpg?w=300" medium="image">
			<media:title type="html">Oh Data!</media:title>
		</media:content>
	</item>
		<item>
		<title>When HAMMER met SWF</title>
		<link>http://blog.gobansaor.com/2012/03/02/when-hammer-met-swf/</link>
		<comments>http://blog.gobansaor.com/2012/03/02/when-hammer-met-swf/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 14:00:22 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[AmazonAWS]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[microETL]]></category>
		<category><![CDATA[SWF]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2454</guid>
		<description><![CDATA[I use the term &#8220;micro ETL&#8221; a lot when writing about tools such as HAMMER, but what do I mean by the term? The ETL bit is easy to explain: ETL, as all you data-warehousing and business intelligence folks will &#8230; <a href="http://blog.gobansaor.com/2012/03/02/when-hammer-met-swf/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2454&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="attachment_2457" class="wp-caption alignleft" style="width: 310px"><a href="http://society6.com/product/Dark-satanic-mill_Print"><img class="size-medium wp-image-2457" title="mill" src="http://gobansaor.files.wordpress.com/2012/03/mill.jpg?w=300&h=200" alt="http://society6.com/product/Dark-satanic-mill_Print" width="300" height="200" /></a><p class="wp-caption-text">Dark satanic mill by Mark Nelson</p></div>
<p>I use the term &#8220;micro ETL&#8221; a lot when writing about tools such as HAMMER, but what do I mean by the term?</p>
<p>The ETL bit is easy to explain:</p>
<p>ETL, as all you data-warehousing and business intelligence folks will know, is the Extracting, Transformation and Loading of data from source systems into a reporting/data warehousing system. The techniques of ETL are not unique to the DW/BI worlds but are used anywhere transfers of data are needed between one computer system and another, for example, master data take-on for new systems or transactional interfaces between front and back-office systems &#8211; this is often referred to as DI (data integration) but is essentially the same problem domain.</p>
<p>So what&#8217;s the &#8220;micro&#8221; bit about?</p>
<p>You might assume that the micro adjective implies small or indeed tiny datasets, and in many cases you would be correct. Most final-mile data analysis, like politics, is local. Most business decisions along with their implementation and monitoring require &#8216;localised&#8217; data. That data will be pre-filtered and summarised to some degree, but a fair degree of data shaping will still happen close to the decision makers. Excel is often the tool of choice when data gets to this stage.</p>
<p>HAMMER is optimised for this world, it sees the world how Excel sees it, but also adds the power of SQL and scripting languages to pick up where Excel stops. But enabling better Excel based data shaping is not HAMMER&#8217;s only function. It can operate outside of Excel (HAMMER.exe) and it can be used to craft task-specific ETL tools <a href="http://blog.gobansaor.com/2011/08/14/hammer-inside/">(HAMMER Inside</a>). In both cases I continue to use Excel as my <a href="http://en.wikipedia.org/wiki/Integrated_development_environment">IDE</a>, teasing out a problem before fixing it in code or in an external HAMMER call; and I can also use Excel as the UI for the end products.</p>
<p>In such scenarios, micro applies not so much to the datasets (which can be anything from tiny to very large) but to the concept of deploying simple micro &#8220;fractional horsepower&#8221; data engines to solve complex ETL, DI or RSS (<a href="http://blog.gobansaor.com/2011/04/19/really-simple-systems/">Really SImple Systems</a>) requirements.</p>
<p>HAMMER is built to take advantage of the distributed grid of powerful data crunchers (be that PCs, laptops, in-house cheap servers or just-in-time pay-as-you-go cloud-based CPUs) that every business, big or small, can now call on.</p>
<p>This revolution in distributed power is similar to what happened with the deployment of <a href="http://en.wikipedia.org/wiki/Fractional_horsepower_motor">fractional horsepower AC-powered electrical motors</a> in the last century. No longer was manufacturing restricted to &#8220;dark satanic mills&#8221; which had to be built close to natural power sources (water and later coal seams); and had to conform to the multi-story classic mill design to harness that captured power through belts, pulleys and shafts. With the expansion of the AC power grids (and the parallel expansion of internal combustion engine carrying roadways) the factory began to take on its modern single-story (or single story with mezzanine) distributed profile than can be seen everywhere from China to Cork. A similar landscape change is happening in IT.</p>
<p>HAMMER can take advantage of the &#8220;distributed engines&#8221; easily enough but the workflow, the actual control and distribution of tasks, data and decisions requires the ad hoc implementation  of either <a href="http://blog.gobansaor.com/2011/03/16/steam-powered-powerpivot/">steam-powered</a> or classic centralised server processes. I badly needed a more pre-built modular approach, micro Workflow to complement  micro ETL (and micro BI via PowerPivot ?), if you like. Last week I had started to think seriously about how/what to do about this (<a href="http://www.jsdb.org/">JSDB powered grids </a>were featuring high on the list) <a href="http://aws.typepad.com/aws/2012/02/amazon-simple-workflow-cloud-based-workflow-management.html">when this appeared</a>.</p>
<p style="text-align:center;"><em>Perfect timing, <a href="http://aws.amazon.com/swf/">Amazon&#8217;s SWF (Simple Workflow service)</a> is exactly what I need!</em></p>
<p>SWF allows for the control and distributed deployment of <a href="http://en.wikipedia.org/wiki/State_(computer_science)">stateless</a> data processors. HAMMER was designed primarily as a stateless data processor (with state being persisted either in Excel or on disk as simple CSV/JSON flat files). Its default use of in-memory, rather than disk-based, SQLite assumes both abundant CPU and RAM (like is the case with your average 64bit laptop) and the existence of an external state-machine (which Excel and now SWF provide).</p>
<p><a href="http://blog.gobansaor.com/2012/03/02/when-hammer-met-swf/when-harry-met-sally/" rel="attachment wp-att-2458"><img class="alignleft size-medium wp-image-2458" title="when-harry-met-sally" src="http://gobansaor.files.wordpress.com/2012/03/when-harry-met-sally.jpg?w=300&h=200" alt="" width="300" height="200" /></a>I&#8217;ve spent any spare time I had this week doing a deep dive into SWF and figuring out how HAMMER can take full advantage of this technology, not just for classic ETL, but for distributed decision control processes and RSS solutions. The result, in Dublin slang, is that I&#8217;m both &#8220;delira and excira&#8221; (delighted and excited). This is, to use that term again, <a href="http://aws.amazon.com/">yet another AWS game- changer</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2454/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2454&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2012/03/02/when-hammer-met-swf/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/2012/03/mill.jpg?w=300" medium="image">
			<media:title type="html">mill</media:title>
		</media:content>

		<media:content url="http://gobansaor.files.wordpress.com/2012/03/when-harry-met-sally.jpg?w=300" medium="image">
			<media:title type="html">when-harry-met-sally</media:title>
		</media:content>
	</item>
		<item>
		<title>HAMMER and Threads Redux &#8211; The adventure continues&#8230;</title>
		<link>http://blog.gobansaor.com/2012/02/25/hammer-and-threads-redux-the-adventure-continues/</link>
		<comments>http://blog.gobansaor.com/2012/02/25/hammer-and-threads-redux-the-adventure-continues/#comments</comments>
		<pubDate>Sat, 25 Feb 2012 00:10:22 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JSDB]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Threads]]></category>
		<category><![CDATA[VBA threads]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2405</guid>
		<description><![CDATA[Sometimes, like Scott of the Antarctic, your data shaping activities may need to &#8220;go outside&#8221; of Excel and it &#8221; may be some time&#8221; before you return. That&#8217;s primarily why the HAMMER.exe command-line version exists; data can be packed up via &#8230; <a href="http://blog.gobansaor.com/2012/02/25/hammer-and-threads-redux-the-adventure-continues/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2405&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://blog.gobansaor.com/2012/02/25/hammer-and-threads-redux-the-adventure-continues/scottoftheantartic/" rel="attachment wp-att-2406"><img class="alignleft size-medium wp-image-2406" title="scottoftheantartic" src="http://gobansaor.files.wordpress.com/2012/02/scottoftheantartic.png?w=300&h=215" alt="" width="300" height="215" /></a></em>Sometimes, like<a href="http://en.wikipedia.org/wiki/Robert_Falcon_Scott"> Scott of the Antarctic</a>, your data shaping activities may need to &#8220;go outside&#8221; of Excel and it &#8221; may be some time&#8221; before you return. That&#8217;s primarily why the HAMMER.exe command-line version exists; data can be packed up via the <a href="http://blog.gobansaor.com/2011/06/29/those-with-a-datasmiths-hammer-see-every-problem-as-a-table/">DELEGATE or SUBMIT commands</a>; picked up by external HAMMER processes (I often use <a href="http://www.jsdb.org/">JSDB&#8217;s Grid micro-messaging JavaScript toolkit</a> to orchestrate such workflows, but perhaps now I&#8217;ll use this &#8211; Amazon&#8217;s latest gem - <a href="http://aws.amazon.com/swf/">AWS SWF</a> !); then returned safely (unlike Scott) to Excel for further processing.</p>
<p>But, when &#8220;going outside&#8221; is not desirable or feasible, another solution is required, namely threads. There are those who regard <a href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf">threads as evil </a>and I too would have to admit I generally would not use them without good reason. But sometimes they&#8217;re needed, usually to keep a controlling UI (in this case Excel) responsive and capable of monitoring and managing background long-running tasks.</p>
<p>I&#8217;ve already added threading capability to HAMMER via the <strong><em><a href="http://blog.gobansaor.com/2011/09/09/hammering-away-at-automated-powerpivot-refresh/">hammerThreadEnabled</a></em></strong> function and via <a href="http://blog.gobansaor.com/2011/06/17/hammer-and-threads/">&#8220;internal HAMMER threads</a>&#8221; (using <a href="http://www.codeproject.com/Articles/71285/Introducing-NET-4-0-Parallel-Programming">NET4.0&#8242;s latest parallel programming additions</a>).</p>
<p>Both of these &#8220;lock&#8221; the Excel main thread until complete, with <strong><em>hammerThreadEnabled</em></strong> being also dependent on Excel&#8217;s dependency graph to determine if threading will happen or not. So I figured I needed to bite the bullet and add a new set of threading commands to better handle long-running tasks, be they tasks that eventually return data or a status to the main Excel thread (such as a long running save to ( or fetch from) a high latency web service end point), or those that run continuously (such as a E<a href="http://blog.gobansaor.com/2011/09/21/exposing-an-excel-powerpivot-model-as-a-web-service/">xcel as a web service</a>). The main new commands are:</p>
<ul>
<li>PYTHONTHREAD &#8211; like PYTHON but spawns a thread to run to Python script. (NET4.0 runtime required)</li>
<li>JAVASCRIPTTHREAD &#8211; as above, but using JAVASCRIPT plus no need for NET 4.0.</li>
</ul>
<p>Both commands &#8220;take ownership&#8221; of the HAMMER session&#8217;s SQLite database  and return the new thread&#8217;s ID (in the form PYTHREAD1,PYTHREAD2, JSTHHREAD3 etc), and are likely to be the last command in a HAMMER function call&#8217;s sequence.</p>
<p>The thread ID can then be used by the following helper commands to monitor, re-join and clean-up such threads:</p>
<ul>
<li>SQLFROMTHREAD &#8211; like SQL but takes two arguments, 1st is the thread id, and the 2nd is the SQL to apply against that thread&#8217;s SQLite database. e.g. = &#8230; &#8220;JSTHREAD1&#8243;,&#8221;Select * from messages&#8221;,&#8221;SQLFROMTHREAD&#8221; &#8230; In general, only Select statements would be issued against this database, but SQLite is thread-safe so data updates are possible but with obvious potential for SQLITE_BUSY locks and time outs. (Likewise, the thread itself can communicate back to main thread using an APPDB connection, as APPDB is always attached uniquely to the main Excel thread).</li>
<li>THREADRETURN &#8211; will report on whatever return values (be that an error, or on success, a string or a table value) once the thread completes. Again, it uses the thread ID as its argument. If the thread is still running, the command returns &#8220;Waiting&#8221;.</li>
<li>DELETETHREAD &#8211; will attempt to terminate an already running thread. It will then, or if already terminated, clean-up and close any resources associated with the thread, mainly its database, but also its Python and/or JavaScript engine instances.</li>
</ul>
<p>It&#8217;s also possible to issue a HAMMER call that will re-join a completed thread&#8217;s database, this will happen if a HAMMER function call&#8217;s 1st argument is a valid thread-name e.g. =HAMMER(&#8220;JSTHREAD2&#8243;,&#8221;Select * from results&#8221;,&#8221;SQL&#8221;). If the thread is still running, the HAMMER function will exit with a return value of &#8220;Waiting&#8221;. With this, it&#8217;s possible to not only access the thread&#8217;s database but also its Python and/or JavaScript engine context. Multiple such HAMMER calls can be made until a DELETETHREAD command is issued or the Excel session is terminated.</p>
<p>As SQLite is thread-safe, SQL can be used as a simple and robust method of inter-thread communication. If the pattern of threads only updating their &#8220;own&#8221; database while the main Excel thread updates only &#8220;APPDB&#8221; is followed, very little locking or timeout issues should arise (ha, famous last words &#8211; okay, not as famous as Scott&#8217;s). There&#8217;s also nothing to stop more adventurous inter-thread single database usage if the need or impulse arises (&#8220;Do ya feel lucky Punk, well do ya!&#8221;). And don&#8217;t forget, normal disk-based databases can also be used alongside, or instead of, the more usual in-memory ones.</p>
<p>This use of SQLite falls neatly into my view of SQLite not so much as a database but as means of mapping and managing  shared memory using SQL as an  API.</p>
<p>It&#8217;s often said that SQLite should be viewed not as an alternative to Oracle/MySQL/MSAccess/whateverRDBMS but as an alternative to a file-open statement. But for me, I primarily use SQLite as an alternative to rolling-my-own in-memory shared data structures  (be that across threads or application stacks).</p>
<p>Two other new commands added with this version are:</p>
<ul>
<li>VERSION &#8211; will return the version of the internal HAMMER (XLite) engine is use.</li>
<li>LISTCOMMANDS &#8211; returns the list of commands available.</li>
</ul>
<p>There&#8217;s also been a small breaking change to the JAVASCRIPT command. Scripts will now only return a table if the return value is a JavaScript Array of Arrays (List of Lists) object or a JSON string representing a LOL. All other objects will be converted to a JSON string representation or scalar string value.</p>
<p>A few extra JavaScript focused helper methods have also been added to the passed-in &#8220;db&#8221; object:</p>
<ul>
<li>db.jsCreateTable(tableName, JSONaLOLorLOOobject) where the 2nd argument can be a &#8220;JSON table&#8221; in either List of Lists or List of Objects format. A table will be created using either the first &#8220;line&#8221; of the LOL or the &#8220;names&#8221; of the objects fields in the LOO to provide the column names (no types applied, as no need most of the time).</li>
<li>db.jsInsertRows(tableName,JSONaLOLorLOOobject) &#8211; as above but will insert/append the pass&#8217;d &#8220;rows&#8221; to the specified table.</li>
<li>db.jsonSQLQuery(SQLSelectStatement,typeOfJSON) will return a table in List of Lists format if typeOfJSON = &#8220;LOL&#8221; or as a List of Objects if &#8220;LOO&#8221;.</li>
</ul>
<p>There&#8217;s also a new JavaScript command: loadAssembly(dotNetAssemblyName) &#8211; which will load a .NET assembly allowing the use of any .NET library within JAVASCRIPT.</p>
<p>Both the JAVASCRIPT and threading commands are at a very early stage, only minimal testing so far, so use with care.</p>
<p><strong><a href="http://bit.ly/datasmith" rel="nofollow">To download the latest version of HAMMER, use this link</a>.</strong></p>
<div><strong><br />
</strong></div>
<div><strong><a href="http://www.gobansaor.com/hammer" rel="nofollow">To see a list of commands implemented by HAMMER see here.</a></strong></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2405/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2405/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2405/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2405/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2405/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2405/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2405/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2405/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2405/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2405/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2405/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2405/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2405/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2405/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2405&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2012/02/25/hammer-and-threads-redux-the-adventure-continues/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/2012/02/scottoftheantartic.png?w=300" medium="image">
			<media:title type="html">scottoftheantartic</media:title>
		</media:content>
	</item>
		<item>
		<title>JavaScript as an Excel scripting language via HAMMER</title>
		<link>http://blog.gobansaor.com/2012/02/16/javascript-as-an-excel-scripting-language-via-hammer/</link>
		<comments>http://blog.gobansaor.com/2012/02/16/javascript-as-an-excel-scripting-language-via-hammer/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 15:31:54 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[HAMMER]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JSDB]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2376</guid>
		<description><![CDATA[I&#8217;ve demonstrated in the past how to embed JavaScript in  Excel using the C based JSDB toolset and having already provided Python as a HAMMER scripting language, I felt the time had come to do the same for JavaScript. With &#8230; <a href="http://blog.gobansaor.com/2012/02/16/javascript-as-an-excel-scripting-language-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&#038;blog=110633&#038;post=2376&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2012/02/16/javascript-as-an-excel-scripting-language-via-hammer/javascript_json_clear/" rel="attachment wp-att-2379"><img class="alignleft size-full wp-image-2379" title="javascript_json_clear" src="http://gobansaor.files.wordpress.com/2012/02/javascript_json_clear.png?w=500" alt=""   /></a>I&#8217;ve demonstrated in the past how to <a href="http://blog.gobansaor.com/2010/06/04/javascript-as-an-excel-scripting-language-via-jsdb/">embed JavaScript in  Excel using the C based JSDB toolset</a> and having already provided Python as a HAMMER scripting language, I felt the time had come to do the same for JavaScript. With this, the latest release of HAMMER, JavaScript&#8217;s back!</p>
<p>There&#8217;s three main reason&#8217;s why I&#8217;ve added JavaScript as a partner scripting language to HAMMER&#8217;s existing Python (and VBA) integration.</p>
<ul>
<li>JavaScript is everywhere, a lot more people know it and use it than have ever used, or likely to use Python, (or VBA). JavaScript is now the undisputed <a href="http://blog.gobansaor.com/2007/03/22/vba-javascript-glue-languages/">&#8220;glue language&#8221;</a>.</li>
<li>I needed a scripting language that would work in all versions of HAMMER (the current IronPython implementation requires NET 4.0). For that reason I decided to use the NET2.0 based <a href="http://jint.codeplex.com/">JINT</a> rather than <a href="https://github.com/fholm/IronJS">IronJS</a> as my choice of JavaScript engine. JINT, is simpler, and probably slower that IronJS, but being C# based (IronJS is being developed in F#) I can more easily dig as deep as I need into JINT&#8217;s codebase without exhausting my technical skills.</li>
<li>Increasingly I&#8217;m coming across JSON as data transfer protocol and although I have inbuilt JSON processing commands in HAMMER, JavaScript and JSON are natural partners.</li>
</ul>
<p>The main use-case I see for JavaScript scripts will be the manipulation of data, which is obviously equally possible with Python, but I see IronPython&#8217;s main use as a scripting language for .NET facilities (IronPython&#8217;s integration with .NET is complete, the JINT engine&#8217;s integration is much less advanced). And as I pointed out above, removing the NET4.0 requirement (for both Excel and the HAMMER.exe command line version) is very useful when building <a href="http://blog.gobansaor.com/2011/08/14/hammer-inside/">HAMMER Inside</a> bespoke applications.</p>
<p>So my scripting language choices are:</p>
<ul>
<li>VBA, when manipulating the Excel Object Model</li>
<li>IronPython when accessing .NET internals, or for complex coding requirements when not  using C# or VB.NET.</li>
<li>SQL , for tabular set manipulations, and for the fact &#8220;t<a href="http://blog.gobansaor.com/2008/12/18/sql-does-exactly-what-it-says-on-the-tin/">hat SQL  does exactly what it says on the tin</a>&#8220;.</li>
<li>JavaScript for everyday data-focused IF-THEN-ELSE&#8217;ing or JSON&#8217;ing.</li>
</ul>
<p>Calling JavaScript from HAMMER is similar to Python. So &#8230;</p>
<p>=HAMMER(&#8220;myVal=&#8217;cat&#8217;; return myVal;&#8221;,&#8221;JAVASCRIPT&#8221;) will return &#8220;cat&#8221;.</p>
<p>Like PYTHON, a object &#8220;db&#8221; is passed into the script, this allows access to the SQLite instance via several functions:</p>
<ul>
<li><span style="font-size:small;"><span style="line-height:22px;">db.SQL(arg) will take a string arg holding a SQL command and execute it.</span></span></li>
<li><span style="font-size:small;"><span style="line-height:22px;">db.SQL(arg,callback(arg)) as above but expects a SELECT statement and will return a JSON encoded object string via the callback&#8217;s arg for each row returned.</span></span></li>
<li><span style="font-size:small;"><span style="line-height:22px;">myJSONTable  = db.jsSQLQuery(arg) expects a SQL SELECT statement and will return the table as a single JSON encoded string as a List of Objects.</span></span></li>
<li><span style="font-size:small;"><span style="line-height:22px;">myJSONReturn = db.JSONhammer(arg) will make a call as an internal HAMMER command where arg is a JSON encoded string of a List of commands. Will return a JSON encoded table or a string value.</span></span></li>
<li><span style="font-size:small;"><span style="line-height:22px;">argValue = db.getArgNoArg(argNo) will get the value of a HAMMER argument, where argNo=1 is the last argument before the JavaScript script argument, argNo=2 is the argument prior to that, and so on.</span></span></li>
<li><span style="font-size:small;"><span style="line-height:22px;">tableName  =  db.getArgNoTable(argNo) like above but returns a table name if the argument position holds a table rather than a string value.</span></span></li>
</ul>
<p>A predefined JSON object is also passed in, offering the usual JSON.parse(arg)  and JSON.stringify(obj) methods.</p>
<p>There&#8217;s also an alert(arg) command which will display a Window&#8217;s message box and a println(arg) command which will append to a _JSSTDOUT specified log file if one has been specified.</p>
<p>Use the &#8220;return&#8221; command to return either a table (a JavaScript object containing either a List of Lists or a List of Objects) or a string value.</p>
<p>I&#8217;ve not fully tested this, or settled completely on the interface between HAMMER and its new JAVASCRIPT engine, but I&#8217;ll do so over the next few weeks and will then include a proper examples of its use.  So use with caution.</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 from here …</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2376/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2376/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2376/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2376/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2376/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2376/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2376/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2376/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2376/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2376/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2376/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2376/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2376/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2376/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2376&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2012/02/16/javascript-as-an-excel-scripting-language-via-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/2012/02/javascript_json_clear.png" medium="image">
			<media:title type="html">javascript_json_clear</media:title>
		</media:content>
	</item>
		<item>
		<title>Death of the Star Schema?</title>
		<link>http://blog.gobansaor.com/2012/01/19/death-of-the-star-schema/</link>
		<comments>http://blog.gobansaor.com/2012/01/19/death-of-the-star-schema/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 16:43:48 +0000</pubDate>
		<dc:creator>gobansaor</dc:creator>
				<category><![CDATA[BI]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[Datawarehouse]]></category>
		<category><![CDATA[Star Schema]]></category>

		<guid isPermaLink="false">http://blog.gobansaor.com/?p=2336</guid>
		<description><![CDATA[With the release of the next version of PowerPivot around the corner (mid March I think), I&#8217;ve been re-acquainting myself with its new features. Most of the current version&#8217;s annoyances have been remedied (no drill-thru, no hierarchy support for example); &#8230; <a href="http://blog.gobansaor.com/2012/01/19/death-of-the-star-schema/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2336&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gobansaor.com/2012/01/19/death-of-the-star-schema/death-of-a-star/" rel="attachment wp-att-2337"><img class="alignleft size-full wp-image-2337" title="death of a star" src="http://gobansaor.files.wordpress.com/2012/01/death-of-a-star.jpg?w=500" alt=""   /></a>With the release of the next version of PowerPivot around the corner (mid March I think), I&#8217;ve been re-acquainting myself with its new features. Most of the current version&#8217;s annoyances have been remedied (no drill-thru, no hierarchy support for example); and the additional enhancements to the DAX language (crossjoins, alternate relationships etc) make modelling m0st any problem possible (and generally easy).</p>
<p>The more I come to know PowerPivot, the more I believe that modelled <a class="zem_slink" title="Data warehouse" href="http://en.wikipedia.org/wiki/Data_warehouse" rel="wikipedia">data warehouses</a>&#8216; days are numbered. I didn&#8217;t say data warehouses per se, rather those that attempt to centrally model end user reporting structures (usually as star-schemas).</p>
<p>There will continue to be a need for centrally controlled data warehouses (or at least simplified data views (and/or copies) of operational datasets, either provided by system vendors of by in-house IT) to bridge the <em>raw-to-actionable data gap. </em>But I suspect <a href="http://www.capgemini.com/technology-blog/2012/01/service-reporting-good-traditional-bi-bad/">the emphasis will change</a> from providing finished goods to providing semi-processed raw materials.</p>
<p>So, will the <a class="zem_slink" title="Star schema" href="http://blog.gobansaor.com/2010/07/09/star-schemas-to-boldly-go-where-no-excel-spreadsheet-has-gone-before/" rel="wikipedia">star-schema</a> become redundant? No, as it&#8217;s still a valid method of modelling a reporting requirement in order to make many queries simpler to phrase (this obviously applies to SQL , but also to DAX queries). But, those who build them will be doing so closer to the problem at hand, and specific to that problem (I&#8217;ve discussed this before in <a href="http://blog.gobansaor.com/2011/01/08/slowly-changing-dimensions-time-to-stop-worrying/">http://blog.gobansaor.com/2011/01/08/slowly-changing-dimensions-time-to-stop-worrying/</a>).</p>
<p>For many reports the barely modified operational data model will be all that&#8217;s required (for example, DAX doesn&#8217;t require &#8220;fact&#8221; header/detail tables to be flattened to detail level, as would be the case with a classic star).</p>
<p>&#8220;Good Enough&#8221; models will become the norm; classic &#8220;Everything You Ever Wanted to Know&#8221; centralised models a luxury for most (especially as such models tend to &#8220;age&#8221; very quickly).</p>
<p>If you&#8217;re about to invest or re-furbish your data warehouse or your reporting data sub-systems, don&#8217;t do so without first taking a serious look at PowerPivot. This is a game-changer, not just for full-stack Microsoft BI shops, but for any business that finds that their reporting datasets invariably end-up in Excel.</p>
<p>If you need any help evaluating PowerPivot or modelling your reporting needs in PowerPivot, <a href="http://www.gobansaor.com/excel-based-bi?dofstar=1"> I&#8217;m for hire</a>.</p>
<p><strong>Update:</strong></p>
<p>Just in case you think I&#8217;m an dimensional-model un-believer or likely to abandon my star-schema roots read this&#8230;.</p>
<p style="padding-left:30px;"><a href="http://blog.gobansaor.com/2010/07/09/star-schemas-to-boldly-go-where-no-excel-spreadsheet-has-gone-before/">Star Schemas: to explore strange new conformed dimensions, to seek out new measures, to boldly go where no Excel spreadsheet has gone before.</a></p>
<p style="padding-left:30px;"><a href='http://twitter.com/gobansaor' class='twitter-follow-button' data-text-color='#333333' data-link-color='#0060ff'>Follow @gobansaor</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gobansaor.wordpress.com/2336/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gobansaor.wordpress.com/2336/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gobansaor.wordpress.com/2336/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gobansaor.wordpress.com/2336/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gobansaor.wordpress.com/2336/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gobansaor.wordpress.com/2336/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gobansaor.wordpress.com/2336/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gobansaor.wordpress.com/2336/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gobansaor.wordpress.com/2336/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gobansaor.wordpress.com/2336/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gobansaor.wordpress.com/2336/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gobansaor.wordpress.com/2336/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gobansaor.wordpress.com/2336/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gobansaor.wordpress.com/2336/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.gobansaor.com&#038;blog=110633&#038;post=2336&#038;subd=gobansaor&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.gobansaor.com/2012/01/19/death-of-the-star-schema/feed/</wfw:commentRss>
		<slash:comments>11</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/2012/01/death-of-a-star.jpg" medium="image">
			<media:title type="html">death of a star</media:title>
		</media:content>
	</item>
		<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&#038;blog=110633&#038;post=2310&#038;subd=gobansaor&#038;ref=&#038;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&#038;blog=110633&#038;post=2310&#038;subd=gobansaor&#038;ref=&#038;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>5</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&#038;blog=110633&#038;post=2264&#038;subd=gobansaor&#038;ref=&#038;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&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&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&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>.  [UPDATE: Feb 2012 - ... or use the <a href="http://blog.gobansaor.com/2012/02/16/javascript-as-an-excel-scripting-language-via-hammer/">JAVASCRIPT command</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&#038;blog=110633&#038;post=2264&#038;subd=gobansaor&#038;ref=&#038;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>5</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>
	</channel>
</rss>
