<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-284600789737488130</atom:id><lastBuildDate>Tue, 16 Dec 2025 20:08:11 +0000</lastBuildDate><category>ruby</category><category>windows</category><category>excel</category><category>win32ole</category><category>tools</category><category>word</category><category>outlook</category><category>faq</category><category>ado</category><category>shell</category><category>access</category><category>dotnet</category><category>gui</category><category>ie</category><category>jruby</category><category>powerpoint</category><category>rubygarden</category><category>wxruby</category><category>book</category><category>commentary</category><category>itunes</category><category>sqlserver</category><category>wmi</category><category>api</category><category>books</category><category>modi</category><category>msproject</category><category>ocr</category><category>rubyconf</category><category>site</category><category>sqlite</category><category>vb</category><category>watir</category><category>wmp</category><title>Ruby on Windows</title><description>On using the Ruby programming language on the Microsoft Windows platform</description><link>http://rubyonwindows.blogspot.com/</link><managingEditor>noreply@blogger.com (David Mullet)</managingEditor><generator>Blogger</generator><openSearch:totalResults>112</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-991719303909503936</guid><pubDate>Sat, 03 Mar 2012 13:00:00 +0000</pubDate><atom:updated>2012-03-03T08:00:23.029-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ado</category><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>ADO, Excel, and Data Types</title><description>I&#39;ve &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/06/using-ruby-ado-to-work-with-excel.html&quot; target=&quot;_blank&quot;&gt;written before&lt;/a&gt; about using Ruby with Microsoft&#39;s ADO technology to query Excel workbooks as databases.&lt;br /&gt;
&lt;br /&gt;
This works well---most of the time. But you may occasionally bump into data type issues, where you find that Excel/ADO treat a specific column as a different data type than you expected.&lt;br /&gt;
&lt;br /&gt;
For this reason, I recommend using a collection of ADO functions that will expressly convert a value to a specific data type. These ADO functions include:&lt;br /&gt;
&lt;br /&gt;
CStr(x) - Converts x to a String value&lt;br /&gt;
CDec(x) - Converts x to a Decimal value&lt;br /&gt;
CInt(x) - Converts x to an Integer value&lt;br /&gt;
CDate(x) - Converts x to a Date value&lt;br /&gt;
CCur(x) - Converts x to a Currency value &lt;br /&gt;
&lt;br /&gt;
For example, instead of assuming that the ORDER_NUMBER field would be treated as a string...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT * FROM ORDERS WHERE ORDER_NUMBER = &#39;12345&#39; ;&lt;br /&gt;
&lt;br /&gt;
...call the &lt;i&gt;CStr()&lt;/i&gt; function on it to ensure a string-to-string comparison:&lt;br /&gt;
&lt;br /&gt;



&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT * FROM ORDERS WHERE CStr(ORDER_NUMBER) = &#39;12345&#39; ;&lt;br /&gt;

&lt;br /&gt;

