<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Polymath Programmer &#187; Programming</title>
	<atom:link href="http://polymathprogrammer.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://polymathprogrammer.com</link>
	<description>Where entrepreneurship, mathematics and programming meet</description>
	<lastBuildDate>Wed, 23 May 2012 16:09:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Dot notation dropdown hell</title>
		<link>http://polymathprogrammer.com/2012/05/18/dot-notation-dropdown-hell/</link>
		<comments>http://polymathprogrammer.com/2012/05/18/dot-notation-dropdown-hell/#comments</comments>
		<pubDate>Fri, 18 May 2012 11:14:50 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dot]]></category>
		<category><![CDATA[dropdown]]></category>
		<category><![CDATA[menu]]></category>
		<category><![CDATA[notation]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3611</guid>
		<description><![CDATA[Have you written something like this: body.LeftArm.ForeArm.Hand.Pinky.Twitch() Would this be easier? body.Twitch(BodyPart.LeftPinky) I&#8217;ve been thinking about this a lot, because I&#8217;m writing a software library. You know what&#8217;s hard? Deciding what classes, functions and properties to expose to the programmer. My software library deals with spreadsheets, and for uhm, research, I downloaded 2 free open-source [...]]]></description>
			<content:encoded><![CDATA[<p>Have you written something like this:<br />
<code>body.LeftArm.ForeArm.Hand.Pinky.Twitch()</code></p>
<p>Would this be easier?<br />
<code>body.Twitch(BodyPart.LeftPinky)</code></p>
<p>I&#8217;ve been thinking about this a lot, because I&#8217;m writing a software library. You know what&#8217;s hard? <strong>Deciding what classes, functions and properties to expose to the programmer.</strong></p>
<p><a href="http://polymathprogrammer.com/store/spreadsheetlight/">My software library deals with spreadsheets</a>, and for uhm, research, I downloaded 2 free open-source libraries for comparison. Then I looked at sample code for 2 commercial libraries too.</p>
<p>You know what I found?</p>
<p>For the most part, the libraries just expose the underlying class structures to the programmer.</p>
<p>While this gives the programmer ultimate coding power, <em>I personally find this exhausting</em>. It&#8217;s like the first time I encountered the .NET Framework. There&#8217;s an overwhelming number of classes with their own functions and enumerations&#8230; &#8220;I just want to write one single sentence to a file!&#8221; Even that took me a few minutes to get used to. Luckily there&#8217;s extensive documentation, or I&#8217;d just collapse under the weight.</p>
<p>Do you remember Nokia? It&#8217;s a telecommunications company, but I know it as a mobile phone maker. My experience with Nokia phones were that they were probably designed by engineers and programmers. There were a lot of dropdown menus.</p>
<p>We programmers can think in hierarchies. But users don&#8217;t usually think in hierarchies (I think there&#8217;s research showing dropdown menus on web sites confuse users).</p>
<p>Consider the basic task in programming: declaring a variable. Here&#8217;s how you do this in VB:<br />
<code>Dim asdf as Int32</code></p>
<p>Here&#8217;s how you do this in C# (and any C-family):<br />
<code>int asdf;</code></p>
<p>When I want a variable, I already know what type it should be. The type matters to me and the compiler. The name matters a little to me, and practically none to the compiler. By the time I type &#8220;Dim asdf as&#8221; I already forgot what type I wanted, because I was so busy coming up with a variable name.</p>
<p>I feel this is backwards. Yes, I kinda have a thing about VB in this case&#8230;</p>
<p>Remember the pinky twitching example?</p>
<p><code>body.LeftArm.ForeArm.Hand.Pinky.Twitch()</code><br />
This forces the programmer to go all the way back to the root class, and then traverse the properties down again to reach the Twitch() function.</p>
<p><code>body.Twitch(BodyPart.LeftPinky)</code><br />
This shortcuts a lot of the traversing.</p>
<p>I have a lot of respect for the programmers working on open-source projects. They give their time and effort to improving software without pay. I just feel the design sometimes leave a little to be desired.</p>
<p>Have you looked at an iPhone? The interface allows the user to reach something within a couple of taps.</p>
<p>Do you know Google recommends that website links be no more than 3 levels deep? This means every page should be available from every other page via no more than 3 clicks.</p>
<p>So why did the first twitching example need 5 levels to reach my Twitch() function?</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/05/18/dot-notation-dropdown-hell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Collision detection in merging Excel cells</title>
		<link>http://polymathprogrammer.com/2012/05/04/collision-detection-merging-excel-cells/</link>
		<comments>http://polymathprogrammer.com/2012/05/04/collision-detection-merging-excel-cells/#comments</comments>
		<pubDate>Fri, 04 May 2012 12:25:36 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cell]]></category>
		<category><![CDATA[collision detection]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[hyperplane separation theorem]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[separating axis theorem]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3577</guid>
		<description><![CDATA[You can merge cells in Excel. &#8220;Duh!&#8221; you say. So how does Excel ensure that the cells you want to merge don&#8217;t overlap any existing merged cells? How do you check programmatically that the cells you want to merge won&#8217;t overlap any existing merged cells? Well, that was the problem I faced while writing my [...]]]></description>
			<content:encoded><![CDATA[<p>You can merge cells in Excel. &#8220;Duh!&#8221; you say. So how does Excel ensure that the cells you want to merge don&#8217;t overlap any existing merged cells? How do you check <em>programmatically </em>that the cells you want to merge won&#8217;t overlap any existing merged cells?</p>
<p>Well, that was the problem I faced while writing my spreadsheet library software (<a href="http://polymathprogrammer.com/store/spreadsheetlight/">check out SpreadsheetLight here!</a>). The inkling of an idea was formed when I visited <a href="http://stackoverflow.com/">StackOverflow</a>. Can&#8217;t remember what I was there for, but the answer page wasn&#8217;t about Excel or spreadsheets. It was about collision detection.</p>
<p>Yes, the type of collision detection used in games so you don&#8217;t walk through walls and stuff.</p>
<p>And thus I learnt a new mathematical theorem: the separating axis theorem (or <a href="http://en.wikipedia.org/wiki/Hyperplane_separation_theorem">hyperplane separation theorem</a>). From what I understand, given two N-dimensional thingies, if you can find one (N-1)-dimensional hyperplane that separates those two thingies, then those two thingies are separate (or not overlapping).</p>
<p>Yes, &#8220;thingies&#8221; is a technical term.</p>
<p>For example, given two 3D objects, if you can find one 2D plane that separates them, then the 3D objects are not overlapping. Another example is when you&#8217;re given two 2D objects, and if you can find one line (which is 1D) that separates them, then the 2D objects are not overlapping.</p>
<p>There are some conditions to be fulfilled, such as the objects being convex and disjoint and whatever. (yes I&#8217;m a mathematician&#8230;) I&#8217;ll leave it to you to do your own reading.</p>
<p>But for our purposes, how do we check if that rectangle of Excel cells we want to merge won&#8217;t overlap with any existing merged cells? We have these conditions that make our lives easier:</p>
<ul>
<li>The merged cells are rectangular</li>
<li>The 4 end points (top-left, top-right, bottom-left, bottom-right) of a merged cell are in whole numbers</li>
<li>The (merged) cells map strictly to a 2D rectangular grid</li>
</ul>
<p>Since the merged cells are rectangular, they&#8217;re also convex (I&#8217;m not going to explain why, just trust me). Since the 4 end points are in whole numbers, line boundaries can be easily calculated (it&#8217;s easy to check if something is <7 or >=8 for example). And since they map strictly to a 2D rectangular grid, the separating axis is a line. And even better, you can always find a subset of solutions of those separating axes that are either horizontal or vertical.</p>
<p>Ok, diagrams are in order.</p>
<p><img src="http://polymathprogrammer.com/images/blog/201205/collisiondetectionmergedcells.png" alt="Collision detection in merged cells" /></p>
<p>So in our case, as long as you can find <em>one</em> horizontal line or <em>one</em> vertical line that separates the 2 merged cells we&#8217;re checking, then the 2 merged cells are separate.</p>
<p>Let&#8217;s try an example. Excel uses cell references that are in the A1 format, which means row 3 column 4 becomes &#8220;D3&#8243;. The column index uses alphabets and is in base-26. <a href="http://polymathprogrammer.com/2011/11/08/calculating-excel-column-names/">Read more here</a>.</p>
<p>We&#8217;re going to simplify that. Let&#8217;s say our existing set of merged cells only has one entry. This merged cell has the top-left corner at row 1 column 1, and the bottom-right corner at row 3 column 4. Suppose we want to check if this merge cell overlaps: top-left corner at row 7 column 8, bottom-right corner at row 10 column 10.</p>
<p>The horizontal line of 5 fits the bill, or the line y=5 if you want to be mathematical about it (but y goes from negative to positive downwards instead of the usual <a href="http://polymathprogrammer.com/2008/09/01/cartesian-coordinates-and-transformation-matrices/">Cartesian</a> y). Or y=6. Or even y=7 (note that the line can &#8220;touch&#8221; one of the merged cells, but not <em>both</em>. This is where the &#8220;whole number&#8221; condition comes in).</p>
<p>The vertical lines x=5, x=6 or x=8 also fit the bill.</p>
<p>Thus, our 2 merged cells don&#8217;t overlap.</p>
<p>So what&#8217;s the programmatic way to check? You&#8217;d be surprised at the simplicity. To make it easier, the variables with &#8220;StartRowIndex&#8221; mean the top row of the merged cell, &#8220;EndRowIndex&#8221; mean the bottom row of the merged cell. And &#8220;StartColumnIndex&#8221; mean the left-most column of the merged cell, and &#8220;EndColumnIndex&#8221; mean the right-most column of the merged cell.</p>
<div class="codediv">
<pre>
if (!(iEndRowIndex < mc.StartRowIndex || iStartRowIndex > mc.EndRowIndex || iEndColumnIndex < mc.StartColumnIndex || iStartColumnIndex > mc.EndColumnIndex))
{
    // there's an overlap!
}
</pre>
</div>
<p>So the merge cell we want to check has top-left corner at (iStartRowIndex, iStartColumnIndex) and bottom-right corner at (iEndRowIndex, iEndColumnIndex).</p>
<p>The variable &#8220;mc&#8221; refers to a custom class I use to represent merged cells. Obviously, you&#8217;d run that condition in a loop through all your existing merged cells. If you can&#8217;t find an overlap after running through that loop, then the merge cell you&#8217;re checking is good to go.</p>
<p>Let&#8217;s run through the individual conditions.</p>
<ul>
<li>(iEndRowIndex < mc.StartRowIndex) means our merged cell is completely above the existing merged cell</li>
<li>(iStartRowIndex > mc.EndRowIndex) means our merged cell is completely below the existing merged cell</li>
<li>(iEndColumnIndex < mc.StartColumnIndex) means our merged cell is completely to the left of the existing merged cell</li>
<li>(iStartColumnIndex > mc.EndColumnIndex) means our merged cell is completely to the right of the existing merged cell</li>
</ul>
<p>The first 2 conditions check for the existence of a horizontal separating axis. The next 2 conditions check for the existence of a vertical separating axis.</p>
<p>Note the negation of the entire boolean condition. Those 4 conditions check for existence of solutions. Negation means checking for overlaps.</p>
<p>Note also that we use strictly greater than or strictly less than checks. If the merge cells share a row or column, then they overlap, right?</p>
<p>Did you know my first draft of writing the code had me checking 6 different conditions? Each condition had its own if statements. This one just had one. I&#8217;m so lucky to have learnt the separating axis theorem. I was checking if a point was above, within or below the merge cell, then I had to check if the point was to the left, within or to the right of the merge cell, and &#8230; urgh, it was horrible&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/05/04/collision-detection-merging-excel-cells/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open XML SDK class structure</title>
		<link>http://polymathprogrammer.com/2012/03/27/open-xml-sdk-class-structure/</link>
		<comments>http://polymathprogrammer.com/2012/03/27/open-xml-sdk-class-structure/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 14:41:07 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[explanation]]></category>
		<category><![CDATA[openxml]]></category>
		<category><![CDATA[sdk]]></category>
		<category><![CDATA[structure]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3462</guid>
		<description><![CDATA[I&#8217;ve gotten a few questions on the class structure of the Open XML SDK. There are articles on Open XML itself, where you work directly with XML files and tags, and zip them up yourself. Basically you work with WordprocessingML (Word), SpreadsheetML (Excel), PresentationML (PowerPoint) and possibly DrawingML (for images and stuff). Eric White did [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve gotten a few questions on the class structure of the Open XML SDK. There are articles on Open XML itself, where you work directly with XML files and tags, and zip them up yourself. Basically you work with WordprocessingML (Word), SpreadsheetML (Excel), PresentationML (PowerPoint) and possibly DrawingML (for images and stuff). <a href="http://ericwhite.com/blog/">Eric White</a> did a lot of stuff on this.</p>
<p>There are also articles on the use of Open XML SDK itself. However, the articles I&#8217;ve found tend to give you code samples and some explanation of why you do those things, but didn&#8217;t really explain the deep &#8220;why&#8221;.</p>
<p>The fundamental question I was asked was &#8220;<strong>How are the Open XML SDK classes related to each other?</strong>&#8220;. A related question is &#8220;Why do I have to use that particular class?&#8221;.</p>
<p>While I&#8217;m familiar with the spreadsheet portion of the SDK, I believe the general class structure applies to the WordprocessingML and PresentationML parts too. So I&#8217;ll use the SpreadsheetML part as the example.</p>
<p>I also didn&#8217;t find any article giving names to the class categories I&#8217;m going to tell you, so I&#8217;m going to make up my own. If there&#8217;s an official Microsoft article on this, let me know. Generally speaking, there are 4 types of SDK classes:</p>
<ul>
<li><strong>Relationship Part Classes</strong> (henceforth referred to as RPCs)</li>
<li><strong>Root Classes</strong> (henceforth referred to as RCs)</li>
<li><strong>Content Classes</strong> (henceforth referred to as CCs)</li>
<li><strong>Special Classes</strong></li>
</ul>
<p>Before I continue, keep in mind that Open XML documents are basically a bunch of XML files zipped together. Just like a relational database, certain XML files are related to each other (just like certain database tables are related to each other). Which brings us to the first type of class.</p>
<h3>Relationship Part Classes</h3>
<p>RPCs are the glue that holds certain SDK classes together. They are most easily recognisable by their class type name. For example, WorkbookPart and WorksheetPart.</p>
<p>However, not all SDK classes with names that end with &#8220;Part&#8221; are RPCs. For example, TablePart is not an RPC (it&#8217;s actually a Content Class). The corresponding RPC is actually TableDefinitionPart.</p>
<p><strong>The most important part of an RPC is that it carries a relationship ID</strong>, and this relationship ID is used to tie relevant classes together. An RPC is also different in that it has as a property, a Root Class.</p>
<h3>Root Classes</h3>
<p>Remember that Open XML documents are a bunch of XML files zipped together? Well, an RC represents one of those XML files.</p>
<p>For example, the RPC WorksheetPart has as its RC, the Worksheet class. The Worksheet class holds information that basically translates into an XML file, typically sheet1.xml (and sheet2.xml and so on). The Worksheet class contains your worksheet cell data information.</p>
<h3>Content Classes</h3>
<p>If RCs represent an XML file, then CCs are basically XML tags.</p>
<p>For example, the Worksheet class contains the SheetData class, which contains the Row class(es), which in turn contains the Cell class(es). The corresponding XML tags are &#8220;worksheet&#8221;, &#8220;sheetData&#8221;, &#8220;row&#8221; and &#8220;c&#8221;.</p>
<p>Yes, an RC represents an XML file, and also translates to be the first XML tag of that XML file. That&#8217;s why it&#8217;s called a Root Class, because it also represents the root element (of the underlying XML structure/document).</p>
<h3>Special Classes</h3>
<p>These aren&#8217;t really that special. As far as I know, there are only 3 classes under this category: WordprocessingDocument, SpreadsheetDocument and PresentationDocument.</p>
<p>Those 3 classes form the starting point of any code relying on the Open XML SDK. You can consider them as Super Relationship Part Classes, because their properties are mainly RPCs.</p>
<h3>An illustration</h3>
<p>You might still be confused at this point (I don&#8217;t blame you&#8230;). Here&#8217;s a diagram for a simple Open XML spreadsheet:<br />
<img src="http://polymathprogrammer.com/images/blog/201203/openxmlsdkclassstructure.png" alt="Open XML SDK class structure" /></p>
<p>In green, we have the Special Class SpreadsheetDocument as the ultimate root.</p>
<p>In blue, we have the RPCs, 1 WorkbookPart class and 2 WorksheetPart classes. The SpreadsheetDocument class has the WorkbookPart class as a property. The WorkbookPart class contains a collection of WorksheetPart classes.</p>
<p>In grey, we have the RCs, 1 Workbook class and 2 Worksheet classes. The Workbook class is the RC of WorkbookPart class. The Worksheet classes are RCs of corresponding WorksheetPart classes. The Workbook class represents the workbook.xml file and the Worksheet classes (typically) represent sheet1.xml and sheet2.xml files.</p>
<p>In orange, we have the CCs. The Workbook class contains the Sheets class, which in turn contains 2 Sheet classes. The Sheet classes have a property holding the relationship ID of the corresponding WorksheetPart classes, which is how they&#8217;re tied to the Worksheet classes.</p>
<h3>One of the most confusing parts&#8230;</h3>
<p>After working with the Open XML SDK for a while, you might find yourself asking these questions:</p>
<ul>
<li>Why are there so many classes?</li>
<li>Why are some of these classes devoid of any meaningful functionality?</li>
<li>Why are some of these classes duplicates of each other?</li>
</ul>
<p>When I was first using the SDK, I felt the same way when I first used the .NET Framework: <strong>Being overwhelmed.</strong> There were many namespaces, with many classes in them, and I didn&#8217;t know which class to use for a specific purpose until I looked it up and wrote a small test program for it. Having a comprehensive help database/file for the .NET Framework was a really good idea.</p>
<p>And so it was with the Open XML SDK. I mean, it&#8217;s a spreadsheet. I can see a couple dozen of classes. Maybe. It turns out to be a lot of classes. That&#8217;s why there are so many code samples out there, but you don&#8217;t really know why you need to use that particular class.</p>
<p>And there are classes without any meaningful properties or functions. They inherit from a base Open XML class, and that&#8217;s it. For example, the Sheets class.</p>
<p>Then there are classes with identical properties. For example, the InlineString class, the SharedStringItem class and CommentText class. Or the Color, BackgroundColor, ForegroundColor and TabColor classes.</p>
<p>The answer is the same for all the above questions. <strong>The Open XML SDK is meant to abstract away the XML file structure.</strong></p>
<p>There are duplicate classes because each class eventually translates into an XML tag (if it&#8217;s a CC or RC). XML requires a different tag for different purposes, hence the Open XML SDK has different classes. Even though the classes are identical in programming functionality, they become rendered as different XML tags.</p>
<p>There are classes without any seemingly meaningful properties or functions <em>because their sole purpose is to have children</em>. (Ooh Open XML SDK joke!) The Sheets class has as children, the Sheet classes. In XML, they&#8217;re correspondingly the &#8220;sheets&#8221; tag with &#8220;sheet&#8221; tags as children. The final XML tags have no XML attributes, hence the corresponding SDK classes also have no properties. Tada!</p>
<p>And finally, there are so many classes, because frankly speaking, you need one SDK class corresponding to each individually different XML tag. There are a lot of XML tags used in Open XML, hence so many classes. And that&#8217;s before we add in the Relationship Part Classes.</p>
<p>If you have any questions, leave them in a comment or contact me. And I&#8217;ll see if I can answer them in an article.</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/03/27/open-xml-sdk-class-structure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Sandbox In The Cloud</title>
		<link>http://polymathprogrammer.com/2012/03/20/sandbox-cloud/</link>
		<comments>http://polymathprogrammer.com/2012/03/20/sandbox-cloud/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 12:18:24 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[joseph palumbo]]></category>
		<category><![CDATA[rackspace]]></category>
		<category><![CDATA[sandbox]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3431</guid>
		<description><![CDATA[I am honoured and excited to bring you an article written by a Rackspace staff, Joseph Palumbo. My thoughts will be at the end of this article. Thanks Joseph! Disclaimer: I&#8217;m not paid by Rackspace. As a founding member of Rackspace&#8217;s Managed Cloud support team, Joseph spends half of his time teaching customers about the [...]]]></description>
			<content:encoded><![CDATA[<p>I am honoured and excited to bring you an article written by a <a href="http://www.rackspace.com/">Rackspace</a> staff, Joseph Palumbo. My thoughts will be at the end of this article. Thanks Joseph! <strong>Disclaimer</strong>: I&#8217;m not paid by Rackspace.</p>
<p><em>As a founding member of Rackspace&#8217;s Managed Cloud support team, Joseph spends half of his time teaching customers about the Cloud and the other half learning about the Cloud from them. Follow him on <a href="https://twitter.com/#!/Racker_Joseph">Twitter</a>.</em></p>
<p>Solid, high performing websites and web applications don’t happen by accident. From imagining an idea, creating code and developing an intuitive user experience, there are many behind the scenes tasks to ensure everything works smoothly.</p>
<p>Despite how simple a website or web app might appear, the reality is that even the simplest looking sites can have powerful and complex code behind them. The complexity means that one small change can take down the entire site. However, both business needs and technologies evolve, necessitating changes to your site. The choice, however, is how you implement these changes.</p>
<p>You can choose to make code changes to your live, production environment, but this is a dangerous proposition. By doing so, you assume the risk of making a mistake that can be visible to users, or creating an error that can make your entire site go dark for an extended period of time. The better alternative is for businesses to create a test and dev sandbox that mirrors the live environment, but in the recent past, this was expensive to do.  The high cost presented a difficult decision: do you spend the money to create a test and development environment or do you assume the risk of introducing a bug or error into the live environment?</p>
<p>With the advances in <a href="http://www.rackspace.com/cloud/">cloud computing</a>, you no longer have to choose. Businesses can easily clone their production environment and create a test and dev sandbox. In the cloned site, developers can replicate the ratio of usage rather than purchase all of the horsepower; this means that you can have a more cost effective version of your site because you aren’t serving up production traffic.</p>
<p>This cloned site can be created on demand for testing code changes and will literally cost just pennies per hour. Not only can businesses create a cloned site for temporary testing, the cloud presents a cost effective solution for a long-term test and dev sandbox.</p>
<p>Furthermore, the test dev sandbox allows experimentation to happen behind the scenes without anyone outside the company (or the IT department) ever knowing. While you are making changes to your test and dev sandbox, the production site is humming along, bringing in revenue, collecting customer data and maintaining your online presence.</p>
<p>Once your developers have perfected the changes and are ready to move the mirror site into production, it can be uploaded directly. If there is a <a href="http://www.rackspace.com/blog/load-balancers-in-the-cloud/">load balancer</a> in front of your configuration, you have the ability to make the test environment the new production environment. You simply make a change on the load balancer, redirecting traffic from the old production site to the new production site in the middle of the night. This is easily done from a systems administration point of view and can result in little or no downtime to your configuration.</p>
<p>In the past, I would receive frantic phone calls from people who didn’t have a test and dev site and didn’t know their code very well. They only had a production site and were trying to make changes, but they were concerned about the potential of bringing down their site, or even worse, making an irreparable error such as erasing part of their database.</p>
<p>The cloud lowers the cost of having a test and dev site, allowing businesses to prove out their code changes without adversely impacting their production site. You can have peace of mind that you won’t make visible mistakes to your users or delete any of their data. Peace of mind is worth every penny – and with the cloud, it won’t cost very many pennies to have.</p>
<h3>Post-article thoughts</h3>
<p>I have personally maintained development, test and production web servers, along with the corresponding web sites. It can get exhausting, especially when you have to coordinate the efforts of other developers and testers (from dev and test sites), and juggle inquiries from customers and customer service officers (from live sites).</p>
<p>I&#8217;ve also personally done server maintenance. There was this one time when there was a change in some wiring structure in the data centre, and I had to be there personally (because there&#8217;s no one else) to make sure my servers were still operational after the change. I&#8217;m really not a hardware kind of guy&#8230;</p>
<p>DNS propagation, IP address settings, SSL certificates, server upgrades. If there was an easy way to enclose all that into a standalone testing environment, my life would have been so much easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/03/20/sandbox-cloud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Partial fractions in SQL queries</title>
		<link>http://polymathprogrammer.com/2012/03/07/partial-fractions-sql/</link>
		<comments>http://polymathprogrammer.com/2012/03/07/partial-fractions-sql/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 12:11:58 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[partial fraction]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3412</guid>
		<description><![CDATA[I never thought my maths training would come in handy again. I was working on a financial report, and one of the requirements was to have a particular calculated value show up. The formula didn&#8217;t make sense to me, but it was a business/financial logic requirement, so I just dealt with it. So here&#8217;s the [...]]]></description>
			<content:encoded><![CDATA[<p>I never thought my maths training would come in handy again. I was working on a financial report, and one of the requirements was to have a particular calculated value show up. The formula didn&#8217;t make sense to me, but it was a business/financial logic requirement, so I just dealt with it.</p>
<p>So here&#8217;s the core of the problem (specific values had been changed):</p>
<div class="codediv">
<pre>
select sum(A)/sum(B) - 0.7 from sometable
</pre>
</div>
<p>where &#8220;A&#8221; and &#8220;B&#8221; are columns of the database table &#8220;sometable&#8221;.</p>
<p><strong>So what&#8217;s the problem?</strong> That select query won&#8217;t run. Or at least it didn&#8217;t run from a Sybase database (or was it an SQL Server database?). I&#8217;m not saying it ran but the value was wrong. I mean it didn&#8217;t even execute. Just in case you asked, &#8220;A&#8221; and &#8220;B&#8221; are numeric data columns so the sum function will work.</p>
<p>I don&#8217;t know how I came up with the idea of using partial fractions. Given that only 0.08%* of staff in the entire office building had maths background, and I probably made up the entire 0.08%, I didn&#8217;t have anyone to bounce ideas off of and be told &#8220;How about you try using partial fractions on that, Vincent?&#8221;</p>
<p>(* a completely made up statistic)</p>
<p>Anyway, I tried using partial fractions, and it worked. Now in partial fractions, you typically deal with decomposing a fraction into 2 or more fractions. Here, we&#8217;re combining fractions into 1 fraction. Let me show you.</p>
<p>sum(A)/sum(B) &#8211; 0.7<br />
= sum(A)/sum(B) &#8211; 7/10<br />
= ( 10*sum(A) &#8211; 7*sum(B) ) / 10*sum(B)</p>
<p>If I remember correctly, this (equivalent) SQL query will work:</p>
<div class="codediv">
<pre>
select ( 10*sum(A) - 7*sum(B) ) / 10*sum(B) from sometable
</pre>
</div>
<p>I&#8217;m not a database expert. If you know why that works but not the original (and more direct) version, leave a comment.</p>
<p>[<strong>UPDATE</strong>: A commenter told me that complicated maths functions don't work on aggregates. The sum(A) result is an aggregated result. Apparently sum(A)/sum(B) is too complicated. Oh well...]</p>
<p>As part of that same programming task, I had to deal with another similar problem:</p>
<div class="codediv">
<pre>
select 50 * (sum(A)/sum(B) - 0.7) from sometable
</pre>
</div>
<p>That SQL query also didn&#8217;t run. So here&#8217;s the partial fraction combining process:</p>
<p>50 * (sum(A)/sum(B) &#8211; 0.7)<br />
= 50*sum(A)/sum(B) &#8211; 35<br />
= ( 50*sum(A) &#8211; 35*sum(B) ) / sum(B)</p>
<h3>Alternatives</h3>
<p>Now I know there&#8217;s another option. I could get sum(A) and sum(B) individually, and then do the required calculation in code (C# code as opposed to database SQL code. I was dealing with ASP.NET then).</p>
<p>After considering my options, I decided to leave all the calculations at the database side. This makes the ASP.NET code &#8220;cleaner&#8221;. Then I only have to deal with one return value (instead of 2, sum(A) and sum(B)), and I can bind it directly to my database objects for display on the web browser.</p>
<p>Also, there were where (and group-by? Can&#8217;t remember&#8230;) clauses in the SQL query. I didn&#8217;t know if I obtained sum(A) and sum(B) individually (even if they were in the same query) that that will affect their values. I decided to play it safe, and just get it all in one resulting value from the same query.</p>
<p>I didn&#8217;t check for efficiency. It wasn&#8217;t an oft-used report, so the code execution won&#8217;t be run frequently enough to matter.</p>
<p>But if you&#8217;re curious enough to do some tests, go ahead. If you then want to share your results, I&#8217;d very much appreciate it too.</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/03/07/partial-fractions-sql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Announcing SpreadsheetLight version 1.1</title>
		<link>http://polymathprogrammer.com/2012/02/20/spreadsheetlight-1pt1/</link>
		<comments>http://polymathprogrammer.com/2012/02/20/spreadsheetlight-1pt1/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 14:54:17 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[spreadsheet]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3369</guid>
		<description><![CDATA[After much researching and programming and suffering (and tea), I&#8217;m happy to announce that version 1.1 of SpreadsheetLight is up! SpreadsheetLight is a spreadsheet manipulation library based on Open XML. I added some functionality for defined names and clearing out data from rows/columns/cells. You can also split worksheet panes now. Version 1 didn&#8217;t have split [...]]]></description>
			<content:encoded><![CDATA[<p>After much researching and programming and suffering (and tea), I&#8217;m happy to announce that <a href="http://polymathprogrammer.com/store/spreadsheetlight/">version 1.1 of SpreadsheetLight</a> is up! SpreadsheetLight is a spreadsheet manipulation library based on Open XML.</p>
<p>I added some functionality for defined names and clearing out data from rows/columns/cells. You can also split worksheet panes now. <a href="http://polymathprogrammer.com/2012/01/10/launching-spreadsheetlight/">Version 1 didn&#8217;t have split pane functionality</a> because I couldn&#8217;t find a way to make it easy for the programmer. Well, I wrote a function that allows you to do it with a minimum of fuss.</p>
<p>But the main bulk of version 1.1 updates is the insert/delete rows/columns part. Say you want to insert 4 rows at the 3rd row. This means all the rows from the 3rd row (including the 3rd row) must be shifted downwards 4 rows. Every merged cell, cell formula, table and defined name must be accounted for.</p>
<p>Merged cells need to be enlarged or trimmed off as needed. Or just simply deleted if it&#8217;s entirely within the delete range.</p>
<p>Tables need to be updated so the cell references within are correctly adjusted. If it used to contain C3:F6, after inserting 4 rows, it has to be C7:F10.</p>
<p>Cell formulas and defined names are sort of related, with the former typically of a more complex form than the latter. Consider taking on something like this:</p>
<p>= A1 +LOG10 +&#8221;BCD32&#8243; -SUM($H6:Sheet1!K$9) *LOG10($F$5) + BCD32 &#8211; SUM(F2:G3)</p>
<p>That has to become this:</p>
<p>= A1 +LOG14 +&#8221;BCD32&#8243; -SUM($H10:Sheet1!K$13) *LOG10($F$9) + BCD36 &#8211; SUM(F2:G7)</p>
<p>Note the LOG10 part. The first instance is a cell reference. The second is the logarithm function, base 10, of the cell originally $F$5. Note also that the first instance of BCD32 is a literal string. Literal strings should not be changed, even if they contain a valid cell reference.</p>
<p>That part took me quite a while. Let&#8217;s just say I&#8217;m glad I&#8217;m fairly proficient in regular expressions&#8230;</p>
<p>The only thing I left out was pictures (aka worksheet drawings) for insert/delete rows/columns. To create similar behaviour to when you&#8217;re doing it in Excel requires more arcane coding&#8230;</p>
<p>So if you&#8217;re looking for a spreadsheet library that&#8217;s light-weight yet capable of heavy-weight functionality, with simple-to-use functions, then consider <a href="http://polymathprogrammer.com/store/spreadsheetlight/">SpreadsheetLight</a>. Or tell your boss.</p>
<p>I&#8217;ve also included a Platinum version, which includes the source code of SpreadsheetLight (licensed with the MIT license). So if you want to know how I accomplished all that magic, consider the Platinum version then. Lots of comments to make the hairy parts less hairy&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/02/20/spreadsheetlight-1pt1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image rotation with bilinear interpolation and alpha progressive borders</title>
		<link>http://polymathprogrammer.com/2012/02/02/image-rotation-bilinear-interpolation-alpha-progressive-borders/</link>
		<comments>http://polymathprogrammer.com/2012/02/02/image-rotation-bilinear-interpolation-alpha-progressive-borders/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 14:10:02 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[alpha]]></category>
		<category><![CDATA[bilinear interpolation]]></category>
		<category><![CDATA[border]]></category>
		<category><![CDATA[edge pixel]]></category>
		<category><![CDATA[image rotation]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[progressive]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3350</guid>
		<description><![CDATA[So a blog reader, Fabien Auréjac, emailed me an improvement over the code I posted on image rotation. Here&#8217;s the one with bilinear interpolation, and here&#8217;s the one with bilinear interpolation and no clipping. Fabien translated the core of my code into PHP. The improvement was on assigning alpha values to the edge pixels after [...]]]></description>
			<content:encoded><![CDATA[<p>So a blog reader, Fabien Auréjac, emailed me an improvement over the code I posted on image rotation. Here&#8217;s <a href="http://polymathprogrammer.com/2008/10/06/image-rotation-with-bilinear-interpolation/">the one with bilinear interpolation</a>, and here&#8217;s <a href="http://polymathprogrammer.com/2010/04/05/image-rotation-with-bilinear-interpolation-and-no-clipping/">the one with bilinear interpolation and no clipping</a>.</p>
<p>Fabien translated the core of my code into PHP. The improvement was on assigning alpha values to the edge pixels after rotation. Edge pixels are pixels beside the &#8220;blank&#8221; pixels (I used black in my code, for instance). The alpha values mean the edge pixels are &#8220;softer&#8221; and thus the resulting image looks smoother.</p>
<p>I suppose if you really want to, you could also &#8220;dumb down&#8221; the values of the red, green and blue colour components for more softening (in addition to the alpha component). I say &#8220;dumb down&#8221; because the blank pixels I used are black (meaning zero for the RGB values). You&#8217;re free to go ahead and do more interpolation.</p>
<p>Fabien has given permission for me to post the code here. I&#8217;ll leave it as an exercise for you to translate to your programming language.</p>
<div class="codediv">
<pre>
$distOmbre=3;
$flouOmbre=4;
$angleRot=60;
$img=imagecreatefromjpeg("media/diapo-Chinon.jpg");
$size=getimagesize("media/diapo-Chinon.jpg");
$LsupH=($size[0]&gt;$size[1])?1:0;
$angleBool=(int)($angleRot/90)%2==0?0:1;
if (($angleBool+$LsupH)%2==0) {
	$largeur=round(abs($size[0]*sin($angleRot%90*pi()/180))+abs($size[1]*sin((90-$angleRot%90)*pi()/180)));
	$hauteur=round(abs($size[0]*cos($angleRot%90*pi()/180))+abs($size[1]*cos((90-$angleRot%90)*pi()/180)));
} else {
	$largeur=round(abs($size[0]*cos($angleRot%90*pi()/180))+abs($size[1]*cos((90-$angleRot%90)*pi()/180)));
	$hauteur=round(abs($size[0]*sin($angleRot%90*pi()/180))+abs($size[1]*sin((90-$angleRot%90)*pi()/180)));
}
$largeur+=$distOmbre+$flouOmbre*2;
$hauteur+=$distOmbre+$flouOmbre*2;
$angleRot*=pi()/180;
$imgRot=imagecreatetruecolor($largeur, $hauteur);
imagealphablending($imgRot, true);
imageantialias($imgRot, true);
for ($i=0; $i&lt;$hauteur; $i++) {
	for ($j=0; $j&lt;$largeur; $j++) {
		// convert raster to Cartesian
        $x = $j - $largeur*0.5;
        $y = $hauteur*0.5 - $i;

        // convert Cartesian to polar
        $fDistance = sqrt($x * $x + $y * $y);
   	 	$fPolarAngle = atan2($y, $x);

        // the crucial rotation part
        // "reverse" rotate, so minus instead of plus
        $fPolarAngle -= $angleRot;
		 // convert polar to Cartesian
        $fTrueX = $fDistance * cos($fPolarAngle);
        $fTrueY = $fDistance * sin($fPolarAngle);

        // convert Cartesian to raster
        $fTrueX = $fTrueX + $size[0]*0.5;
        $fTrueY = $size[1]*0.5 - $fTrueY;

        $iFloorX = (int)(floor($fTrueX));
        $iFloorY = (int)(floor($fTrueY));
        $iCeilingX = (int)(ceil($fTrueX));
        $iCeilingY = (int)(ceil($fTrueY));
        //echo $fTrueX." ".$fTrueY." ".$iFloorX." ".$iCeilingX." ".$iFloorY." ".$iCeilingY."&lt;br&gt;";
		if ($iFloorX &gt;= 0 &#038;&#038; $iCeilingX &gt;= 0 &#038;&#038; $iFloorX &lt; $size[0] &#038;&#038; $iCeilingX &lt; $size[0] &#038;&#038; $iFloorY &gt;= 0 &#038;&#038; $iCeilingY &gt;= 0 &#038;&#038; $iFloorY &lt; $size[1] &#038;&#038; $iCeilingY &lt; $size[1]) {
			$fDeltaX = $fTrueX - $iFloorX;
			$fDeltaY = $fTrueY - $iFloorY;
			$clrTopLeft = imagecolorat($img, $iFloorX, $iFloorY);
			$colorsTopLeft = imagecolorsforindex($img, $clrTopLeft);
			$clrTopRight = imagecolorat($img, $iCeilingX, $iFloorY);
			$colorsTopRight = imagecolorsforindex($img, $clrTopRight);
			$clrBottomLeft = imagecolorat($img, $iFloorX, $iCeilingY);
			$colorsBottomLeft = imagecolorsforindex($img, $clrBottomLeft);
			$clrBottomRight = imagecolorat($img, $iCeilingX, $iCeilingY);
			$colorsBottomRight = imagecolorsforindex($img, $clrBottomRight);
			// linearly interpolate horizontally between top neighbours
			$fTopRed = (1 - $fDeltaX) * $colorsTopLeft['red'] + $fDeltaX * $colorsTopRight['red'];
			$fTopGreen = (1 - $fDeltaX) * $colorsTopLeft['green'] + $fDeltaX * $colorsTopRight['green'];
			$fTopBlue = (1 - $fDeltaX) * $colorsTopLeft['blue'] + $fDeltaX * $colorsTopRight['blue'];
			// linearly interpolate horizontally between bottom neighbours
			$fBottomRed = (1 - $fDeltaX) * $colorsBottomLeft['red'] + $fDeltaX * $colorsBottomRight['red'];
			$fBottomGreen = (1 - $fDeltaX) * $colorsBottomLeft['green'] + $fDeltaX * $colorsBottomRight['green'];
			$fBottomBlue = (1 - $fDeltaX) * $colorsBottomLeft['blue'] + $fDeltaX * $colorsBottomRight['blue'];
			// linearly interpolate vertically between top and bottom interpolated results
			$iRed = (int)(round((1 - $fDeltaY) * $fTopRed + $fDeltaY * $fBottomRed));
			$iGreen = (int)(round((1 - $fDeltaY) * $fTopGreen + $fDeltaY * $fBottomGreen));
			$iBlue = (int)(round((1 - $fDeltaY) * $fTopBlue + $fDeltaY * $fBottomBlue));
			// make sure colour values are valid
			if ($iRed &lt; 0) $iRed = 0;
			if ($iRed &gt; 255) $iRed = 255;
			if ($iGreen &lt; 0) $iGreen = 0;
			if ($iGreen &gt; 255) $iGreen = 255;
			if ($iBlue &lt; 0) $iBlue = 0;
			if ($iBlue &gt; 255) $iBlue = 255;
			if ($iFloorX &gt; 0 &#038;&#038; $iCeilingX &gt; 0 &#038;&#038; $iFloorX &lt; $size[0]-1 &#038;&#038; $iCeilingX &lt; $size[0]-1 &#038;&#038; $iFloorY &gt; 0 &#038;&#038; $iCeilingY &gt; 0 &#038;&#038; $iFloorY &lt; $size[1]-1 &#038;&#038; $iCeilingY &lt; $size[1]-1) {
				$colorallocation=imagecolorallocate($imgRot, $iRed, $iGreen, $iBlue);
				imagesetpixel($imgRot, $j, $i, $colorallocation);
			} else if ($iFloorX == 0 &#038;&#038; $iFloorY &gt;= 0 &#038;&#038; $iCeilingY &gt;= 0 &#038;&#038; $iFloorY &lt; $size[1] &#038;&#038; $iCeilingY &lt; $size[1]) {//left
				$alpha=round((1-abs($fDeltaX))*127);
				$colorallocation=imagecolorallocatealpha($imgRot, $iRed, $iGreen, $iBlue, $alpha);
				imagesetpixel($imgRot, $j, $i, $colorallocation);
			} else if ($iFloorX &gt;= 0 &#038;&#038; $iCeilingX &gt;= 0 &#038;&#038; $iFloorX &lt; $size[0] &#038;&#038; $iCeilingX &lt; $size[0] &#038;&#038; $iFloorY == 0) {//top
				$alpha=round((1-abs($fDeltaY))*127);
				$colorallocation=imagecolorallocatealpha($imgRot, $iRed, $iGreen, $iBlue, $alpha);
				imagesetpixel($imgRot, $j, $i, $colorallocation);
			} else if ($iCeilingX == $size[0]-1 &#038;&#038; $iFloorY &gt;= 0 &#038;&#038; $iCeilingY &gt;= 0 &#038;&#038; $iFloorY &lt; $size[1] &#038;&#038; $iCeilingY &lt; $size[1]) {//right
				$alpha=round(abs($fDeltaX)*127);
				$colorallocation=imagecolorallocatealpha($imgRot, $iRed, $iGreen, $iBlue, $alpha);
				imagesetpixel($imgRot, $j, $i, $colorallocation);
			} else if ($iFloorX &gt;= 0 &#038;&#038; $iCeilingX &gt;= 0 &#038;&#038; $iFloorX &lt; $size[0] &#038;&#038; $iCeilingX &lt; $size[0] &#038;&#038; $iCeilingY == $size[1]-1) {//bottom
				$alpha=round(abs($fDeltaY)*127);
				$colorallocation=imagecolorallocatealpha($imgRot, $iRed, $iGreen, $iBlue, $alpha);
				imagesetpixel($imgRot, $j, $i, $colorallocation);
			}
		}
	}
}
</pre>
</div>
<p>Fabien is French (I think), which is why you get variable names such as distOmbre (shadow distance?), flouOmbre (fuzzy shadow?), largeur (width), hauteur (height). And this one took me a bit more time to translate&#8230; LsupH is probably &#8220;width greater than height?&#8221;. The &#8220;L&#8221; probably refers to &#8220;largeur&#8221;, and &#8220;H&#8221; refers to &#8220;hauteur&#8221;.</p>
<p>Reading international programming code is fun. *smile*</p>
<p>There&#8217;s also an interesting piece of code:</p>
<div class="codediv">
<pre>
$size=getimagesize("media/diapo-Chinon.jpg");
$LsupH=($size[0]&gt;$size[1])?1:0;
$angleBool=(int)($angleRot/90)%2==0?0:1;
if (($angleBool+$LsupH)%2==0) {
	$largeur=round(abs($size[0]*sin($angleRot%90*pi()/180))+abs($size[1]*sin((90-$angleRot%90)*pi()/180)));
	$hauteur=round(abs($size[0]*cos($angleRot%90*pi()/180))+abs($size[1]*cos((90-$angleRot%90)*pi()/180)));
} else {
	$largeur=round(abs($size[0]*cos($angleRot%90*pi()/180))+abs($size[1]*cos((90-$angleRot%90)*pi()/180)));
	$hauteur=round(abs($size[0]*sin($angleRot%90*pi()/180))+abs($size[1]*sin((90-$angleRot%90)*pi()/180)));
}
</pre>
</div>
<p>So here&#8217;s your mission, should you choose to accept it (I recently watched Mission Impossible&#8230;). <strong>What is Fabien trying to accomplish in that section of code?</strong> Hint: it has something to do with getting a &#8220;nice&#8221; resulting image width and height.</p>
<p>I&#8217;ll tell you a more &#8220;elegant&#8221; alternative to that code section. But it&#8217;ll involve some mathematics. And drawings. Prepare for poorly drawn diagrams&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/02/02/image-rotation-bilinear-interpolation-alpha-progressive-borders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Launching SpreadsheetLight</title>
		<link>http://polymathprogrammer.com/2012/01/10/launching-spreadsheetlight/</link>
		<comments>http://polymathprogrammer.com/2012/01/10/launching-spreadsheetlight/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 04:15:51 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[openxml]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[spreadsheet]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3306</guid>
		<description><![CDATA[I am excited to tell you that my spreadsheet software library is available! For the initial launch version (I decided to go for version 1. Why do people launch with versions 0.8? I don&#8217;t know&#8230;), you get comprehensive support for styles, rich text formatting, 47 named cell styles, themes (either one of the 20 built-in [...]]]></description>
			<content:encoded><![CDATA[<p>I am excited to tell you that my spreadsheet software library is available!</p>
<p><a href="http://polymathprogrammer.com/store/spreadsheetlight/"><img src="http://polymathprogrammer.com/spreadsheetlight/SpreadsheetLightBox.jpg" alt="SpreadsheetLight" /></a></p>
<p>For the initial launch version (I decided to go for version 1. Why do people launch with versions 0.8? I don&#8217;t know&#8230;), you get comprehensive support for styles, rich text formatting, 47 named cell styles, themes (either one of the 20 built-in themes or create-your-own). Well, like I said, comprehensive styling support.</p>
<p>There&#8217;s also the (hum-drum) support for merging cells and freezing panes. I actually explored how to split panes. I certainly wrote about it in my <a href="http://polymathprogrammer.com/store/spreadsheet-open-xml/">Open XML guide</a>, but it turns out that there&#8217;s a tiny rectangle at the top-left corner that Microsoft Excel didn&#8217;t tell me about. The size of that tiny rectangle is dependent on the font you use, and even the screen resolution of your computer screen.</p>
<p>While I could add a function that allows you to just input the size in EMUs (<a href="http://polymathprogrammer.com/2009/10/22/english-metric-units-and-open-xml/">English Metric Units</a>), I decided that if I can&#8217;t do it well, I don&#8217;t want to do it. At least for the initial launch.</p>
<p>Row heights and column widths were also big time drains. It turns out that they&#8217;re also dependent on the font and screen resolution of your computer screen. I was trying to calculate the standard row heights and column widths for the fonts in the built-in themes, and I thought I had them. I wrote a program using SpreadsheetLight to generate spreadsheets with different minor fonts, and I wrote a program to read in those spreadsheets and get the &#8220;standard&#8221; row height and column width. I spent 3 hours collecting data.</p>
<p>Then on a whim, I switched my computer screen&#8217;s resolution from 120 DPI to 96 DPI (my eyesight&#8217;s not that good ok? I need bigger text&#8230;), and whoa! All that data doesn&#8217;t apply anymore&#8230; All in all, I think I spent 6 or 7 days trying to figure out a general calculation formula. I failed. I don&#8217;t know how Excel does it.</p>
<p>I also surprised myself by including extensive support for pictures. I thought you just insert a picture into the worksheet and that&#8217;s it! It turns out there&#8217;s a ton of post-insertion manipulations you can do. For example, if your picture has transparent areas, you could set a background fill, and that background colour will be visible through the picture. Also, you can rotate the picture in 3D.</p>
<p>SpreadsheetLight is licensed under the MIT license. I decided to use one of the available software licenses instead of making up one of my own. As far as I can tell, the MIT license allows the recipient of the software to use the software in personal or commercial products. It&#8217;s also categorised as free software, as in freedom of use, not free as in cost. I don&#8217;t want to deal with per-client, or per-server, or per-developer or per-what-not licensing restrictions.</p>
<p>Even if you&#8217;re not interested in spreadsheet software, <a href="http://polymathprogrammer.com/store/spreadsheetlight/">have a look at SpreadsheetLight</a>. Tell some other programmer about it. Tell your manager about it. It took me slightly over 2 months of intense coding, and I want someone in the world out there to have an easier life because of SpreadsheetLight. Thanks!</p>
<p>Oh, and the image art is designed by Charlie Pabst from <a href="http://www.charfishdesign.com/">Charfish Design</a>. While I have a fair competence in image work, I decided to get a professional designer to help me. It&#8217;s a business and professional product. I&#8217;m not going to risk the product&#8217;s success so I could stoke my ego&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/01/10/launching-spreadsheetlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Named cell styles are still explicitly declared</title>
		<link>http://polymathprogrammer.com/2012/01/05/named-cell-styles-explicitly-declared/</link>
		<comments>http://polymathprogrammer.com/2012/01/05/named-cell-styles-explicitly-declared/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 05:12:14 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[named cell style]]></category>
		<category><![CDATA[spreadsheet]]></category>
		<category><![CDATA[style]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3258</guid>
		<description><![CDATA[Styling cells in Microsoft Excel has its difficulties (as I&#8217;ve written before). The biggest one is keeping track of all the indices. In Open XML SDK, you have the ability to have a named cell style. At first glance, you might think that&#8217;s awesome. You just use a named cell style, and all the related [...]]]></description>
			<content:encoded><![CDATA[<p>Styling cells in Microsoft Excel has its difficulties (<a href="http://polymathprogrammer.com/2009/12/21/advanced-styling-in-excel-open-xml/">as I&#8217;ve written before</a>). The biggest one is keeping track of all the indices. In Open XML SDK, you have the ability to have a named cell style.</p>
<p>At first glance, you might think that&#8217;s awesome. You just use a named cell style, and all the related styles are applied. It&#8217;s like there&#8217;s a red car that uses hybrid fuels. &#8220;Yes, I would like to have a red car that uses hybrid fuels.&#8221; Not quite.</p>
<p>You see, the named cell style is dependent on the implementing spreadsheet software. For example, Microsoft Excel has the &#8220;Normal&#8221;, &#8220;Bad&#8221;, &#8220;Good&#8221; and &#8220;Neutral&#8221; named cell styles. But Google Spreadsheets and OpenOffice.org Calc do not have to have those named cell styles, or even style it the same as Microsoft Excel. This is where Open XML SDK isn&#8217;t quite &#8220;open&#8221;&#8230; After much research and work, I discovered the SDK is basically Open-XML-ising Microsoft Excel (and Word and PowerPoint). I&#8217;m neutral on the stands of open source and &#8220;forcing standards&#8221;. I just use whatever there is, and make something within the limitations.</p>
<p>Because of the dependency, the underlying individual styles need to be declared explicitly. Actually more so because of the dependency.</p>
<p>So for my spreadsheet software library <strong>SpreadsheetLight</strong>, I used Excel as the guideline.</p>
<p>In researching Excel named cell styles, I had to look at the underlying XML files (because Open XML spreadsheets are made of XML files). While the Open XML SDK comes with a document explorer (the Productivity Tool), I needed to make notes and also that I felt the need to see the XML file itself, rather than using the explorer tool.</p>
<p>This gave me a problem because while XML files are supposed to be human-readable, it doesn&#8217;t make it easy to read. The &#8220;natural&#8221; XML file has no indents. Oh my Godiva chocolate, it&#8217;s so hard to read&#8230; Then I remembered I had an XML tool, <strong>XML Studio</strong>. I fired that up and a few clicks later, the XML file had nice indents and I could find out where the individual style tags were. XML Studio was amazing to use.</p>
<p><strong>Disclaimer</strong>: I was given a free developer license of XML Studio by <a href="http://www.liquid-technologies.com/">Liquid Technologies</a>. But the software is really useful if you work with XML files a lot.</p>
<p>After doing my notes for a while, I discovered even that&#8217;s not enough. There were too many individual styles! I needed the indices for those styles, because only the index was referenced in the final style (CellFormat classes). I didn&#8217;t really feel up to annotating the indices&#8230; until I remembered my partially completed <a href="http://polymathprogrammer.com/soxdecompiler/">Open XML spreadsheet decompiler tool</a>. When I created that tool, one of my aims was to put in comments on the index of the individual styles.</p>
<p>Note to Liquid Technologies: You might want to consider putting in XML comments on the index of an XML child tag with respect to its parent. But I don&#8217;t know if that&#8217;s useful to programming spheres other than Open XML&#8230;</p>
<p>Anyway, my hard work paid off, and SpreadsheetLight allows you to apply named cell styles. Here&#8217;s how the spreadsheet looks like:<br />
<img src="http://polymathprogrammer.com/images/blog/201201/applyingnamedcellstyles.png" alt="Applying named cell styles" /></p>
<p>Note that some of the named cell styles use accent colours. The accent colours are part of the spreadsheet&#8217;s theme. So in offering named cell styles as a feature, I also had to allow you to create your own theme. And here&#8217;s the code using SpreadsheetLight:</p>
<div class="codediv">
<pre>
System.Drawing.Color[] clrs = new System.Drawing.Color[12];
clrs[0] = System.Drawing.Color.White;
clrs[1] = System.Drawing.Color.Black;
clrs[2] = System.Drawing.Color.WhiteSmoke;
clrs[3] = System.Drawing.Color.DarkSlateGray;
clrs[4] = System.Drawing.Color.DarkRed;
clrs[5] = System.Drawing.Color.OrangeRed;
clrs[6] = System.Drawing.Color.DarkGoldenrod;
clrs[7] = System.Drawing.Color.DarkOliveGreen;
clrs[8] = System.Drawing.Color.Navy;
clrs[9] = System.Drawing.Color.Indigo;
clrs[10] = System.Drawing.Color.SkyBlue;
clrs[11] = System.Drawing.Color.MediumPurple;

SLDocument sl = new SLDocument("ColourWheel", "Castellar", "Harrington", clrs);

sl.SetRowHeight(6, 24);
sl.SetColumnWidth(1, 1);
sl.SetColumnWidth(2, 13);
sl.SetColumnWidth(3, 13);
sl.SetColumnWidth(4, 13);
sl.SetColumnWidth(5, 13);
sl.SetColumnWidth(6, 13);
sl.SetColumnWidth(7, 13);

sl.SetCellValue(2, 2, "Normal");
sl.ApplyNamedCellStyle(2, 2, SLNamedCellStyleValues.Normal);
sl.SetCellValue(2, 3, "Bad");
sl.ApplyNamedCellStyle(2, 3, SLNamedCellStyleValues.Bad);
sl.SetCellValue(2, 4, "Good");
sl.ApplyNamedCellStyle(2, 4, SLNamedCellStyleValues.Good);
sl.SetCellValue(2, 5, "Neutral");
sl.ApplyNamedCellStyle(2, 5, SLNamedCellStyleValues.Neutral);

sl.SetCellValue(3, 2, "Calculation");
sl.ApplyNamedCellStyle(3, 2, SLNamedCellStyleValues.Calculation);
sl.SetCellValue(3, 3, "Check Cell");
sl.ApplyNamedCellStyle(3, 3, SLNamedCellStyleValues.CheckCell);
sl.SetCellValue(3, 4, "Explanatory Text");
sl.ApplyNamedCellStyle(3, 4, SLNamedCellStyleValues.ExplanatoryText);
sl.SetCellValue(3, 5, "Input");
sl.ApplyNamedCellStyle(3, 5, SLNamedCellStyleValues.Input);

sl.SetCellValue(4, 2, "Linked Cell");
sl.ApplyNamedCellStyle(4, 2, SLNamedCellStyleValues.LinkedCell);
sl.SetCellValue(4, 3, "Note");
sl.ApplyNamedCellStyle(4, 3, SLNamedCellStyleValues.Note);
sl.SetCellValue(4, 4, "Output");
sl.ApplyNamedCellStyle(4, 4, SLNamedCellStyleValues.Output);
sl.SetCellValue(4, 5, "Warning Text");
sl.ApplyNamedCellStyle(4, 5, SLNamedCellStyleValues.WarningText);

sl.SetCellValue(6, 2, "Heading 1");
sl.ApplyNamedCellStyle(6, 2, SLNamedCellStyleValues.Heading1);
sl.SetCellValue(6, 3, "Heading 2");
sl.ApplyNamedCellStyle(6, 3, SLNamedCellStyleValues.Heading2);
sl.SetCellValue(6, 4, "Heading 3");
sl.ApplyNamedCellStyle(6, 4, SLNamedCellStyleValues.Heading3);
sl.SetCellValue(6, 5, "Heading 4");
sl.ApplyNamedCellStyle(6, 5, SLNamedCellStyleValues.Heading4);
sl.SetCellValue(6, 6, "Title");
sl.ApplyNamedCellStyle(6, 6, SLNamedCellStyleValues.Title);
sl.SetCellValue(6, 7, "Total");
sl.ApplyNamedCellStyle(6, 7, SLNamedCellStyleValues.Total);

sl.SetCellValue(8, 2, "Accent1");
sl.ApplyNamedCellStyle(8, 2, SLNamedCellStyleValues.Accent1);
sl.SetCellValue(8, 3, "Accent2");
sl.ApplyNamedCellStyle(8, 3, SLNamedCellStyleValues.Accent2);
sl.SetCellValue(8, 4, "Accent3");
sl.ApplyNamedCellStyle(8, 4, SLNamedCellStyleValues.Accent3);
sl.SetCellValue(8, 5, "Accent4");
sl.ApplyNamedCellStyle(8, 5, SLNamedCellStyleValues.Accent4);
sl.SetCellValue(8, 6, "Accent5");
sl.ApplyNamedCellStyle(8, 6, SLNamedCellStyleValues.Accent5);
sl.SetCellValue(8, 7, "Accent6");
sl.ApplyNamedCellStyle(8, 7, SLNamedCellStyleValues.Accent6);

sl.SetCellValue(9, 2, "Accent1Perc60");
sl.ApplyNamedCellStyle(9, 2, SLNamedCellStyleValues.Accent1Percentage60);
sl.SetCellValue(9, 3, "Accent2Perc60");
sl.ApplyNamedCellStyle(9, 3, SLNamedCellStyleValues.Accent2Percentage60);
sl.SetCellValue(9, 4, "Accent3Perc60");
sl.ApplyNamedCellStyle(9, 4, SLNamedCellStyleValues.Accent3Percentage60);
sl.SetCellValue(9, 5, "Accent4Perc60");
sl.ApplyNamedCellStyle(9, 5, SLNamedCellStyleValues.Accent4Percentage60);
sl.SetCellValue(9, 6, "Accent5Perc60");
sl.ApplyNamedCellStyle(9, 6, SLNamedCellStyleValues.Accent5Percentage60);
sl.SetCellValue(9, 7, "Accent6Perc60");
sl.ApplyNamedCellStyle(9, 7, SLNamedCellStyleValues.Accent6Percentage60);

sl.SetCellValue(10, 2, "Accent1Perc40");
sl.ApplyNamedCellStyle(10, 2, SLNamedCellStyleValues.Accent1Percentage40);
sl.SetCellValue(10, 3, "Accent2Perc40");
sl.ApplyNamedCellStyle(10, 3, SLNamedCellStyleValues.Accent2Percentage40);
sl.SetCellValue(10, 4, "Accent3Perc40");
sl.ApplyNamedCellStyle(10, 4, SLNamedCellStyleValues.Accent3Percentage40);
sl.SetCellValue(10, 5, "Accent4Perc40");
sl.ApplyNamedCellStyle(10, 5, SLNamedCellStyleValues.Accent4Percentage40);
sl.SetCellValue(10, 6, "Accent5Perc40");
sl.ApplyNamedCellStyle(10, 6, SLNamedCellStyleValues.Accent5Percentage40);
sl.SetCellValue(10, 7, "Accent6Perc40");
sl.ApplyNamedCellStyle(10, 7, SLNamedCellStyleValues.Accent6Percentage40);

sl.SetCellValue(11, 2, "Accent1Perc20");
sl.ApplyNamedCellStyle(11, 2, SLNamedCellStyleValues.Accent1Percentage20);
sl.SetCellValue(11, 3, "Accent2Perc20");
sl.ApplyNamedCellStyle(11, 3, SLNamedCellStyleValues.Accent2Percentage20);
sl.SetCellValue(11, 4, "Accent3Perc20");
sl.ApplyNamedCellStyle(11, 4, SLNamedCellStyleValues.Accent3Percentage20);
sl.SetCellValue(11, 5, "Accent4Perc20");
sl.ApplyNamedCellStyle(11, 5, SLNamedCellStyleValues.Accent4Percentage20);
sl.SetCellValue(11, 6, "Accent5Perc20");
sl.ApplyNamedCellStyle(11, 6, SLNamedCellStyleValues.Accent5Percentage20);
sl.SetCellValue(11, 7, "Accent6Perc20");
sl.ApplyNamedCellStyle(11, 7, SLNamedCellStyleValues.Accent6Percentage20);

sl.SetCellValue(13, 2, 12345678);
sl.ApplyNamedCellStyle(13, 2, SLNamedCellStyleValues.Comma);
sl.SetCellValue(13, 4, 12345678);
sl.ApplyNamedCellStyle(13, 4, SLNamedCellStyleValues.Comma0);
sl.SetCellValue(14, 2, 12345678);
sl.ApplyNamedCellStyle(14, 2, SLNamedCellStyleValues.Currency);
sl.SetCellValue(14, 4, 12345678);
sl.ApplyNamedCellStyle(14, 4, SLNamedCellStyleValues.Currency0);
sl.SetCellValue(15, 2, 123);
sl.ApplyNamedCellStyle(156, 2, SLNamedCellStyleValues.Percentage);

sl.SaveAs("NamedCellStyles.xlsx");
</pre>
</div>
<p>I set the column widths of the 2nd to 7th column, and the row height of the 6th row so it&#8217;s easier to see.</p>
<p>The main body text (the minor font) is in Harrington, and the title font (major font) is Castellar. You will note that even though the major font is supposedly used for heading and title texts, only the named cell style Title uses the major font. The headings 1 through 4 use the minor font.</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2012/01/05/named-cell-styles-explicitly-declared/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rich strings and inline strings in spreadsheets</title>
		<link>http://polymathprogrammer.com/2011/12/13/rich-strings-inline-strings-spreadsheets/</link>
		<comments>http://polymathprogrammer.com/2011/12/13/rich-strings-inline-strings-spreadsheets/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 06:09:37 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[inline string]]></category>
		<category><![CDATA[rich string]]></category>
		<category><![CDATA[spreadsheet]]></category>

		<guid isPermaLink="false">http://polymathprogrammer.com/?p=3212</guid>
		<description><![CDATA[Quite a while ago, I was mucking around in Excel and I discovered you can set the text in a cell to different fonts! Even different colours! (Ok, you&#8217;re probably bored of me going on about spreadsheets and Open XML, but it&#8217;s all I&#8217;m thinking about right now&#8230;) Granted, it&#8217;s a limited set of font [...]]]></description>
			<content:encoded><![CDATA[<p>Quite a while ago, I was mucking around in Excel and I discovered you can set the text in a cell to different fonts! Even different colours! (Ok, you&#8217;re probably bored of me going on about spreadsheets and Open XML, but it&#8217;s all I&#8217;m thinking about right now&#8230;) Granted, it&#8217;s a limited set of font style manipulations, but I&#8217;ve always thought the text in a cell was completely subjected to the cell style. I never thought you could change anything within a cell. I&#8217;m not an expert Excel user, ok?</p>
<p>The term used is an &#8220;inline string&#8221;. At least that&#8217;s what it&#8217;s referred to in the Open XML SDK, as the InlineString class.</p>
<p>This gave me a problem. How do I implement this in my <a href="http://polymathprogrammer.com/2011/12/05/working-on-spreadsheet-software-library/">spreadsheet library</a>? It&#8217;s not as easy as just setting a cell value. You&#8217;d have to set up all the fonts and colours and bolds and italics and underlines, and then dump that bunch of stuff into a cell.</p>
<p>If you do it by hand, you&#8217;ll run (haha, foretelling a pun) into the DocumentFormat.OpenXml.Spreadsheet.Run class. Basically, you&#8217;re appending style runs. Here&#8217;s how you do it in Excel:</p>
<p><img src="http://polymathprogrammer.com/images/blog/201112/inlinestring.png" alt="Inline string" /></p>
<p>You select the text in the formula box (not within the cell). Then you apply any font styles you want.</p>
<p>Aaannd&#8230; here&#8217;s where I tell you how my spreadsheet library is going to make your life easier. Here&#8217;s a sample screenshot of a result:</p>
<p><img src="http://polymathprogrammer.com/images/blog/201112/spreadsheetlightinlinestring.png" alt="SpreadsheetLight inline string" /></p>
<p>Let&#8217;s look at the source code to generate that.</p>
<div class="codediv">
<pre>
SLDocument sl = new SLDocument(SLThemeTypeValues.Metro);

SLFont font;
SLRstType rst;

font = new SLFont();
font.FontColor = System.Drawing.Color.Red;
rst = new SLRstType();
rst.AppendText("Roses are ");
rst.AppendText("red", font);
sl.SetCellValue(2, 2, rst.ToInlineString());

font = new SLFont();
font.FontColor = System.Drawing.Color.Blue;
rst = new SLRstType();
rst.AppendText("And violets are ");
rst.AppendText("blue", font);
sl.SetCellValue(3, 2, rst.ToInlineString());

font = new SLFont();
font.Bold = true;
font.Italic = true;
font.Underline = UnderlineValues.Double;
font.SetFont(FontSchemeValues.Major, 11);
font.SetFontThemeColor(SLThemeColorIndexValues.Accent2Color);
rst = new SLRstType();
rst.AppendText("But seriously...", font);
sl.SetCellValue(4, 2, rst.ToInlineString());

font = new SLFont();
font.SetFont(FontSchemeValues.Minor, 15);
font.SetFontThemeColor(SLThemeColorIndexValues.Accent1Color);
rst = new SLRstType();
rst.AppendText("you don't ", font);

font = new SLFont();
font.Italic = true;
rst.AppendText("have ", font);

rst.AppendText("to ");

font = new SLFont();
font.Underline = UnderlineValues.Single;
font.FontColor = System.Drawing.Color.OrangeRed;
rst.AppendText("emphasise ", font);

rst.AppendText("it ");

font = new SLFont();
font.Bold = true;
font.SetFontThemeColor(SLThemeColorIndexValues.Accent3Color);
rst.AppendText("so ", font);

rst.AppendText("much...");

sl.SetCellValue(5, 2, rst.ToInlineString());

SLStyle style = new SLStyle();
style.Fill.SetPatternForegroundColor(SLThemeColorIndexValues.Accent1Color);
style.Fill.SetPatternType(PatternValues.Solid);
sl.SetCellStyle(7, 2, style);
sl.SetCellValue(7, 3, "Accent 1");

style = new SLStyle();
style.Fill.SetPatternForegroundColor(SLThemeColorIndexValues.Accent2Color);
style.Fill.SetPatternType(PatternValues.Solid);
sl.SetCellStyle(8, 2, style);
sl.SetCellValue(8, 3, "Accent 2");

style = new SLStyle();
style.Fill.SetPatternForegroundColor(SLThemeColorIndexValues.Accent3Color);
style.Fill.SetPatternType(PatternValues.Solid);
sl.SetCellStyle(9, 2, style);
sl.SetCellValue(9, 3, "Accent 3");

style = new SLStyle();
style.Fill.SetPatternForegroundColor(SLThemeColorIndexValues.Accent4Color);
style.Fill.SetPatternType(PatternValues.Solid);
sl.SetCellStyle(10, 2, style);
sl.SetCellValue(10, 3, "Accent 4");

style = new SLStyle();
style.Fill.SetPatternForegroundColor(SLThemeColorIndexValues.Accent5Color);
style.Fill.SetPatternType(PatternValues.Solid);
sl.SetCellStyle(11, 2, style);
sl.SetCellValue(11, 3, "Accent 5");

style = new SLStyle();
style.Fill.SetPatternForegroundColor(SLThemeColorIndexValues.Accent6Color);
style.Fill.SetPatternType(PatternValues.Solid);
sl.SetCellStyle(12, 2, style);
sl.SetCellValue(12, 3, "Accent 6");

sl.SaveAs("InlineString.xlsx");
</pre>
</div>
<p>I&#8217;m using the Metro theme, which means the major Latin font is Consolas, and the minor Latin font is Corbel. The body text is in minor Latin font.</p>
<p>You&#8217;ll notice the 2 new classes, SLFont and SLRstType classes. The SLRstType models after the Open XML SDK (abstract) class RstType. I think it stands for &#8220;rich string type&#8221; (r + st + type).</p>
<p>I have filled in 6 cells with the accent colours, just so you can see how the colours are used. The accent colours are tied to the theme used, as is the major and minor Latin fonts. So if you use these colours and fonts, the text is automatically formatted against the current theme.</p>
<p>This is an advantage if you set the font as the minor Latin font, instead of directly as &#8220;Corbel&#8221;. If the user changes the theme of your resulting spreadsheet, the text changes to the new theme&#8217;s minor Latin font. Of course, if you want the text to stay as &#8220;Corbel&#8221;, regardless of the theme, then set it directly and explicitly as &#8220;Corbel&#8221;. The SLFont class has overloaded functions for this.</p>
<p>P.S. Can you tell I&#8217;m excited about this? I&#8217;m going to launch this baby. Soon. I will limit such &#8220;promotional&#8221; articles, but I really think Excel gives me surprises, so I thought you might want to know what your user thinks is normal Excel activity.</p>
]]></content:encoded>
			<wfw:commentRss>http://polymathprogrammer.com/2011/12/13/rich-strings-inline-strings-spreadsheets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

