<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Sergio Pereira : Ruby, Tips-and-Tricks</title><link>http://devlicio.us/blogs/sergio_pereira/archive/tags/Ruby/Tips-and-Tricks/default.aspx</link><description>Tags: Ruby, Tips-and-Tricks</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Excel is the business format, automate it</title><link>http://devlicio.us/blogs/sergio_pereira/archive/2008/06/09/excel-is-the-business-format-automate-it.aspx</link><pubDate>Tue, 10 Jun 2008 03:35:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:40931</guid><dc:creator>sergiopereira</dc:creator><slash:comments>6</slash:comments><description>&lt;p&gt;
	One thing I realized when working in large companies is that Excel is the
	true data exchange file format. That what the business types exchange 
	among themselves and how they like to persist any kind of lists or
	anything that needs to be formatted like a table (be it tabular data or not.)
&lt;/p&gt;
&lt;p&gt;
	All too often one of this documents is forwarded to me  containing some form
	of business data that will become all sorts of things: lookup data, configuration
	values, updates to an existing table, etc.
&lt;/p&gt;
&lt;p&gt;
	I dread these conversion tasks when I have to do them manually so I tend
	to automate the task as soon as it smells like a candidate for recurrence.
	That way I&amp;#39;ll take a hit on the first time and reap the benefits from then on. 
&lt;/p&gt;
&lt;p&gt;
	For some reason I like writing these automation scripts in Ruby. I could probably
	almost as easily write them in VBScript, C#, PowerShell or even VBA but my
	experience with Ruby is that it tends to be shorter (as in more concise) and
	easier to develop. Of course that varies with your level of familiarity with the
	Ruby libraries, but the learning curve isn&amp;#39;t bad at all.
&lt;/p&gt;
&lt;p&gt;
	Consider the following hypothetical layout for an Excel file dropped in your
	inbox for import. 
&lt;/p&gt;
&lt;table border="1" style="border-collapse:collapse;" cellpadding="3" cellspacing="1"&gt;
	&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Price&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Category&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;&lt;td&gt;DVD Player&lt;/td&gt;&lt;td&gt;76.49&lt;/td&gt;&lt;td&gt;Electronics&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Rain Coat&lt;/td&gt;&lt;td&gt;35.10&lt;/td&gt;&lt;td&gt;Men&amp;#39;s apparel&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Code Complete&lt;/td&gt;&lt;td&gt;49.99&lt;/td&gt;&lt;td&gt;Books&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;...&lt;/td&gt;&lt;td&gt;...&lt;/td&gt;&lt;td&gt;...&lt;/td&gt;&lt;td&gt;...&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;&lt;b&gt;120&lt;/b&gt;&lt;/td&gt;&lt;td&gt;24&amp;quot; Monitor&lt;/td&gt;&lt;td&gt;499.99&lt;/td&gt;&lt;td&gt;Computer Accessories&lt;/td&gt;&lt;/tr&gt;	
&lt;/table&gt;
&lt;p&gt;
	My typical script to process such file would be the obvious line-by-line
	read, maybe processing each cell before ultimately converting the row to
	its final format (or skipping that row.) The skeleton of that kind of script
	is shown below.
&lt;/p&gt;
&lt;pre name="code" class="ruby"&gt;require &amp;#39;win32ole&amp;#39;

begin 
  excel_app = WIN32OLE.new(&amp;#39;Excel.Application&amp;#39;)
  book = excel_app.Workbooks.Open(&amp;quot;c:\\project\\data\\datafile.xls&amp;quot;)
  sheet = book.Worksheets(1)
  #first row contains only the headers
  row = 2 #start at the 2nd line (excel is 1-based)

  #stop when we find an empty row
  while sheet.Cells(row, 1).Value
    data = []
    (1..4).each {|c| data[c] = sheet.Cells(row, c).Value }
    #at this point the &amp;#39;data&amp;#39; array contains the entire row
    #use it as desired *********
    
    row += 1
  end
  
rescue 
  #oops...
  puts &amp;quot;There was an error: #{$!}&amp;quot;
ensure
  #cleanup
  excel_app.DisplayAlerts = 0
  book.Close if book
  excel_app.Quit
end&lt;/pre&gt;

&lt;p&gt;
	But, no matter if you use Ruby or any other language, the value in
	automating these tasks can be tremendous. Taking the time to learn
	the basics of Excel automation is, in my opinion, very important
	and will let your users continue to use the tool that they like.
&lt;/p&gt;
&lt;p&gt;
	In a kind of reverse example, I have had occasions when one of
	the business users was repeatedly requesting for some of the
	data in Excel format during the application development (while we
	didn&amp;#39;t have a web page to show that data yet) so, after he asked for
	a updated report for the second time, I created a script to read the
	data from the database, create an Excel file, and send the file attached
	in an email message every Monday morning. Easy way to gain a happy user.
&lt;/p&gt;
Update:  As noted in the comments, one nice reference for automating with Ruby is &lt;a href="http://rubyonwindows.blogspot.com/"&gt;Ruby 
on Windows&lt;/a&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=40931" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Automation/default.aspx">Automation</category></item></channel></rss>