It&#39;s a few extra keystrokes that could save you time---and frustration---in the long run.&lt;br /&gt;
&lt;br /&gt;
More information can be found &lt;a href=&quot;http://office.microsoft.com/en-us/access-help/type-conversion-functions-HA001229018.aspx&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://rubyonwindows.blogspot.com/2012/03/ado-excel-and-data-types.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-4380391068956869759</guid><pubDate>Sat, 03 Sep 2011 00:27:00 +0000</pubDate><atom:updated>2011-09-02T19:50:36.494-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">outlook</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>Automating Outlook with Ruby: Saving Mail Messages To Files</title><description>I&#39;ve talked in the past about &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/08/automating-outlook-with-ruby-inbox.html&quot;&gt;managing mail messages in your Inbox&lt;/a&gt;, and about &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/12/automating-outlook-with-ruby-saving.html&quot;&gt;saving email attachments to your hard drive&lt;/a&gt;. A reader recently asked about saving a mail message as a file on your hard drive.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This can be done by calling the MailItem&#39;s &lt;b&gt;&lt;i&gt;SaveAs()&lt;/i&gt;&lt;/b&gt; method. This method takes two arguments. The first argument is a string indicating the full path and filename to which you want to save the message. The second argument is an integer that indicates the file type.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let&#39;s look at a brief example that saves an Inbox message as an HTML file:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;div&gt;require &#39;win32ole&#39;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;olHTML = 5&lt;/div&gt;&lt;div&gt;outlook = WIN32OLE.connect(&quot;Outlook.Application&quot;)&lt;/div&gt;&lt;div&gt;mapi = outlook.GetNameSpace(&quot;MAPI&quot;)&lt;/div&gt;&lt;div&gt;inbox  = mapi.GetDefaultFolder(6)&lt;/div&gt;&lt;div&gt;msg = inbox.Items(2)&lt;/div&gt;&lt;div&gt;msg.SaveAs(&#39;c:\temp\message.htm&#39;, olHTML)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Further details on the &lt;i&gt;SaveAs()&lt;/i&gt; method can be found &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa210279(v=office.11).aspx&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;A full list of valid file type values can be found &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb208132(v=office.12).aspx&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That&#39;s all for now. Questions? Comments? Suggestions? Post a comment or send me an email.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks for stopping by!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>http://rubyonwindows.blogspot.com/2011/09/automating-outlook-with-ruby-saving.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-4063553665855177187</guid><pubDate>Wed, 16 Mar 2011 12:01:00 +0000</pubDate><atom:updated>2011-03-17T07:00:56.411-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jruby</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>JRuby 1.6: Now With Win32OLE Goodness</title><description>JRuby 1.6 has just been released and, among the many new features, the JRuby installer for Windows now includes the win32ole library. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is good news for those of us that frequently use Ruby&#39;s win32ole module to  automate &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/excel&quot;&gt;Excel&lt;/a&gt;, &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/word&quot;&gt;Word&lt;/a&gt;, and a variety of other Windows applications and processes. Now you have the option of running your code on the JVM.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And running on the JVM opens up a world of possibilities. You could, for example, whip up a Swing GUI via &lt;a href=&quot;http://www.monkeybars.org/&quot;&gt;Monkeybars&lt;/a&gt;, and use &lt;a href=&quot;https://github.com/rawr/rawr&quot;&gt;Rawr&lt;/a&gt; to package it up as an EXE file for ease of distribution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Interested? Download JRuby 1.6 at &lt;a href=&quot;http://www.jruby.org/&quot;&gt;jruby.org&lt;/a&gt;, take the win32ole module for a drive around the block, and let me know if you hit any potholes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>http://rubyonwindows.blogspot.com/2011/03/jruby-16-now-with-win32ole-goodness.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>10</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-7200025808742269936</guid><pubDate>Mon, 07 Feb 2011 13:49:00 +0000</pubDate><atom:updated>2011-02-07T09:01:39.922-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">tools</category><title>Ruby on NetBeans: Here Comes the Cavalry</title><description>As &lt;a href=&quot;http://rubyonwindows.blogspot.com/2011/01/netbeans-drops-support-for-ruby-and.html&quot;&gt;recently reported&lt;/a&gt;, the NetBeans IDE team has decided to drop support for Ruby (and Rails) from NetBeans 7.0.&lt;br /&gt;&lt;br /&gt;I have received many good suggestions from readers, with RedCar and RubyMine getting a lot of love.&lt;br /&gt;&lt;br /&gt;But wait! What&#39;s that? It sounds like trumpets off in the distance... and hoofbeats.&lt;br /&gt;&lt;br /&gt;Indeed, Tom Enebo is leading the cavalry to save the day, as he &lt;a href=&quot;http://www.ruby-forum.com/topic/999516&quot;&gt;reported in the JRuby forum&lt;/a&gt; recently:&lt;br /&gt;&lt;blockquote&gt;I have been talking to Netbeans team about us adopting the project and this is a done deal.  Putting together some details and you should see a blog post about this in the next few days.  So, if you like using Netbeans dont worry, it will still be an available option in the plugins catalog (not sure about the full Ruby product as an independent download from netbeans site yet).&lt;/blockquote&gt;Good news for all those that would like to continue to use NetBeans with Ruby.&lt;br /&gt;&lt;br /&gt;Thanks, Tom!</description><link>http://rubyonwindows.blogspot.com/2011/02/ruby-on-netbeans-here-comes-cavalry.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-8132987099027460927</guid><pubDate>Thu, 27 Jan 2011 13:27:00 +0000</pubDate><atom:updated>2011-01-27T08:43:26.746-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">tools</category><title>NetBeans Drops Support for Ruby and Rails</title><description>The NetBeans team has, unfortunately, decided to &lt;a href=&quot;http://netbeans.org/community/news/show/1507.html&quot;&gt;remove Ruby and Rails support&lt;/a&gt; from the NetBeans IDE:&lt;div&gt;&lt;blockquote&gt;After thorough consideration, we have taken the difficult step to discontinue support for Ruby on Rails in the NetBeans IDE.&lt;/blockquote&gt;&lt;blockquote&gt;As of January 27, the Ruby on Rails module will be gone from development builds of NetBeans IDE 7.0. &lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;NetBeans has served me well for larger projects over the years, and NetBeans 6.9.1 retains its existing support for Ruby and Rails. But perhaps it&#39;s time to start considering Ruby IDE alternatives, and I&#39;m open to suggestions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description><link>http://rubyonwindows.blogspot.com/2011/01/netbeans-drops-support-for-ruby-and.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>13</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-6264382848717731112</guid><pubDate>Sun, 26 Sep 2010 22:48:00 +0000</pubDate><atom:updated>2010-09-26T18:04:04.109-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>Coming Soon: win32ole for JRuby</title><description>FYI: In a &lt;a href=&quot;http://www.ruby-forum.com/topic/217489&quot;&gt;recent Ruby Forum thread&lt;/a&gt;, Charles Nutter wrote:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;FWIW, a win32ole library is in development and should be in JRuby for 1.6.&lt;/blockquote&gt;&lt;br /&gt;This is good news for those of us who do a lot of work with the standard Ruby win32ole library.&lt;br /&gt;&lt;br /&gt;My sincere thanks to all who are helping to make this happen.</description><link>http://rubyonwindows.blogspot.com/2010/09/coming-soon-win32ole-for-jruby.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-7897806512118306482</guid><pubDate>Sat, 28 Aug 2010 19:03:00 +0000</pubDate><atom:updated>2010-08-28T14:21:59.134-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">tools</category><title>New Ruby IDE Discussion Group</title><description>FYI, Ed Howland has launched a new &lt;a href=&quot;http://groups.google.com/group/ruby-ide&quot;&gt;Ruby IDE discussion group&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;I set this group up to focus discussions about a community developed IDE written in Ruby (but not necessarily limited to writing code in just that language. The intent is to take general discussion specific off-line from the main ruby-talk group  Hopefully, this will be a high signal-noise ratio discussion. &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;So if you&#39;ve got some constructive thoughts on what would be the ideal Ruby IDE, make yourself heard here:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;a href=&quot;http://groups.google.com/group/ruby-ide&quot;&gt;http://groups.google.com/group/ruby-ide&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;David</description><link>http://rubyonwindows.blogspot.com/2010/08/new-ruby-ide-discussion-group.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-4914404293017560544</guid><pubDate>Wed, 10 Feb 2010 12:59:00 +0000</pubDate><atom:updated>2010-02-11T09:45:14.014-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">powerpoint</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>Ruby &amp; PowerPoint: Inserting HyperLinks</title><description>I&#39;ve &lt;a href=&quot;http://rubyonwindows.blogspot.com/2008/08/automating-powerpoint-with-ruby.html&quot;&gt;written previously&lt;/a&gt; about automating &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/powerpoint&quot;&gt;Microsoft PowerPoint&lt;/a&gt; with Ruby.  Someone recently asked how to use Ruby code to insert hyperlinks into a PowerPoint slide.  Let&#39;s take a look now at how this can be done.&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;&lt;br /&gt;Setting the Scene&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Let&#39;s quickly review the code that will launch PowerPoint...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;ppt = WIN32OLE.new(&#39;PowerPoint.Application&#39;)&lt;br /&gt;ppt.Visible = true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...create a new presentation...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;doc = ppt.Presentations.Add()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...add a new slide...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;slide = doc.Slides.Add(1, 2)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...and insert text into each of the two textboxes...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;slide.Shapes(1).TextFrame.TextRange.Text = &quot;Ruby on Windows&quot;&lt;br /&gt;slide.Shapes(2).TextFrame.TextRange.Text = &quot;Ruby on Windows: PowerPoint&quot;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To fully understand the above code, you may want to read &lt;a href=&quot;http://rubyonwindows.blogspot.com/2008/08/automating-powerpoint-with-ruby.html&quot;&gt;this article&lt;/a&gt;, if you haven&#39;t already.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;ActionSettings and HyperLinks&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;OK, now we have a PowerPoint presentation with a slide containing two textboxes, and we&#39;re ready to make the text of the second textbox a hyperlink.  Let&#39;s grab a reference to the TextRange object that holds the text contained in the second textbox (a Shape object) on the slide:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;text_range = slide.Shapes(2).TextFrame.TextRange &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To define the action that is to be taken when a TextRange object is clicked, we need to work with the first item in the TextRange&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;ActionSettings &lt;/span&gt;collection:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;action = text_range.ActionSettings(1)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This returns the &lt;span style=&quot;font-style:italic;&quot;&gt;ActionSetting &lt;/span&gt;object that represents a MouseClick action. This ActionSetting object includes a &lt;span style=&quot;font-style:italic;&quot;&gt;HyperLink &lt;/span&gt;object...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;link = action.Hyperlink&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...and it is the properties of this HyperLink object that we will modify to result in a link to our website:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;link.Address = &quot;http://rubyonwindows.blogspot.com/search/label/powerpoint&quot;&lt;br /&gt;link.ScreenTip = &quot;Click to go to website&quot;&lt;br /&gt;link.TextToDisplay = &quot;Ruby on Windows: PowerPoint&quot;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Our complete code looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;&lt;br /&gt;ppt = WIN32OLE.new(&#39;PowerPoint.Application&#39;)&lt;br /&gt;ppt.Visible = true&lt;br /&gt;doc = ppt.Presentations.Add()&lt;br /&gt;&lt;br /&gt;slide = doc.Slides.Add(1, 2)&lt;br /&gt;slide.Shapes(1).TextFrame.TextRange.Text = &quot;Ruby on Windows&quot;&lt;br /&gt;slide.Shapes(2).TextFrame.TextRange.Text = &quot;Ruby on Windows: PowerPoint&quot;&lt;br /&gt;&lt;br /&gt;text_range = slide.Shapes(2).TextFrame.TextRange &lt;br /&gt;action = text_range.ActionSettings(1)&lt;br /&gt;link = action.Hyperlink&lt;br /&gt;&lt;br /&gt;link.Address = &quot;http://rubyonwindows.blogspot.com/search/label/powerpoint&quot;&lt;br /&gt;link.ScreenTip = &quot;Click to go to website&quot;&lt;br /&gt;link.TextToDisplay = &quot;Ruby on Windows: PowerPoint&quot;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That&#39;s all for now, but feel free to post a comment here or send me email with questions, comments, or suggested topics.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2010/02/ruby-powerpoint-inserting-hyperlinks.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-3029044052381771110</guid><pubDate>Sun, 24 Jan 2010 12:55:00 +0000</pubDate><atom:updated>2010-01-24T07:56:04.535-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">powerpoint</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><category domain="http://www.blogger.com/atom/ns#">word</category><title>Saving Microsoft Office Documents as PDFs</title><description>A recent discussion in the Ruby Forum reminded me that it is possible with Microsoft Office 2007 applications to save a document in Adobe PDF format.&lt;br /&gt;&lt;br /&gt;In the &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/word&quot;&gt;Microsoft Word&lt;/a&gt; object model, you can call the Document object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;SaveAs()&lt;/span&gt; method, passing it a filename, and the document will be saved in the default format.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;document.SaveAs(&#39;c:\temp\MyDocument.doc&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But the &lt;span style=&quot;font-style:italic;&quot;&gt;SaveAs()&lt;/span&gt; method accepts an optional second parameter, an integer that specifies the file format.  In the Word object model, the PDF format is represented by the value &lt;span style=&quot;font-style:italic;&quot;&gt;17&lt;/span&gt;.  So, where &lt;span style=&quot;font-style:italic;&quot;&gt;document &lt;/span&gt;represents your Document object, you can do the following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;document.SaveAs(&#39;c:\temp\MyDocument.pdf&#39;, 17)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/excel&quot;&gt;Microsoft Excel&lt;/a&gt;, the Workbook object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;SaveAs()&lt;/span&gt; method accepts the value &lt;span style=&quot;font-style:italic;&quot;&gt;57&lt;/span&gt; to specify PDF format:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;workbook.SaveAs(&#39;c:\temp\MyWorkbook.pdf&#39;, 57)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And in &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/powerpoint&quot;&gt;Microsoft PowerPoint&lt;/a&gt;, the magic number is 32:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;presentation.SaveAs(&#39;c:\temp\MyPresentation.pdf&#39;, 32)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can find enumerations for file types over at MSDN:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb238158.aspx&quot;&gt;Microsoft Word&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb241279.aspx&quot;&gt;Microsoft Excel&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb251061.aspx&quot;&gt;Microsoft PowerPoint&lt;/a&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;A tip of the hat to Joe Peck for &lt;a href=&quot;http://www.ruby-forum.com/topic/202700&quot;&gt;mentioning this&lt;/a&gt; in the Ruby Forum.&lt;br /&gt;&lt;br /&gt;Let me know if you have any questions or comments, and thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2010/01/saving-microsoft-office-documents-as.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>10</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-2662284314841581355</guid><pubDate>Wed, 20 Jan 2010 12:57:00 +0000</pubDate><atom:updated>2010-01-20T08:26:46.156-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><category domain="http://www.blogger.com/atom/ns#">word</category><title>Connecting to One of Many Open Documents</title><description>If you&#39;ve hung around here for a little while, then you probably already know that you can use the &lt;span style=&quot;font-style:italic;&quot;&gt;WIN32OLE.connect()&lt;/span&gt; method to connect to a running instance of applications like &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/word&quot;&gt;Microsoft Word&lt;/a&gt;.  Just pass the method the ProgID of the Application object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;word = WIN32OLE.connect(&#39;Word.Application&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That works great if you have just one instance of the application running, with one or multiple documents open.  But suppose you have multiple instances of the application running?  How can you be sure that you connect to the instance with Document B, and not the instance with Document A?&lt;br /&gt;&lt;br /&gt;Well, assuming that Document B has been saved and you know the full filename, then you can connect to the &lt;span style=&quot;font-style:italic;&quot;&gt;Document &lt;/span&gt;object, rather than to the &lt;span style=&quot;font-style:italic;&quot;&gt;Application &lt;/span&gt;object.  And you do this by passing the &lt;span style=&quot;font-style:italic;&quot;&gt;WIN32OLE.connect()&lt;/span&gt; method the full filename:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;document = WIN32OLE.connect(&#39;C:\Path To File\DocumentB.doc&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This returns an instance of the &lt;span style=&quot;font-style:italic;&quot;&gt;Word.Document&lt;/span&gt; object. You can then grab &lt;br /&gt;an instance of that Document&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Application &lt;/span&gt;object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;word = document.Application&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This works with other multiple-instance applications, such as &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/excel&quot;&gt;Excel&lt;/a&gt;.  The following code connects to a specific instance of an &lt;span style=&quot;font-style:italic;&quot;&gt;Excel.Workbook&lt;/span&gt; object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;workbook = WIN32OLE.connect(&#39;C:\Path To File\WorkbookB.xls&#39;)&lt;br /&gt;xl = workbook.Application&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;By the way, some applications, such as &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/powerpoint&quot;&gt;PowerPoint&lt;/a&gt;, are single-instance applications, so there will never be multiple instances of the application running, avoiding the need to use the process outlined above.&lt;br /&gt;&lt;br /&gt;There you have it.  Please let me know if you have specific questions or suggestions for future articles.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/12/connecting-to-one-of-many-open.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-4143908943123542982</guid><pubDate>Thu, 14 Jan 2010 13:11:00 +0000</pubDate><atom:updated>2010-01-14T09:01:05.021-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">itunes</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>Creating an iTunes Song Inventory in Excel</title><description>I&#39;ve talked in the past about automating &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/itunes&quot;&gt;iTunes&lt;/a&gt;, and about automating &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/excel&quot;&gt;Excel&lt;/a&gt;. Let&#39;s now look at how to use Ruby to produce an iTunes report in Excel. Our finished product will be a sorted worksheet containing Artist, Year, Album, and Song Name.&lt;br /&gt;&lt;br /&gt;As usual, we&#39;ll be working with the &lt;span style=&quot;font-style:italic;&quot;&gt;win32ole &lt;/span&gt;library, so include the following at the top of your code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next, we want to launch the iTunes application using the &lt;span style=&quot;font-style:italic;&quot;&gt;WIN32OLE.new()&lt;/span&gt; method:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;itunes = WIN32OLE.new(&#39;iTunes.Application&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We&#39;ll create an array to hold the iTunes Library data:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;data = []&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The following code iterates over the iTunes &lt;span style=&quot;font-style:italic;&quot;&gt;LibraryPlaylist.Tracks &lt;/span&gt;collection. For each track in the library that is not a podcast, our code adds a row to the &lt;span style=&quot;font-style:italic;&quot;&gt;data &lt;/span&gt;array containing Artist, Year, Album, and Year, all of which are properties of the Track object.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;itunes.LibraryPlaylist.Tracks.each do |track|&lt;br /&gt;  if not track.Podcast&lt;br /&gt;    data &lt;&lt; [track.Artist, track.Year, track.Album, track.Name]&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To include podcasts in your report, simply remove the &lt;span style=&quot;font-style:italic;&quot;&gt;Podcast &lt;/span&gt;conditional:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;itunes.LibraryPlaylist.Tracks.each do |track|&lt;br /&gt;  data &lt;&lt; [track.Artist, track.Year, track.Album, track.Name]&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now that we have our data array, let&#39;s sort it...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;data.sort!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...and then insert a row of field names as the first row:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;data.insert(0, [&#39;ARTIST&#39;, &#39;YEAR&#39;, &#39;ALBUM&#39;, &#39;NAME&#39;])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next, we&#39;ll launch a new instance of Excel, assigning it to the &lt;span style=&quot;font-style:italic;&quot;&gt;xl &lt;/span&gt;variable...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;xl = WIN32OLE.new(&#39;Excel.Application&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...and make the application window visible:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;xl.Visible = true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We create a new workbook by calling the Application object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Workbooks.Add()&lt;/span&gt; method...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wb = xl.Workbooks.Add()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...and we get a reference to the first worksheet in the Workbook object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Worksheets &lt;/span&gt;collection:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ws = wb.Worksheets(1)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now we&#39;re ready to &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-excel-with-ruby-defining.html&quot;&gt;insert our data into a range of cells&lt;/a&gt;. We&#39;ll define a Range of cells that begins at cell A1. We&#39;ll call the &lt;span style=&quot;font-style:italic;&quot;&gt;Range.Resize()&lt;/span&gt; method to resize the Range to fit the number of rows (data.size) and the number of columns (data.first.size) in our data array.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rng = ws.Range(&#39;A1&#39;).Resize(data.size, data.first.size)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then we insert our data:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rng.Value = data&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Finally, we&#39;ll do a wee bit of formatting, making the first row bold...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ws.Rows(1).Font.Bold = true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...and adding AutoFilter drop-down lists to the column headers...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ws.Rows(1).AutoFilter()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There&#39;s a variety of other formatting you could apply, as discussed &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/06/automating-excel-with-ruby-formatting.html&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That&#39;s all for now, but feel free to post a comment here or send me email with questions, comments, or suggested topics.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2010/01/creating-itunes-song-inventory-in-excel.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-5544902475478065216</guid><pubDate>Mon, 24 Aug 2009 11:45:00 +0000</pubDate><atom:updated>2009-08-24T08:37:35.453-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><category domain="http://www.blogger.com/atom/ns#">word</category><title>Ruby &amp; Word: Inserting Pictures Into Documents</title><description>In &lt;a href=&quot;http://rubyonwindows.blogspot.com/2009/08/ruby-excel-inserting-pictures-into.html&quot;&gt;an earlier article&lt;/a&gt;, I explained how to insert an image into a range of cells in an Excel worksheet. Today we&#39;ll look at how to insert an image into a Word document.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Setting the Scene&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Feel free to play along at home: Imagine that you have a Word document already open...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;word = WIN32OLE.connect(&#39;Word.Application&#39;)&lt;br /&gt;doc = word.ActiveDocument&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...and you want to insert an image from your PC...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;image = &#39;C:\Pictures\Picture1.jpg&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...into a given Range object in the document:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;range = doc.Sentences(2)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;The InlineShapes Collection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;InlineShapes &lt;/span&gt;object represents a collection of pictures, OLE objects, and ActiveX controls contained within a given &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-word-with-ruby-document.html&quot;&gt;Document&lt;/a&gt; or &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-word-with-ruby-range-object.html&quot;&gt;Range&lt;/a&gt; object.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;The AddPicture() Method&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To insert an image into a document or range, we call the &lt;span style=&quot;font-style:italic;&quot;&gt;AddPicture()&lt;/span&gt; method on the &lt;span style=&quot;font-style:italic;&quot;&gt;InlineShapes &lt;/span&gt;collection. This method accepts up to four parameters:&lt;br /&gt;&lt;br /&gt;* &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;FileName &lt;/span&gt;&lt;/span&gt;(required) - The full path and filename of the image to insert.&lt;br /&gt;&lt;br /&gt;* &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;LinkToFile &lt;/span&gt;&lt;/span&gt;(optional) - If &lt;span style=&quot;font-style:italic;&quot;&gt;true &lt;/span&gt;the inserted picture will be linked to the file from which it was created. You&#39;ll usually set this to &lt;span style=&quot;font-style:italic;&quot;&gt;false &lt;/span&gt;to make the picture an independent copy of the file. The default value is &lt;span style=&quot;font-style:italic;&quot;&gt;false&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;* &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;SaveWithDocument &lt;/span&gt;&lt;/span&gt;(optional) - Set to &lt;span style=&quot;font-style:italic;&quot;&gt;true &lt;/span&gt;to save the linked picture with the document. The default is &lt;span style=&quot;font-style:italic;&quot;&gt;false&lt;/span&gt;. This value will be ignored unless &lt;span style=&quot;font-style:italic;&quot;&gt;LinkToFile &lt;/span&gt;is set to &lt;span style=&quot;font-style:italic;&quot;&gt;true&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;* &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Range &lt;/span&gt;&lt;/span&gt;(optional) - A Range object representing the position in which to insert the picture.&lt;br /&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;AddPicture()&lt;/span&gt; method returns a reference to the newly created InlineShape object that is your picture.&lt;br /&gt;&lt;br /&gt;So, to insert an image at the start of the range that we defined earlier, we could call the method on our &lt;span style=&quot;font-style:italic;&quot;&gt;range &lt;/span&gt;object...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;range = doc.Sentences(2)&lt;br /&gt;pic = range.InlineShapes.AddPicture( { &#39;FileName&#39; =&gt; image } )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...or we could call it on the Document object and pass the Range object as a parameter:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;range = doc.Sentences(2)&lt;br /&gt;pic = doc.InlineShapes.AddPicture( { &#39;FileName&#39; =&gt; image, &lt;br /&gt;                                     &#39;Range&#39; =&gt; range } )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When providing all four parameters, the syntax looks like this:&lt;br /&gt;&lt;pre&gt;    &lt;br /&gt;pic = doc.InlineShapes.AddPicture( { &#39;FileName&#39; =&gt; image, &lt;br /&gt;                                     &#39;LinkToFile&#39; =&gt; false, &lt;br /&gt;                                     &#39;SaveWithDocument&#39; =&gt; false, &lt;br /&gt;                                     &#39;Range&#39; =&gt; range } )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If your only parameter is the FileName, you could bypass the hash format and simply pass the string to the method, like this...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic = range.InlineShapes.AddPicture( &#39;C:\Pictures\Picture1.jpg&#39; )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To insert the image at the currently selected position, use the &lt;span style=&quot;font-style:italic;&quot;&gt;word.Selection.Range&lt;/span&gt; object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic = word.Selection.Range.InlineShapes.AddPicture( image )&lt;br /&gt;pic = doc.InlineShapes.AddPicture( { &#39;FileName&#39; =&gt; image, &lt;br /&gt;                                     &#39;Range&#39; =&gt; word.Selection.Range } )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that&#39;s our show for today. Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/08/ruby-word-inserting-pictures-into.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-7252018167599528782</guid><pubDate>Thu, 20 Aug 2009 11:38:00 +0000</pubDate><atom:updated>2009-08-20T07:50:57.277-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">book</category><title>About the Book</title><description>A few readers have asked me for details on the book-in-progress.&lt;br /&gt;&lt;br /&gt;The working title is &quot;Automating Windows Applications with Ruby&quot;. As the title implies, the focus is on automating applications, usually via Win32OLE/COM.&lt;br /&gt;&lt;br /&gt;This is not an &quot;Introduction to Ruby&quot; book: I make the assumption that the reader already has a working knowledge of the language and now wants to put it to good use driving applications and processes on Windows.  Some of the topics covered include:&lt;br /&gt;&lt;br /&gt;* Microsoft Excel&lt;br /&gt;* Microsoft Word&lt;br /&gt;* Microsoft Outlook&lt;br /&gt;* Microsoft PowerPoint&lt;br /&gt;* Database Access with ADO&lt;br /&gt;* Microsoft Access&lt;br /&gt;* Microsoft SQL Server&lt;br /&gt;* Microsoft Internet Explorer&lt;br /&gt;* Microsoft Office Document Imaging (OCR)&lt;br /&gt;* iTunes&lt;br /&gt;* Windows Media Player&lt;br /&gt;* Text-to-Speech&lt;br /&gt;* Microsoft Agent&lt;br /&gt;* Hummingbird HostExplorer&lt;br /&gt;* Attachmate Extra&lt;br /&gt;* Windows Management Instrumentation&lt;br /&gt;&lt;br /&gt;Each chapter will include step-by-step tutorials, and many chapters will also include a reference section covering commonly-used classes, properties, and methods.  Some chapters are extensive, while others may be only a few pages in length.&lt;br /&gt;&lt;br /&gt;This isn&#39;t intended to be an &quot;Everything You&#39;d Ever Want To Know About...&quot; resource, but it is my intention to provide you with a book that will serve as both a quick-start guide and a go-to reference for automating a wide variety of applications.&lt;br /&gt;&lt;br /&gt;Stay tuned...</description><link>http://rubyonwindows.blogspot.com/2009/08/about-book.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>12</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-6432464328814526112</guid><pubDate>Wed, 05 Aug 2009 12:26:00 +0000</pubDate><atom:updated>2009-08-05T07:59:24.966-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>Ruby &amp; Excel: Inserting Pictures Into Cells (New and Improved!)</title><description>In &lt;a href=&quot;http://rubyonwindows.blogspot.com/2009/07/ruby-excel-inserting-pictures-into.html&quot;&gt;a previous article&lt;/a&gt;, I discussed a method for inserting images into an Excel worksheet. It seems that the &lt;span style=&quot;font-style:italic;&quot;&gt;Worksheet.Pictures.Insert()&lt;/span&gt; method that I demonstrated in that article, though frequently used, is not actually officially documented in the Excel Object Model Reference. An astute reader has called my attention to this fact and, in reply, I hereby present the officially documented---and probably preferred---method for adding an image to a worksheet.&lt;br /&gt;&lt;br /&gt;The Worksheet object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Shapes &lt;/span&gt;collection includes an &lt;span style=&quot;font-style:italic;&quot;&gt;AddPicture()&lt;/span&gt; method that creates a picture from an existing file and returns a Shape object that represents the new picture. The syntax is:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;.AddPicture(Filename, LinkToFile, SaveWithDocument, Left, Top, Width, Height)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;All seven arguments are required, but this allows you to specify the position and size of the picture in the method call.&lt;br /&gt;&lt;br /&gt;The following code inserts an image into the range of cells from C3 to F5 in the active worksheet:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;&lt;br /&gt;xl = WIN32OLE.connect(&#39;Excel.Application&#39;)&lt;br /&gt;ws = xl.ActiveSheet&lt;br /&gt;&lt;br /&gt;range = ws.Range(&#39;C3:F5&#39;)&lt;br /&gt;&lt;br /&gt;pic = ws.Shapes.AddPicture( { &lt;br /&gt;    &#39;FileName&#39; =&gt; &#39;C:\Pictures\Image1.jpg&#39;, &lt;br /&gt;    &#39;LinkToFile&#39; =&gt; false, &lt;br /&gt;    &#39;SaveWithDocument&#39; =&gt; true, &lt;br /&gt;    &#39;Left&#39; =&gt; range.Left, &lt;br /&gt;    &#39;Top&#39; =&gt; range.Top, &lt;br /&gt;    &#39;Width&#39; =&gt; range.Width, &lt;br /&gt;    &#39;Height&#39; =&gt; range.Height &lt;br /&gt;} )&lt;br /&gt;    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can find further details on the AddPicture() method on &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb209605.aspx&quot;&gt;MSDN&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;My thanks to Charles Roper for his inquiry, prompting me to dig a little deeper.&lt;br /&gt;&lt;br /&gt;And my thanks to you for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/08/ruby-excel-inserting-pictures-into.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-2136933897701255202</guid><pubDate>Sun, 02 Aug 2009 20:33:00 +0000</pubDate><atom:updated>2009-08-02T15:38:27.428-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">modi</category><category domain="http://www.blogger.com/atom/ns#">ocr</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>OCR: Converting Images to Text with MODI</title><description>Joe Schmoe from Kokomo has a scanned image of a 300-page contract.  Joe wishes he could search this file for certain rates and terms, but it&#39;s an image, not a text file.  &lt;span style=&quot;font-weight:bold;&quot;&gt;OCR &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;/span&gt;&lt;/span&gt;might be just what the doctor ordered.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style:italic;&quot;&gt;Optical character recognition, usually abbreviated to OCR, is the mechanical or electronic translation of images of handwritten, typewritten or printed text (usually captured by a scanner) into machine-editable text.&lt;/span&gt; --&lt;a href=&quot;http://en.wikipedia.org/wiki/Optical_character_recognition&quot;&gt;Wikipedia&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One such OCR solution that you may already have available to you is Microsoft Office Document Imaging (MODI), part of the Microsoft Office suite.  Let&#39;s look at how you can use Ruby and the MODI API to automate the conversion of a scanned document into text.&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;&lt;br /&gt;Installing MODI&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;MODI might not have been installed when you installed Microsoft Office, so your first step may be to install it from the Office install disks.  If installed, you will probably find an icon for &quot;Microsoft Office Document Imaging&quot; located on your Windows Start/Programs menus under &quot;Microsoft Office Tools&quot;.  If it&#39;s not there, go to your Add/Remove Software control panel, select your Microsoft Office installation, and select the option to add features.  Then follow the necessary steps, which may vary depending on your version of Windows and Office.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Accessing the MODI API&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To begin with, we&#39;ll use the &lt;span style=&quot;font-style:italic;&quot;&gt;win32ole&lt;/span&gt; module to create a new instance of the &lt;span style=&quot;font-style:italic;&quot;&gt;MODI.Document&lt;/span&gt; object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;doc = WIN32OLE.new(&#39;MODI.Document&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Loading the Image&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The next step is to call the document object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Create()&lt;/span&gt; method, passing it the name of the .TIF file to load:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;doc.Create(&#39;C:\images\image1.tif&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;NOTE: MODI only works with TIFF files.  If your image is in another format (.JPG or .PNG, for example), you can use an image editor (such as Paint.NET or Photoshop) or code library (such as RMagick) to convert it to TIFF format.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Performing the OCR&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;OCR()&lt;/span&gt; method performs the optical character recognition on the document.  The mthod can be called without parameters...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;doc.OCR()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...or with any of three optional parameters:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;doc.OCR( { &#39;LangId&#39; =&gt; 9, &lt;br /&gt;           &#39;OCROrientImage&#39; =&gt; true, &lt;br /&gt;           &#39;OCRStraightenImage&#39; =&gt; true } )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-style:italic;&quot;&gt;LangId&lt;/span&gt;: An integer representing the language of the document.  English = 9, French = 12, German = 7, Italian = 16, Spanish = 10.  This value defaults to the user&#39;s regional settings.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style:italic;&quot;&gt;OCROrientImage&lt;/span&gt;: This boolean value specifies whether the OCR engine attempts to determine the orientation (portrait versus landscape) of the page.  The value defaults to &lt;span style=&quot;font-style:italic;&quot;&gt;true&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style:italic;&quot;&gt;OCRStraightenImage&lt;/span&gt;: This boolean value specifies whether the OCR engine attempts to &quot;deskew&quot; the image to correct minor misalignments.  The value defaults to &lt;span style=&quot;font-style:italic;&quot;&gt;true&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;You may find that tweaking these parameters from their default values produces better results, depending on the individual image(s) you&#39;re working with.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Getting the Text&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Naturally, you&#39;ll want to get your hands on the text produced by the OCR process.  Each page of the Document is represented by an Image object.  The Image object contains a Layout object; and that Layout object&#39;s Text property represents the text for that image/page.  So the hierarchy looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Document&lt;br /&gt;    =&gt;Images&lt;br /&gt;        =&gt;Image&lt;br /&gt;            =&gt;Layout&lt;br /&gt;                =&gt;Text&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To accrue the entire text, simply iterate over the Document.Images collection and grab the Layout.Text values.  For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;File.open(&#39;my_text.txt&#39;, &#39;w&#39;) do |f|&lt;br /&gt;    for image in doc.Images&lt;br /&gt;        f.puts(&quot;\n&quot; + image.Layout.Text + &quot;\n&quot;)&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Text, But Not Formatting&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;No OCR process can guarantee 100% accuracy, but I&#39;ve found that MODI does a pretty good job recognizing text.  Results will vary, of course, depending on the quality of the TIFF image.  Note, however, that it cannot preserve formatting of tabular data.  So while the text in a series of columns may be produced with a high degree of accuracy, that text will probably be produced with one value per line.  So...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;apple    orange    pear&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...comes out as...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;apple&lt;br /&gt;orange&lt;br /&gt;pear&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Paragraphs of text have, in my experience, been produced with the proper line feeds.  Play around with it and see if it meets your needs.&lt;br /&gt;&lt;br /&gt;That concludes our show for today.  Thanks for tuning in!</description><link>http://rubyonwindows.blogspot.com/2009/08/ocr-converting-images-to-text-with-modi.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-1910133545778414753</guid><pubDate>Sun, 12 Jul 2009 23:01:00 +0000</pubDate><atom:updated>2009-08-05T08:07:33.098-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>Ruby &amp; Excel: Inserting Pictures Into Cells</title><description>A reader recently asked how to insert an image from their PC into a cell in an Excel worksheet. So if you have a couple of minutes, I&#39;ll demonstrate how to insert an image, specify the exact position, and resize the image.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;UPDATE:&lt;/span&gt; It seems that the Worksheet.Pictures.Insert() method that I demonstrated below, though frequently used, is not actually officially documented in the Excel Object Model Reference. See &lt;a href=&quot;http://rubyonwindows.blogspot.com/2009/08/ruby-excel-inserting-pictures-into.html&quot;&gt;this newer article&lt;/a&gt; for the officially documented method.&lt;br /&gt;&lt;br /&gt;Let&#39;s start by connecting to an open Excel &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-excel-with-ruby-worksheet.html&quot;&gt;worksheet&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;xl = WIN32OLE.connect(&#39;Excel.Application&#39;)&lt;br /&gt;ws = xl.ActiveSheet&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Inserting the Image&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To insert a picture into a worksheet, call the Worksheet object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Pictures.Insert()&lt;/span&gt; method, passing it the filename of the image to insert:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic = ws.Pictures.Insert(&#39;C:\Pictures\Image1.jpg&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;Pictures.Insert()&lt;/span&gt; method inserts a new Picture object into the &lt;span style=&quot;font-style:italic;&quot;&gt;Pictures &lt;/span&gt;collection and returns a reference to the new Picture object, which we&#39;ve assigned to the variable &lt;span style=&quot;font-style:italic;&quot;&gt;pic&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Positioning the Image&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;OK, now that you&#39;ve got the picture inserted into the worksheet, you probably want to specify its exact position, perhaps aligned with a certain range of cells. Let&#39;s start by defining that &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-excel-with-ruby-rows-columns.html&quot;&gt;range &lt;/a&gt;of cells, from cell C3 to cell F5:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;range = ws.Range(&#39;C3:F5&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We want the picture aligned with the top/left corner of our range, so we&#39;ll set our Picture object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Top &lt;/span&gt;and &lt;span style=&quot;font-style:italic;&quot;&gt;Left &lt;/span&gt;properties to be the same as our Range object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Top &lt;/span&gt;and &lt;span style=&quot;font-style:italic;&quot;&gt;Left &lt;/span&gt;properties.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic.Top = range.Top&lt;br /&gt;pic.Left = range.Left&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Resizing the Image&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that we have the top/left position set, let&#39;s move on to specifying the width and height of the picture.  The original image has an &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Aspect_ratio_%28image%29&quot;&gt;aspect ratio&lt;/a&gt;&lt;/span&gt;, which is the image&#39;s width divided by its height.  An image that is 800x600 pixels could be said to have an aspect ratio of 4:3. When resizing an image, you may wish to maintain its original aspect ratio, to avoid making the image appear stretched in one direction or the other.&lt;br /&gt;&lt;br /&gt;By default, a Picture object in Excel has its aspect ratio locked, so that when you change &lt;span style=&quot;font-style:italic;&quot;&gt;either &lt;/span&gt;the width &lt;span style=&quot;font-style:italic;&quot;&gt;or &lt;/span&gt;the height, the other dimension is automatically adjusted to preserve the aspect ratio.&lt;br /&gt;&lt;br /&gt;You adjust the width and/or height of a Picture object by setting its---wait for it---&lt;span style=&quot;font-style:italic;&quot;&gt;Width &lt;/span&gt;and &lt;span style=&quot;font-style:italic;&quot;&gt;Height &lt;/span&gt;properties.  With the aspect ratio locked, we can set the image to fill the width of the range...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic.Width = range.Width&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...or to fill the height of the range...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic.Height = range.Height&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...but we cannot successfully apply both settings without first unlocking the aspect ratio.&lt;br /&gt;&lt;br /&gt;To unlock the Picture&#39;s aspect ratio, you set the Picture object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;ShapeRange.LockAspectRatio&lt;/span&gt; property to &lt;span style=&quot;font-style:italic;&quot;&gt;false&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic.ShapeRange.LockAspectRatio = false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now that we have unlocked the aspect ratio, we can set the picture&#39;s width and height to match the range&#39;s width and height:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic.Width = range.Width&lt;br /&gt;pic.Height = range.Height&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;Width &lt;/span&gt;and &lt;span style=&quot;font-style:italic;&quot;&gt;Height &lt;/span&gt;properties are just numerical values. So you could instead do something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pic.Width = 400&lt;br /&gt;pic.Height = 300&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And that, my friends, is how you insert, position, and resize an image in Excel.&lt;br /&gt;&lt;br /&gt;Let me know if you have any questions or comments, and thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/07/ruby-excel-inserting-pictures-into.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-2679054707872784897</guid><pubDate>Thu, 09 Jul 2009 12:34:00 +0000</pubDate><atom:updated>2009-07-09T07:54:37.593-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>Ruby &amp; Excel: Hiding and Unhiding Columns, Rows, and Worksheets</title><description>Occasionally, when working with Excel, you may have a need to hide certain columns or rows in a worksheet. As an example, perhaps your worksheet lists revenue for each of 12 months, but your intended recipient only wants to see the columns showing year-to-date totals. Whatever the reason, you&#39;d like to simply hide certain columns (or rows) rather than delete them completely. And since you&#39;re &lt;span style=&quot;font-style:italic;&quot;&gt;here&lt;/span&gt;, you&#39;d probably prefer to do that &lt;span style=&quot;font-style:italic;&quot;&gt;with Ruby code&lt;/span&gt;...&lt;br /&gt;&lt;br /&gt;Let&#39;s set the scene by assuming that your code is working with an open workbook and you want to hide columns in the currently selected &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-excel-with-ruby-worksheet.html&quot;&gt;worksheet&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;xl = WIN32OLE.connect(&#39;Excel.Application&#39;)&lt;br /&gt;wb = xl.ActiveWorkbook&lt;br /&gt;ws = xl.ActiveSheet&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Hiding Columns&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To hide one or more columns, obtain a reference to the &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-excel-with-ruby-rows-columns.html&quot;&gt;column range(s)&lt;/a&gt; and set the &lt;span style=&quot;font-style:italic;&quot;&gt;Hidden &lt;/span&gt;property to &lt;span style=&quot;font-style:italic;&quot;&gt;true&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ws.Columns(&#39;A&#39;).Hidden = true&lt;br /&gt;ws.Columns(&#39;D:K&#39;).Hidden = true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Unhiding (displaying) columns works the same way; except, of course, you set the &lt;span style=&quot;font-style:italic;&quot;&gt;Hidden &lt;/span&gt;property to &lt;span style=&quot;font-style:italic;&quot;&gt;false&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ws.Columns(&#39;A&#39;).Hidden = false&lt;br /&gt;ws.Columns(&#39;D:K&#39;).Hidden = false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The following code ensures that all columns in a worksheet are visible:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ws.Columns.Hidden = false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Hiding Rows&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Rows have a &lt;span style=&quot;font-style:italic;&quot;&gt;Hidden &lt;/span&gt;property, too, so you can do this to hide rows...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ws.Rows(&#39;3&#39;).Hidden = true&lt;br /&gt;ws.Rows(&#39;7:11&#39;).Hidden = true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...and to unhide them:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ws.Rows(&#39;3&#39;).Hidden = false&lt;br /&gt;ws.Rows(&#39;7:11&#39;).Hidden = false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Hiding Worksheets&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But what if you want to hide an entire worksheet? The Worksheet object doesn&#39;t have a &lt;span style=&quot;font-style:italic;&quot;&gt;Hidden &lt;/span&gt;property. Instead, you&#39;ll use the &lt;span style=&quot;font-style:italic;&quot;&gt;Visible &lt;/span&gt;property. So to hide the &#39;Great Amish Scientists&#39; worksheet in the active workbook (&lt;span style=&quot;font-style:italic;&quot;&gt;wb&lt;/span&gt;), we&#39;d use this code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wb.Worksheets(&#39;Great Amish Scientists&#39;).Visible = false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And to unhide it, we&#39;d toggle the &lt;span style=&quot;font-style:italic;&quot;&gt;Visible &lt;/span&gt;property back to &lt;span style=&quot;font-style:italic;&quot;&gt;true&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wb.Worksheets(&#39;Great Amish Scientists&#39;).Visible = true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The following code ensures that all worksheets in a workbook are visible:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wb.Worksheets.each do |ws|&lt;br /&gt;    ws.Visible = true&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And that, folks, is pretty much all there is to it. Let me know if you have any questions or comments, and thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/07/ruby-excel-hiding-and-unhiding-columns.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-548040704791074903</guid><pubDate>Mon, 29 Jun 2009 00:15:00 +0000</pubDate><atom:updated>2009-06-28T20:17:39.379-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">wxruby</category><title>wxRuby: Changing Text Fonts and Colours</title><description>A reader recently asked me how to change the text font size and color for &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/wxruby&quot;&gt;wxRuby&lt;/a&gt; controls such as the StaticText control. Let&#39;s take a look at how you can do this.&lt;br /&gt;&lt;br /&gt;Imagine, if you will, that we have a StaticText control named &lt;span style=&quot;font-style:italic;&quot;&gt;my_control&lt;/span&gt;...&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Changing Fonts&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We&#39;ll begin by creating a new Font object by calling the &lt;span style=&quot;font-style:italic;&quot;&gt;Font.new(&lt;/span&gt;) method:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;my_font = Wx::Font.new()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next, we&#39;ll set various attributes of our new Font object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;my_font.set_point_size(20)&lt;br /&gt;my_font.set_family(Wx::FONTFAMILY_MODERN)&lt;br /&gt;my_font.set_style(Wx::FONTSTYLE_ITALIC) &lt;br /&gt;my_font.set_weight(Wx::FONTWEIGHT_BOLD)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once we have our Font object defined to our satisfaction, we can then pass it to our control&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;set_font()&lt;/span&gt; method:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;my_control.set_font(my_font)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Changing Colors&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Text color is &lt;span style=&quot;font-style:italic;&quot;&gt;not&lt;/span&gt; an attribute of the Font object, but is rather the foreground color of the control. So, to change the color of the text, we call the control&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;set_foreground_colour()&lt;/span&gt; method and pass it a Colour object. We&#39;ll make it easy and use one of wxRuby&#39;s built-in Colour constants:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;my_control.set_foreground_colour(Wx::RED)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Make a note  of the spelling: &lt;span style=&quot;font-style:italic;&quot;&gt;colour&lt;/span&gt;, not &lt;span style=&quot;font-style:italic;&quot;&gt;color&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Further Reading&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A simple working example can be found &lt;a href=&quot;http://pastie.org/527541&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Documentation of the Font object can be found &lt;a href=&quot;http://wxruby.rubyforge.org/doc/font.html&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Documentation of the &lt;span style=&quot;font-style:italic;&quot;&gt;set_foreground_colour()&lt;/span&gt; method can be found &lt;a href=&quot;http://wxruby.rubyforge.org/doc/window.html#Window_setforegroundcolour&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Documentation of the Colour object can be found &lt;a href=&quot;http://wxruby.rubyforge.org/doc/colour.html&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And there you have it. Let me know if you&#39;d like to see more on this or other subjects. &lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/06/wxruby-changing-text-fonts-and-colours.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-1610032345734731799</guid><pubDate>Tue, 23 Jun 2009 13:00:00 +0000</pubDate><atom:updated>2009-06-23T08:04:45.002-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">word</category><title>Ruby &amp; Word: Inserting Tables</title><description>Microsoft Word is great for text documents. Microsoft Excel is great for tables of data. But, sometimes, you need to get your chocolate in your peanut butter. In other words, you may occasionally need to include a table in a Word document. Let&#39;s walk through how to do that.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Setting the Stage&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To borrow an example from my upcoming book, let&#39;s say that you want to insert a table that contains a list of all movies starring Spencer Tracy and Katharine Hepburn, including the year each movie was released, the title, and the director. Your 2-dimensional &lt;span style=&quot;font-style:italic;&quot;&gt;films&lt;/span&gt; array might look like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;films = []&lt;br /&gt;films &lt;&lt; [&quot;1942&quot;, &quot;Woman of the Year&quot;, &quot;George Stevens&quot;]&lt;br /&gt;films &lt;&lt; [&quot;1942&quot;, &quot;Keeper of the Flame&quot;, &quot;George Cukor&quot;]&lt;br /&gt;films &lt;&lt; [&quot;1945&quot;, &quot;Without Love&quot;, &quot;Harold S. Bucquet&quot;]&lt;br /&gt;films &lt;&lt; [&quot;1947&quot;, &quot;The Sea of Grass&quot;, &quot;Elia Kazan&quot;]&lt;br /&gt;films &lt;&lt; [&quot;1948&quot;, &quot;State of the Union&quot;, &quot;Frank Capra&quot;]&lt;br /&gt;films &lt;&lt; [&quot;1949&quot;, &quot;Adam&#39;s Rib&quot;, &quot;George Cukor&quot;]&lt;br /&gt;films &lt;&lt; [&quot;1952&quot;, &quot;Pat and Mike&quot;, &quot;George Cukor&quot;]&lt;br /&gt;films &lt;&lt; [&quot;1957&quot;, &quot;Desk Set&quot;, &quot;Walter Lang&quot;]&lt;br /&gt;films &lt;&lt; [&quot;1967&quot;, &quot;Guess Who&#39;s Coming to Dinner&quot;, &quot;Stanley Kramer&quot;]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let&#39;s connect to a running &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-word-with-ruby-application.html&quot;&gt;instance of Word&lt;/a&gt; and use the currently selected &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-word-with-ruby-document.html&quot;&gt;document&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;word = WIN32OLE.connect(&#39;Word.Application&#39;)&lt;br /&gt;doc = word.ActiveDocument&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Moving to the End of the Document&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First, let&#39;s move to the end of the document, where we&#39;ll add our new table. We do this by calling the &lt;span style=&quot;font-style:italic;&quot;&gt;Selection.EndKey()&lt;/span&gt; method, which moves the selection to the end of a word, line, or document. We&#39;ll pass this method a value of &lt;span style=&quot;font-style:italic;&quot;&gt;6&lt;/span&gt;, which specifies that we want to move to the end of the document:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;word.Selection.EndKey(6)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Adding a New Table&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Tables collection in Word&#39;s object model represents all the Table objects in a selection, range, or document. To add a new Table to a document, call the Document object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Tables.Add()&lt;/span&gt; method and pass it three parameters:&lt;br /&gt;&lt;br /&gt;* The range object representing where the table is to be inserted&lt;br /&gt;* The number of rows for the new table&lt;br /&gt;* The number of columns for the new table&lt;br /&gt;&lt;br /&gt;Now let&#39;s add a new table with one row and three columns (we&#39;ll add more rows later):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;table = doc.Tables.Add(word.Selection.Range, 1, 3)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;Tables.Add()&lt;/span&gt; method returns a reference to the newly created table, which we have assigned to the cleverly named variable &lt;span style=&quot;font-style:italic;&quot;&gt;table&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Inserting Text into Table Cells&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can reference a single cell in a table by calling the &lt;span style=&quot;font-style:italic;&quot;&gt;Cell()&lt;/span&gt; method and passing it the row and column numbers (NOTE: the first row or column is represented by &lt;span style=&quot;font-style:italic;&quot;&gt;1&lt;/span&gt;, not &lt;span style=&quot;font-style:italic;&quot;&gt;0&lt;/span&gt;). Once you have your cell, you can set the text via its &lt;span style=&quot;font-style:italic;&quot;&gt;Range.Text&lt;/span&gt; property; so we add the header text as follows:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;table.Cell(1, 1).Range.Text = &#39;Year&#39;&lt;br /&gt;table.Cell(1, 2).Range.Text = &#39;Film Title&#39;&lt;br /&gt;table.Cell(1, 3).Range.Text = &#39;Director&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Adding Rows&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To add a row to your table, simply call the Table object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Rows.Add()&lt;/span&gt; method. Now that we&#39;ve added the header text, let&#39;s iterate over our &lt;span style=&quot;font-style:italic;&quot;&gt;films&lt;/span&gt; array and add a new row to the table for each film and insert the text:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;films.each_with_index do |film, r|&lt;br /&gt;    table.Rows.Add()&lt;br /&gt;    film.each_with_index do |field, c|&lt;br /&gt;        table.Cell(r + 2, c + 1).Range.Text = field&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There you have it. Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/05/ruby-word-inserting-tables.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>10</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-2614253677748061348</guid><pubDate>Fri, 12 Jun 2009 12:06:00 +0000</pubDate><atom:updated>2009-06-12T07:35:30.993-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">word</category><title>Ruby &amp; Word: Counting Words and Pages</title><description>Someone recently asked how to get a count of the number of words and pages in a Microsoft Word document.  This is done by calling the &lt;span style=&quot;font-style:italic;&quot;&gt;ComputeStatistics()&lt;/span&gt; method on a Range or Document object.&lt;br /&gt;&lt;br /&gt;As an example (play along at home), let&#39;s imagine that you have a &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/word&quot;&gt;Word&lt;/a&gt; document open.  Your first step is to use the &lt;span style=&quot;font-style:italic;&quot;&gt;win32ole &lt;/span&gt; library&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;connect()&lt;/span&gt; method to connect to the existing instance of Word:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;word = WIN32OLE.connect(&#39;Word.Application&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You pass the &lt;span style=&quot;font-style:italic;&quot;&gt;ComputeStatistics()&lt;/span&gt; method an integer representing the type of statistic that you want to calculate.  In other words, &quot;What do you want to count?&quot;  So let&#39;s take a moment to define constants for those values:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;WdStatisticCharacters = 3&lt;br /&gt;WdStatisticCharactersWithSpaces = 5&lt;br /&gt;WdStatisticWords = 0&lt;br /&gt;WdStatisticLines = 1&lt;br /&gt;WdStatisticParagraphs = 4&lt;br /&gt;WdStatisticPages = 2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can call the &lt;span style=&quot;font-style:italic;&quot;&gt;ComputeStatistics()&lt;/span&gt; method on a &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-word-with-ruby-document.html&quot;&gt;Document object&lt;/a&gt;...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;doc = word.ActiveDocument&lt;br /&gt;word_count = doc.ComputeStatistics(WdStatisticWords)&lt;br /&gt;page_count = doc.ComputeStatistics(WdStatisticPages)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...or on a &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/04/automating-word-with-ruby-range-object.html&quot;&gt;Range object&lt;/a&gt;...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;paragraph = doc.Paragraphs(27)&lt;br /&gt;word_count = paragraph.Range.ComputeStatistics(WdStatisticWords)&lt;br /&gt;char_count = paragraph.Range.ComputeStatistics(WdStatisticCharacters)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When called on a Document object, the method accepts an optional second parameter, &lt;span style=&quot;font-style:italic;&quot;&gt;IncludeFootnotesAndEndnotes&lt;/span&gt;, a boolean which (obviously) specifies if the calculation should include footnotes and endnotes:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;word_count = doc.ComputeStatistics(WdStatisticWords, true)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;IncludeFootnotesAndEndnotes&lt;/span&gt; parameter defaults to &lt;span style=&quot;font-style:italic;&quot;&gt;false&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Official details on the &lt;span style=&quot;font-style:italic;&quot;&gt;ComputeStatistics()&lt;/span&gt; method are available from MSDN &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa171867(office.11).aspx&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That&#39;s all for now.  Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/06/ruby-word-counting-words-and-pages.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-7579703581704514797</guid><pubDate>Thu, 04 Jun 2009 13:00:00 +0000</pubDate><atom:updated>2009-06-04T08:18:51.198-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">word</category><title>Ruby &amp; Word: Creating and Applying Styles</title><description>Microsoft &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/word&quot;&gt;Word&lt;/a&gt; uses the Styles model to apply a set of pre-defined formatting to text.  Styles can also serve a second purpose, to tag sections of the document as normal, title, headings and such.  You can then, for example, create a Table of Contents in Word based on the text that is formatted with the Heading styles.&lt;br /&gt;&lt;br /&gt;Naturally, you can do all this with code (otherwise, I wouldn&#39;t be wasting your time here).  Over the next few minutes, we&#39;ll walk through the process of creating a new Style, setting its properties, and then applying that style to text.&lt;br /&gt;&lt;br /&gt;The Style object represents a single built-in or user-defined Word style.  The Styles collection contains all the Style objects within a document.  To reference the Styles collection, simply call the Styles method on the document:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;doc = word.ActiveDocument&lt;br /&gt;styles = doc.Styles&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To create a new Style, we call the &lt;span style=&quot;font-style:italic;&quot;&gt;Add()&lt;/span&gt; method on the Styles object and pass it a hash defining the name and the type of the new Style.  The following code creates a new Paragraph style named &#39;Code&#39;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;code_style = doc.Styles.Add({&#39;Name&#39; =&gt; &#39;Code&#39;, &#39;Type&#39; =&gt; 1})&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The Type property defines what StyleType your new Style is based on.  Possible values are:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;WdStyleTypeParagraph = 1&lt;br /&gt;wdStyleTypeCharacter = 2&lt;br /&gt;WdStyleTypeTable     = 3&lt;br /&gt;WdStyleTypeList      = 4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The default is WdStyleTypeParagraph.&lt;br /&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;Add()&lt;/span&gt; method returns a reference to the newly-created Style object.  Now that you have your new Style object, you can customize it through various properties that you can set.  As a starting point, you may want to base your new style on another style by setting the &lt;span style=&quot;font-style:italic;&quot;&gt;BaseStyle &lt;/span&gt;property:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;code_style.BaseStyle = &#39;Normal&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Font properties can be defined...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;code_style.Font.Name = &#39;Consolas&#39;&lt;br /&gt;code_style.Font.Size = 12&lt;br /&gt;code_style.Font.Bold = false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...as well as paragraph spacing and background colors:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;code_style.NoSpaceBetweenParagraphsOfSameStyle = true&lt;br /&gt;code_style.Shading.BackgroundPatternColor = 15132390&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that not all properties will apply to all style types.&lt;br /&gt;&lt;br /&gt;Now that you&#39;ve created your own Style, you might want to automatically apply it to some existing text.  The following code iterates over each paragraph in the document (&lt;span style=&quot;font-style:italic;&quot;&gt;doc&lt;/span&gt; variable).  For each paragraph that uses the &#39;Preformatted Text&#39; style, the new &#39;Code&#39; style is applied instead:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;doc.Paragraphs.each do |paragraph|&lt;br /&gt;    if paragraph.Style.NameLocal == &#39;Preformatted Text&#39;&lt;br /&gt;        paragraph.Style = &#39;Code&#39;&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There you have it.  If you&#39;d like to learn more here about Styles, or anything else related to automating Word with Ruby, please let me know.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/06/ruby-word-creating-and-applying-styles.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-1891061465285187623</guid><pubDate>Sun, 24 May 2009 22:00:00 +0000</pubDate><atom:updated>2009-05-24T17:05:51.644-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">tools</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>The OCRA Compiler: Tips, Tricks, and Gotchas</title><description>I&#39;ve &lt;a href=&quot;http://rubyonwindows.blogspot.com/2009/05/ocra-one-click-ruby-application-builder.html&quot;&gt;previously mentioned&lt;/a&gt; Lars Christensen&#39;s &lt;a href=&quot;http://rubyforge.org/projects/ocra/&quot;&gt;One-Click Ruby Application Builder&lt;/a&gt;, a &quot;compiler&quot; for Ruby scripts that shows a lot of potential (and current value).  There&#39;s not much documentation yet, but folks are installing it, using it, and providing feedback.  It works right out of the box for many purposes, but here are a few things to keep in mind as you use it...&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;&quot;Failed to create directory&quot; Error&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One user reported receiving the error &quot;Failed to create directory&quot; when running the compiled executable.  As a possible workaround, try running ocra.rb from the directory where your script is located.  For example, instead of running...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ocra.rb &quot;C:\code\rubyscripts\application.rbw&quot;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...navigate to the &quot;C:\code\rubyscripts&quot; directory, then run:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ocra.rb application.rbw&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that while this resolved the problem on my machine, it didn&#39;t help the person who originally reported the problem.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Require RubyGems&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When you compile your script (which uses one or more gems) with OCRA and then run the executable, you may receive a &#39;no such file to load&#39; error.  Try adding the line...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;rubygems&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...to the top of your script, above the other &lt;span style=&quot;font-style:italic;&quot;&gt;require&lt;span style=&quot;font-style:italic;&quot;&gt;&lt;/span&gt;&lt;/span&gt; statements.  I&#39;ve found that a script that runs pre-compiled without this statement may not execute once compiled.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Compile Without Running&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I mentioned earlier that it would be nice to have an option to avoid fully running the script, similar to RubyScript2Exe&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;exit if RUBYSCRIPT2EXE.is_compiling?&lt;/span&gt; idiom.  A tip of the hat goes to reader &quot;BackOrder&quot;, who offered the following solution:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;exit if Object.const_defined?(:Ocra)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Put all your &lt;span style=&quot;font-style:italic;&quot;&gt;require &lt;/span&gt;statements at the top of your code, followed by this line.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;OCRA and Mechanize: &quot;libxml2.dll not found&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There may be a problem compiling a script that requires the mechanize gem.  Running the compiled executable resulted in a &quot;libxml2.dll was not found&quot; error on my machine.&lt;br /&gt;&lt;br /&gt;Note that the above observations relate to version 1.0.2 (current as of this writing) of the ocra gem.&lt;br /&gt;&lt;br /&gt;More information is available in the OCRA &lt;a href=&quot;http://rubyforge.org/forum/?group_id=8185&quot;&gt;forums&lt;/a&gt; and &lt;a href=&quot;http://rubyforge.org/tracker/?group_id=8185&quot;&gt;bug tracker&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Thanks again to Lars for creating OCRA, and to the users who have installed it, used it, and provided their feedback.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/05/ocra-compiler-tips-tricks-and-gotchas.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-8860010970366469069</guid><pubDate>Sun, 17 May 2009 16:03:00 +0000</pubDate><atom:updated>2009-05-17T11:35:35.685-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">win32ole</category><title>Handling WIN32OLE Events in Excel</title><description>Someone recently asked how to have Ruby react to events in Excel.  Specifically, they were trying retrieve the contents of a row in a worksheet when it&#39;s selected.&lt;br /&gt;&lt;br /&gt;The win32ole module provides a WIN32OLE_EVENT class that will allow you to execute a block of code when a specific event occurs.&lt;br /&gt;&lt;br /&gt;To set the scene, let&#39;s use the &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;WIN32OLE.connect()&lt;/span&gt;&lt;/span&gt; method to connect to an existing instance of Microsoft Excel and grab a reference to the currently active workbook:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;xl = WIN32OLE.connect(&#39;Excel.Application&#39;)&lt;br /&gt;wb = xl.ActiveWorkbook&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next, we&#39;ll call the &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;WIN32OLE_EVENT.new()&lt;/span&gt;&lt;/span&gt; method to create a new OLE event object.  You pass this method an OLE object---our Workbook object---and the name of the event sink.  In this instance, we want to use the &lt;span style=&quot;font-style:italic;&quot;&gt;WorkbookEvents&lt;/span&gt; sink:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ev = WIN32OLE_EVENT.new(wb, &#39;WorkbookEvents&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once you have your event sink defined, you call its &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;on_event()&lt;/span&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;&lt;/span&gt;&lt;/span&gt; method to hook into a particular event and run a block of code when that event fires.  In our scenario, we want to take action when the &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;SheetSelectionChange &lt;/span&gt;&lt;/span&gt;event fires.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ev.on_event(&#39;SheetSelectionChange&#39;) do&lt;br /&gt;    range = xl.Selection&lt;br /&gt;    puts(range.Value)&lt;br /&gt;    STDOUT.flush()&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The above block of code will execute when the user selects a range of cells, and will print out the array of values from the selected cells.&lt;br /&gt;&lt;br /&gt;Finally, you need to start the event message loop to begin the event monitoring:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;loop do&lt;br /&gt;    WIN32OLE_EVENT.message_loop&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the real world, we need a means to exit the message loop.  Let&#39;s catch the &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;BeforeClose &lt;/span&gt;&lt;/span&gt;event, which fires (of course) just prior to the workbook being closed:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ev.on_event(&#39;BeforeClose&#39;) do&lt;br /&gt;    exit_event_loop&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, when the &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;BeforeClose &lt;/span&gt;&lt;/span&gt;event fires, we&#39;ll have it call a new &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;exit_event_loop()&lt;/span&gt;&lt;/span&gt; method, which sets a &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;$LOOP&lt;/span&gt;&lt;/span&gt; value to &lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;false&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$LOOP = true&lt;br /&gt;&lt;br /&gt;def exit_event_loop&lt;br /&gt;    $LOOP = false&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Finally, we&#39;ll modify our earlier message loop block, accordingly, and also toss in a brief pause:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;while $LOOP&lt;br /&gt;    WIN32OLE_EVENT.message_loop&lt;br /&gt;    sleep(0.1)&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Our complete code looks something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;&lt;br /&gt;xl = WIN32OLE.connect(&#39;Excel.Application&#39;)&lt;br /&gt;wb = xl.ActiveWorkbook&lt;br /&gt;&lt;br /&gt;ev = WIN32OLE_EVENT.new(wb, &#39;WorkbookEvents&#39;)&lt;br /&gt;&lt;br /&gt;ev.on_event(&#39;SheetSelectionChange&#39;) do&lt;br /&gt;    range = xl.Selection&lt;br /&gt;    puts(range.Value)&lt;br /&gt;    STDOUT.flush()&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;ev.on_event(&#39;BeforeClose&#39;) do&lt;br /&gt;    puts(&#39;Closed&#39;);STDOUT.flush&lt;br /&gt;    exit_event_loop&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;$LOOP = true&lt;br /&gt;&lt;br /&gt;def exit_event_loop&lt;br /&gt;    $LOOP = false&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;while $LOOP&lt;br /&gt;    WIN32OLE_EVENT.message_loop&lt;br /&gt;    sleep(0.1)&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And there you have it.  Tweak to suit your individual needs.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/05/handling-win32ole-events-in-excel.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>13</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-1201501479819524668</guid><pubDate>Thu, 14 May 2009 12:12:00 +0000</pubDate><atom:updated>2009-05-14T08:00:41.161-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><category domain="http://www.blogger.com/atom/ns#">tools</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>OCRA: One-Click Ruby Application Builder</title><description>I &lt;a href=&quot;http://rubyonwindows.blogspot.com/2009/05/rubyscript2exe-and-rubygems.html&quot;&gt;recently mentioned&lt;/a&gt; the fact that RubyScript2Exe 0.5.3 doesn&#39;t play well with recent versions of RubyGems.  At the end of that post I mentioned that there are alternatives emerging for creating executables from your Ruby code, including Lars Christensen&#39;s OCRA, the One-Click Ruby Application Builder.&lt;br /&gt;&lt;br /&gt;I&#39;ve had a chance to take OCRA for a short test drive and it looks promising.  Like Erik Veenstra&#39;s &lt;a href=&quot;http://rubyonwindows.blogspot.com/2007/09/compiling-your-ruby-app-with.html&quot;&gt;RubyScript2Exe&lt;/a&gt;, OCRA lets you &quot;compile&quot; your ruby code into an EXE file that you can distribute to others, without requiring that the users have Ruby installed on their PCs.  To quote the OCRA page:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The executable is a self-extracting, self-running executable that contains the Ruby interpreter, your source code and any additionally needed ruby libraries or DLL.&lt;/blockquote&gt;&lt;br /&gt;OCRA can be installed via RubyGems: open a console window and type:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;gem install ocra&lt;/pre&gt;&lt;br /&gt;It&#39;s also available from &lt;a href=&quot;http://rubyforge.org/projects/ocra/&quot;&gt;the RubyForge page&lt;/a&gt;.  Version 1.0.2 is the latest as of this writing.&lt;br /&gt;&lt;br /&gt;The syntax to compile a script is...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ocra.rb [option] your/script.rb&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...where &lt;span style=&quot;font-style:italic;&quot;&gt;option&lt;/span&gt; is one or more of the following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--dll dllname    Include additional DLLs from the Ruby bindir.&lt;br /&gt;--no-lzma        Disable LZMA compression of the executable.&lt;br /&gt;--quiet          Suppress output.&lt;br /&gt;--help           Display this information.&lt;br /&gt;--windows        Force Windows application (rubyw.exe)&lt;br /&gt;--console        Force console application (ruby.exe)&lt;br /&gt;--no-autoload    Don&#39;t load/include script.rb&#39;s autoloads&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Thus far, I have exercised only the &lt;span style=&quot;font-style:italic;&quot;&gt;--windows&lt;/span&gt; and &lt;span style=&quot;font-style:italic;&quot;&gt;--console&lt;/span&gt; options.&lt;br /&gt;&lt;br /&gt;To create a non-console application, either use the &lt;span style=&quot;font-style:italic;&quot;&gt;--windows&lt;/span&gt; option or give your script the &lt;span style=&quot;font-style:italic;&quot;&gt;.rbw&lt;/span&gt; filename extension.  Compiling a basic non-console script is as simple as opening a console window, navigating to the folder containing your script, and typing:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ocra.rb myscript.rbw&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;OCRA will then run your script to check for dependencies, gather the necessary files, and create your executable.  An option to avoid fully running the script would be nice, similar to RubyScript2Exe&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;exit if RUBYSCRIPT2EXE.is_compiling?&lt;/span&gt; idiom.&lt;br /&gt;&lt;br /&gt;OCRA uses LZMA compression, so the resulting executable is relatively small.  A simple wxRuby app, for example, resulted in a 2.5 Mb executable.  The same app compiled with RubyScript2Exe weighed in at over 9 Mb.  Apps that do not require a GUI toolkit will be even smaller, perhaps 500k.&lt;br /&gt;&lt;br /&gt;I haven&#39;t spent a lot of time with OCRA yet, but I think it shows great potential and I want to thank Lars Christensen for his efforts.  If you have a need to distribute Ruby programs to non-technical users, you should &lt;a href=&quot;http://rubyforge.org/projects/ocra/&quot;&gt;check it out&lt;/a&gt; and pass your feedback along to Lars.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/05/ocra-one-click-ruby-application-builder.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>17</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-284600789737488130.post-4102993752494622029</guid><pubDate>Mon, 11 May 2009 12:16:00 +0000</pubDate><atom:updated>2009-05-11T07:40:20.535-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">excel</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><title>Ruby &amp; Excel: Extracting Cell Comments</title><description>Someone recently asked how to get the comment text from a particular cell in an &lt;a href=&quot;http://rubyonwindows.blogspot.com/search/label/excel&quot;&gt;Excel&lt;/a&gt; worksheet.&lt;br /&gt;&lt;br /&gt;You could call the cell&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Comment&lt;/span&gt; property to obtain a reference to the Comment object, then use the Comment object&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;Text&lt;/span&gt; property to get---or set---the text of the comment.&lt;br /&gt;&lt;br /&gt;Imagine that you have a workbook open and you want to get the comment text from cell B2 in the currently selected worksheet. The following code should do the trick:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require &#39;win32ole&#39;&lt;br /&gt;&lt;br /&gt;xl = WIN32OLE.connect(&#39;Excel.Application&#39;)&lt;br /&gt;ws = xl.ActiveSheet&lt;br /&gt;cell = ws.Range(&#39;B2&#39;)&lt;br /&gt;comment = cell.Comment&lt;br /&gt;text = comment.Text&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Do you---or would you like to---use comments in your worksheets? I can go into further detail about the Comment object and the Comments collection, but that&#39;s all we have time for today.&lt;br /&gt;&lt;br /&gt;Thanks for stopping by!</description><link>http://rubyonwindows.blogspot.com/2009/05/ruby-excel-extracting-cell-comments.html</link><author>noreply@blogger.com (David Mullet)</author><thr:total>2</thr:total></item></channel></rss>