<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET4Office</title><link>http://blogs.msdn.com/eric_carter/default.aspx</link><description>A blog by Eric Carter</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>8. VSTO Bug Tracker : Using a Ribbon</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/14/8-vsto-bug-tracker-using-a-ribbon.aspx</link><pubDate>Thu, 14 May 2009 18:19:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616768</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9616768.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9616768</wfw:commentRss><description>&lt;p&gt;To get started, from the Project menu choose Add New Item. In the Add New Item dialog box, click Ribbon (Visual Designer). Then click the Add button. A new Ribbon is created and the Ribbon Designer is displayed. &lt;/p&gt;  &lt;p&gt;Next, click on the Group control that is created for you and change the Label in the Properties window to “Bugs” as well. Drag and drop a Button control from the Toolbox onto the Group control.&amp;#160; Use the Properties window to set the Label for the button to “Add Bug Data”.&amp;#160; Also, set the ControlSize to RibbonControlSizeLarge and set an Image for the button if you like.&amp;#160; Double click on the Button control to add an event handler.&amp;#160; The event handler will invoke the PopulateSpreadsheet method.&amp;#160; You can now remove the SheetBeforeRightClick handler that we added earlier if you like.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; AddBugData_Click(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; System.&lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; AddBugData.Click
        Globals.ThisAddIn.PopulateSpreadsheet(&lt;span class="kwrd"&gt;True&lt;/span&gt;)
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
&lt;style type="text/css"&gt;





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Then, drag and drop a Gallery control from the Toolbox onto the Group control. Use the Properties window to set the Label for the Gallery control to “Bug Charts”. Also, set the ControlSize to RibbonControlSizeLarge and set an Image for the Gallery control if you like.&lt;/p&gt;

&lt;p&gt;With the Gallery control configured the way we want, let’s write some code behind it. Click on the Gallery control again to select it. Then click on the lightning bolt icon button in the Properties window to show the events for the Gallery control. Three events are displayed. Click is raised when an item in our Items collection is clicked. And ItemsLoading is raised when the user drops down the Gallery control before its contents are displayed—this is the event that can be handled at runtime to modify the Items and Buttons lists before the Gallery control is displayed to the user.&lt;/p&gt;

&lt;p&gt;We want to add handlers for ItemsLoading and Click. First, let’s write the handler for the ItemsLoading event. Double click on the ItemsLoading event in the Properties window and Visual Studio generates an event handler in the code behind the Ribbon and displays the event handler. Add the code below.&amp;#160; What does this code do?&amp;#160; It will dynamically populate the Gallery control with a RibbonDropDownItem for each chart in the workbook.&amp;#160; It sets the RibbonDropDownItem to the image of the chart.&amp;#160; It also tags each RibbonDropDownItem with an identifier that the Click event will use.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Gallery1_ItemsLoading(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; System.&lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; Gallery1.ItemsLoading
        Gallery1.Items.Clear()

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; c &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Worksheet
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; tag &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; tempFileName &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = System.IO.Path.GetTempFileName()

        &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; s &lt;span class="kwrd"&gt;In&lt;/span&gt; Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; i &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;
            &lt;span class="kwrd"&gt;For&lt;/span&gt; i = 1 &lt;span class="kwrd"&gt;To&lt;/span&gt; s.ChartObjects.Count
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; d &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; RibbonDropDownItem
                c = s.ChartObjects(i)

                c.Chart.Export(tempFileName, &lt;span class="str"&gt;&amp;quot;BMP&amp;quot;&lt;/span&gt;)
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; bmpTemp &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.Drawing.Bitmap(tempFileName)
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; bmpUnlinked &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.Drawing.Bitmap(bmpTemp)
                bmpTemp.Dispose()
                d.Image = bmpUnlinked

                d.Tag = tag
                Gallery1.Items.Add(d)
                tag = tag + 1
            &lt;span class="kwrd"&gt;Next&lt;/span&gt;
        &lt;span class="kwrd"&gt;Next&lt;/span&gt;

        System.IO.File.Delete(tempFileName)
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;

&lt;p&gt;Now click on the Gallery control again to select it, then double click on the Click event in the Properties window and Visual Studio generates an event handler in the code behind the Ribbon and displays the event handler.&amp;#160;&amp;#160; In the Click event we will activate the chart corresponding to the RibbonDropDownItem.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Gallery1_Click(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; System.&lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; Gallery1.Click
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; tagFound &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt; = Gallery1.SelectedItem.Tag
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Worksheet
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; tag &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;

        &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; s &lt;span class="kwrd"&gt;In&lt;/span&gt; Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; i &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;
            &lt;span class="kwrd"&gt;For&lt;/span&gt; i = 1 &lt;span class="kwrd"&gt;To&lt;/span&gt; s.ChartObjects.Count
                &lt;span class="kwrd"&gt;If&lt;/span&gt; tagFound = tag &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                    s.ChartObjects(i).Activate()
                    &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
                &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
                tag = tag + 1
            &lt;span class="kwrd"&gt;Next&lt;/span&gt;
        &lt;span class="kwrd"&gt;Next&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;

&lt;p&gt;When we run the add-in, we get this result when you drop down the gallery control for a document with two charts in it.&amp;#160; The gallery control updates to display images of the current charts in the workbook.&amp;#160; If you click one of the drop down items, it activates the corresponding chart in the workbook.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/7.VSTOBugTrackerUsingaRibbon_11A8B/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/7.VSTOBugTrackerUsingaRibbon_11A8B/image_thumb.png" width="644" height="440" /&gt;&lt;/a&gt; &lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;That’s all folks!&amp;#160; Hoped you enjoyed this example of using VSTO.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616768" width="1" height="1"&gt;</description></item><item><title>7. VSTO Bug Tracker : Using Document-Level Features in Add-Ins</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/14/7-vsto-bug-tracker-using-document-level-features-in-add-ins.aspx</link><pubDate>Thu, 14 May 2009 18:18:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616764</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9616764.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9616764</wfw:commentRss><description>&lt;p&gt;Prior to Visual Studio 2008 SP1, you couldn’t use common VSTO features like controls in the document and databinding to list objects at the add-in level.&amp;#160; But with SP1 we introduced a way for you to use these features at the add-in level.&amp;#160; In this section some of the wierd ways Idid things in section 4 will start to make more sense—I designed the code in Section 4 to be easily portable to an add-in.&lt;/p&gt;  &lt;p&gt;One thing that won’t port to the add-in level is cached data—that feature only works when code is at the document level.&lt;/p&gt;  &lt;p&gt;Choose File &amp;gt; Add &amp;gt; New Project.. and create a new Excel add-in project.&amp;#160; I’ll be using VB in this example.&lt;/p&gt;  &lt;p&gt;Add a web reference to the BugService as described in Article 4.&amp;#160; Be sure to name the reference BugService.&lt;/p&gt;  &lt;p&gt;Now, double click on your ThisAddIn file.&amp;#160; In the ThisAddIn class, add this as a member variable.&amp;#160; We won’t be adding any our dataset as a member variable because we can’t cache it at the add-in level, so there is no reason to make it a class member variable.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Public&lt;/span&gt; buttonDictionary &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Dictionary(Of Excel.Worksheet, Microsoft.Office.Tools.Excel.Controls.Button)&lt;/pre&gt;

&lt;p&gt;Next, we will put some calls to our AddListObjectAndButton function.&amp;#160; Add an event handler for the NewWorkbook, WorkbookBeforeClose, and WorkbookOpen events.&amp;#160; You will also put some code in ThisAddIn_Startup.&amp;#160; Also, handle the SheetBeforeRightClick event temporarily until we add a ribbon in the next article—this will make it so that if you right click on a worksheet, the bug data will be added to the workbook.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; ThisAddIn_Startup(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Startup
        &lt;span class="kwrd"&gt;If&lt;/span&gt; Application.ActiveWorkbook IsNot &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            PopulateSpreadsheet(&lt;span class="kwrd"&gt;False&lt;/span&gt;)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; ThisAddIn_Shutdown(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Shutdown

    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Application_NewWorkbook(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; Wb &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Workbook) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; Application.NewWorkbook
        PopulateSpreadsheet(&lt;span class="kwrd"&gt;False&lt;/span&gt;)
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Application_SheetBeforeRightClick(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; Sh &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; Target &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Interop.Excel.Range, &lt;span class="kwrd"&gt;ByRef&lt;/span&gt; Cancel &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Boolean&lt;/span&gt;) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; Application.SheetBeforeRightClick
        PopulateSpreadsheet(&lt;span class="kwrd"&gt;True&lt;/span&gt;)
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Application_WorkbookBeforeClose(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; Wb &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Workbook, &lt;span class="kwrd"&gt;ByRef&lt;/span&gt; Cancel &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Boolean&lt;/span&gt;) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; Application.WorkbookBeforeClose
        CleanUpDynamicButton()
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Application_WorkbookOpen(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; Wb &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Workbook) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; Application.WorkbookOpen
        PopulateSpreadsheet(&lt;span class="kwrd"&gt;False&lt;/span&gt;)
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The rest of the code is almost identical to the code we wrote in Article 4.&amp;#160; PopulateSpreadsheet has these changes from the document to the add-in level.&lt;/p&gt;

&lt;p&gt;1) Instead of the line “vstoSheet = GetVstoObject(s)” it changes to “vstoSheet = s.GetVstoObject()”.&amp;#160; At the add-in level, GetVstoObject is an extension method to the Microsoft.Office.Interop.Excel.Worksheet type.&lt;/p&gt;

&lt;p&gt;2) We don’t have the “If NeedsFill(“bugDataSet”)” if clause—cached data isn’t supported at the add-in level.&lt;/p&gt;

&lt;p&gt;3) Since bugDataset isn’t needed to be declared at the class member level due to no cached data, we declare it local in PopulateSpreadsheet.&amp;#160; Also you might need to add an “Imports System.Data&amp;quot; to the top of the file.&lt;/p&gt;

&lt;p&gt;4) We’ll also add a line at the top of PopulateSpreadsheet to detect if the name of the active workbook is “BugWorkbook”—the wokrbook we created in Section 4.&amp;#160; If it is, we’ll immediately return so as not to have our add-in conflict with our document level solution.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Other than these four changes, the remaining code should look very familiar:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; PopulateSpreadsheet(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; alwaysAdd &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Boolean&lt;/span&gt;)
        &lt;span class="kwrd"&gt;If&lt;/span&gt; Application.ActiveWorkbook.Name = &lt;span class="str"&gt;&amp;quot;BugWorkbook&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt; &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; foundList &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.ListObject = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Worksheet = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; bugDataset &lt;span class="kwrd"&gt;As&lt;/span&gt; DataSet


        foundList = FindList()

        &lt;span class="rem"&gt;' If not there create it if always add is true&lt;/span&gt;
        &lt;span class="kwrd"&gt;If&lt;/span&gt; foundList &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; alwaysAdd = &lt;span class="kwrd"&gt;True&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                s = Application.ActiveSheet
                foundList = s.ListObjects.AddEx(Excel.XlListObjectSourceType.xlSrcRange, s.Range(&lt;span class="str"&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;D2&amp;quot;&lt;/span&gt;))
                foundList.Name = &lt;span class="str"&gt;&amp;quot;BugListObject&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;Else&lt;/span&gt;
                &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
        &lt;span class="kwrd"&gt;Else&lt;/span&gt;
            s = &lt;span class="kwrd"&gt;TryCast&lt;/span&gt;(foundList.Parent, Excel.Worksheet)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

        &lt;span class="rem"&gt;' Dynamically create the list object&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; vstoSheet &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Excel.Worksheet
        vstoSheet = s.GetVstoObject()

        &lt;span class="rem"&gt;' Do we already have a listobject, if so exit.&lt;/span&gt;
        &lt;span class="kwrd"&gt;If&lt;/span&gt; vstoSheet.Controls.Contains(&lt;span class="str"&gt;&amp;quot;BugListObject&amp;quot;&lt;/span&gt;) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; list &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Excel.ListObject = vstoSheet.Controls.AddListObject(foundList)

        &lt;span class="rem"&gt;'If NeedsFill(&amp;quot;bugDataset&amp;quot;) Then&lt;/span&gt;
        Application.StatusBar = &lt;span class="str"&gt;&amp;quot;Updating data from bug web service...&amp;quot;&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; bugService &lt;span class="kwrd"&gt;As&lt;/span&gt; BugService.BugService = &lt;span class="kwrd"&gt;New&lt;/span&gt; BugService.BugService()
        bugDataset = bugService.BulkDataExport(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)
        &lt;span class="rem"&gt;'End If&lt;/span&gt;

        list.AutoSetDataBoundColumnHeaders = &lt;span class="kwrd"&gt;True&lt;/span&gt;
        list.DataSource = bugDataset.Tables(0)
        list.Range.Columns.AutoFit()
        list.Disconnect()

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; buttonRange &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Range = s.Range(&lt;span class="str"&gt;&amp;quot;E1&amp;quot;&lt;/span&gt;)
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotButton &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Excel.Controls.Button
        pivotButton = vstoSheet.Controls.AddButton(buttonRange, &lt;span class="str"&gt;&amp;quot;CreatePivotTable&amp;quot;&lt;/span&gt;)
        buttonDictionary.Add(s, pivotButton)
        &lt;span class="kwrd"&gt;AddHandler&lt;/span&gt; pivotButton.Click, &lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; pivotButton_Click
        pivotButton.Text = &lt;span class="str"&gt;&amp;quot;Pivot&amp;quot;&lt;/span&gt;

        Application.StatusBar = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
        s.Name = &lt;span class="str"&gt;&amp;quot;Bug Data&amp;quot;&lt;/span&gt;
        s.Activate()
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; FindList() &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.ListObject
        &lt;span class="rem"&gt;' Do we already have a created list object?&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; l &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.ListObject = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Worksheet = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; s &lt;span class="kwrd"&gt;In&lt;/span&gt; Application.ActiveWorkbook.Worksheets
            &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; l &lt;span class="kwrd"&gt;In&lt;/span&gt; s.ListObjects
                &lt;span class="kwrd"&gt;If&lt;/span&gt; l.Name = &lt;span class="str"&gt;&amp;quot;BugListObject&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                    &lt;span class="kwrd"&gt;Return&lt;/span&gt; l
                &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;Next&lt;/span&gt;
        &lt;span class="kwrd"&gt;Next&lt;/span&gt;
        &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; pivotButton_Click(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs)
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Worksheet = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotCache &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.PivotCache
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotTables &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.PivotTables
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotTable &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.PivotTable
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotField &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.PivotField

        s = Application.ActiveWorkbook.Worksheets.Add()
        pivotCache = s.Parent.PivotCaches.Create(Excel.XlPivotTableSourceType.xlDatabase, FindList().Range, Excel.XlPivotTableVersionList.xlPivotTableVersion12)
        pivotTables = s.PivotTables()
        pivotTable = pivotTables.Add(pivotCache, s.Range(&lt;span class="str"&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;))

        pivotTable.AddDataField(pivotTable.PivotFields(4))
        pivotTable.AddFields(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)

        pivotField = pivotTable.PivotFields(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;)
        pivotField.Orientation = Excel.XlPivotFieldOrientation.xlPageField
        pivotField.CurrentPage = &lt;span class="str"&gt;&amp;quot;Active&amp;quot;&lt;/span&gt;

        pivotField = pivotTable.PivotFields(&lt;span class="str"&gt;&amp;quot;Team&amp;quot;&lt;/span&gt;)
        pivotField.Orientation = Excel.XlPivotFieldOrientation.xlPageField
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; project &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = InputBox(&lt;span class="str"&gt;&amp;quot;Enter the team&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Team name&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Project - Office Client&amp;quot;&lt;/span&gt;)
        pivotField.CurrentPage = project

        s.Name = project
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; CleanUpDynamicButton()
        &lt;span class="kwrd"&gt;Try&lt;/span&gt;
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; l &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.ListObject = FindList()
            &lt;span class="kwrd"&gt;If&lt;/span&gt; (l &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; vstoButton &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Excel.Controls.Button
            vstoButton = buttonDictionary(l.Parent)
            &lt;span class="kwrd"&gt;RemoveHandler&lt;/span&gt; vstoButton.Click, &lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; pivotButton_Click
            buttonDictionary.Remove(l.Parent)
        &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; Exception

        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;

&lt;p&gt;Now, when you run this add-in and right click on the worksheet, the bugs dataset will be added to the workbook along with the “Pivot” button.&lt;/p&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Next up, we’ll enhance our solution with a custom ribbon.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616764" width="1" height="1"&gt;</description></item><item><title>6. VSTO Bug Tracker: Word Report Generation</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/14/6-vsto-bug-tracker-word-report-generation.aspx</link><pubDate>Thu, 14 May 2009 18:17:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616762</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9616762.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9616762</wfw:commentRss><description>&lt;p&gt;Another thing I want my bug tracking system to do is help me generate a weekly report with a summary table of key stats for all my teams. I want to do this in Word so I can add my own comments and a status summary of what went on during the week.&lt;/p&gt;  &lt;p&gt;We already prepared to build this Word report by writing the Web Service method “GetDailyValues”.&amp;#160; Create a new Word document project in C# and call it &lt;strong&gt;BugDocument. &lt;/strong&gt;If you start from a new document, follow the instructions below.&amp;#160; If you want to start from an existing document I’ve provided one here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ericca.members.winisp.net/bugdocument.docx"&gt;http://ericca.members.winisp.net/bugdocument.docx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Add a heading in the document called “Bug Report for “ then drag and drop a DatePickerContentControl in.&amp;#160; Next, add a table with 6 rows and 5 columns.&amp;#160; The headings for the columns are Active, Incoming, Fix Rate, and Resolve Rate.&amp;#160; The headings for the rows are Office Client, Office Server, Pro Tools, VBA, and VSTA.&amp;#160; Now drag and drop in new PlainTextContentControls left to right in this order into the table:&lt;/p&gt;  &lt;p&gt;1 2 3 4 &lt;/p&gt;  &lt;p&gt;5 6 7 8&lt;/p&gt;  &lt;p&gt;9 10 11 12&lt;/p&gt;  &lt;p&gt;13 14 15 16&lt;/p&gt;  &lt;p&gt;17 18 19 20&lt;/p&gt;  &lt;p&gt;This results in the document shown below:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/6.VSTOBugTrackerWordReportGeneration_12275/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/6.VSTOBugTrackerWordReportGeneration_12275/image_thumb.png" width="644" height="447" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Next, add a WebService reference to our BugService as described in Article 4.&amp;#160; Make sure the WebService is named BugService.&lt;/p&gt;  &lt;p&gt;We’re going to add an event handler for the DatePickerContentControl we added to the heading.&amp;#160; Click on the DatePickerControl, then use the Properties window to add an event handler for the Exiting event.&lt;/p&gt;  &lt;p&gt;In the code behind for ThisDocument, add a member variable to hold the dataset we will get back from the web service.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; DataSet ds;&lt;/pre&gt;

&lt;p&gt;The exiting event should look like this.&amp;#160; It gets the date that is picked, calls the web service, and calls the BindControls (if this is the first call) which establishes databindings between all the content controls you added and the dataset.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; datePickerContentControl1_Exiting(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, Microsoft.Office.Tools.Word.ContentControlExitingEventArgs e)
    {
        DateTime date = System.Convert.ToDateTime(datePickerContentControl1.Text);
        BugService.BugService bugService = &lt;span class="kwrd"&gt;new&lt;/span&gt; BugService.BugService();

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (ds != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            ds.Clear();
            DataSet d = bugService.GetDailyValues(date.Date.ToShortDateString());
            ds.Merge(d);
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt;
        {
            ds = bugService.GetDailyValues(date.Date.ToShortDateString());
            BindControls();
        }
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; BindControls()
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl1.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.1&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl2.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.2&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl3.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.3&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl4.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.4&amp;quot;&lt;/span&gt;);

        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl5.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.5&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl6.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.6&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl7.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.7&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl8.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.8&amp;quot;&lt;/span&gt;);

        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl9.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.9&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl10.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.10&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl11.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.11&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl12.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.12&amp;quot;&lt;/span&gt;);

        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl13.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.13&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl14.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.14&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl15.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.15&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl16.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.16&amp;quot;&lt;/span&gt;);

        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl17.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.17&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl18.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.18&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl19.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.19&amp;quot;&lt;/span&gt;);
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.plainTextContentControl20.DataBindings.Add(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, ds, &lt;span class="str"&gt;&amp;quot;Table.20&amp;quot;&lt;/span&gt;);
    }&lt;/pre&gt;

&lt;p&gt;When we run this solution, and pick a date from the date picker, the table is filled in from the data set returned by the web service showing current bug statistics for that date.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/6.VSTOBugTrackerWordReportGeneration_12275/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/6.VSTOBugTrackerWordReportGeneration_12275/image_thumb_1.png" width="644" height="466" /&gt;&lt;/a&gt; &lt;/pre&gt;
&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Although this is as far as we are going to take this part of the solution, you can imagine some additional things we could do.&amp;#160; First, because we use databinding, we could update our web service to return more than a single row, and use a currency manager to move through the rows in the dataset which would cause all the bound controls to update automatically.&amp;#160; This is a potential reason to use this technique (databinding) as opposed to the other technique you can use with content controls which is doing xpath bindings to an XML xpart embedded in the document.&lt;/p&gt;

&lt;p&gt;Also, we could use cached data in this solution in a similar way as was explained in Article 5 to populate the dataset in the document without starting Word.&lt;/p&gt;

&lt;p&gt;In the next section, I’m going to show you how we can take some of the functionality in my bug workbook to the add-in level so it will work against any spreadsheet without requiring any code in a spreadsheet.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616762" width="1" height="1"&gt;</description></item><item><title>5. VSTO Bug Tracker : Using Cached Data</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/14/5-vsto-bug-tracker-using-cached-data.aspx</link><pubDate>Thu, 14 May 2009 18:15:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616756</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9616756.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9616756</wfw:commentRss><description>&lt;p&gt;We are now going to convert our previous sample to use cached data.&amp;#160; In our current solution we have code that when the document loads, it calls a web service to get the bug data.&amp;#160; We are going to use the cached data feature to allow us to call the web service at a different time to fill in the dataset in the document without having to start Excel.&amp;#160; &lt;/p&gt;  &lt;p&gt;Why would we want to do this?&amp;#160; Well, several reasons.&amp;#160; First, we can improve the load time of our document by updating the data in the document in advance.&amp;#160; This also is handy to update the data in the document if the document is going to be opened outside the firewall where the web service can’t be accessed.&amp;#160; So a process running on a machine within the firewall can update the data in the document and then give the document to a machine running outside the firewall. As mentioned in the last article, it can also allow me to update the bug data in my workbooks in the middle of the night via a scheduled process so I can hit the web service when traffic is low.&lt;/p&gt;  &lt;p&gt;To convert our previous solution to used cached data, we simply add the CachedData attribute to the DataSet we declared in Sheet1.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;    &amp;lt;Cached()&amp;gt; &lt;span class="kwrd"&gt;Public&lt;/span&gt; bugDataset &lt;span class="kwrd"&gt;As&lt;/span&gt; DataSet&lt;/pre&gt;
&lt;style type="text/css"&gt;





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Next, we’ll modify our implementation of PopulateSpreadsheet.&amp;#160; The change here is to uncomment out the if statement &lt;font face="Consolas"&gt;&lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;NeedsFill&lt;/span&gt;(&lt;span class="str"&gt;&amp;quot;bugDataset&amp;quot;&lt;/span&gt;) &lt;/font&gt;&lt;span class="kwrd"&gt;&lt;font face="Consolas"&gt;Then&lt;/font&gt; which now brackets the code that calls the web service to update bugDataset.&amp;#160; What will happen now is that there are two ways of initializing the dataset in the document.&amp;#160; If the document gets run immediately after it is built, bugDataSet will not yet be cached in the document, so the bugDataSet will be updated by the web service call.&amp;#160; On subsequent runs after the document is saved, the web service won’t be called because the dataset will be cached in the document already.&amp;#160; The second way that the dataset can be initialized is through a console app that we will write presently.&lt;/span&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;If&lt;/span&gt; NeedsFill(&lt;span class="str"&gt;&amp;quot;bugDataset&amp;quot;&lt;/span&gt;) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            Application.StatusBar = &lt;span class="str"&gt;&amp;quot;Updating data from bug web service...&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; bugService &lt;span class="kwrd"&gt;As&lt;/span&gt; BugWorkbook.BugService.BugService = &lt;span class="kwrd"&gt;New&lt;/span&gt; BugWorkbook.BugService.BugService()
            bugDataset = bugService.BulkDataExport(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; If&lt;/pre&gt;
&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now, lets create a console application that can populate the data set into the document without starting Excel.&amp;#160; Use File &amp;gt; Add &amp;gt; New Project… to add a new console application to the solution (under Language, Windows, Console Application) and call it &lt;strong&gt;UpdateExcelWorkbook&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this console application, we will be using a class called ServerDocument which lets us access the cached data without starting up Excel.&amp;#160; Right click on the project node for the console application and choose “Add Reference…”.&amp;#160; From the Add Reference dialog, locate the .NET assembly called Microsoft.VisualStudio.Tools.Applications.ServerDocument.v9.0 and add it as a reference.&lt;/p&gt;

&lt;p&gt;Also add using Microsoft.VisualStudio.Tools.Applications; (Imports Microsoft.VisualStudio.Tools.Applications for VB) and using System.Data; (Imports System.Data) to the Program.cs (or Program.vb) file.&lt;/p&gt;

&lt;p&gt;We must also add a web reference to BugService—follow the steps given in article 4, and be sure to name it BugService.&lt;/p&gt;

&lt;p&gt;Now we’ll write the code for the console application.&amp;#160; The code creates a new instance of the ServerDocument class, iterates over the cached data until it finds a cached dataset called “bugDataSet”—the name of the public variable we added to Sheet1.&amp;#160; It then updates that dataset by calling the web service, then using a method called SerializeDataInstance which writes the dataset into the document.&amp;#160; Finally it calls doc.Save then exits.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.VisualStudio.Tools.Applications;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Data;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; UpdateExcelWorkbook
{
    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program
    {
        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (args.Length != 1)
            {
                Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Usage:&amp;quot;&lt;/span&gt;);
                Console.WriteLine(&lt;span class="str"&gt;&amp;quot;   UpdateExcelWorkbook.exe myfile.xlsx&amp;quot;&lt;/span&gt;);
                &lt;span class="kwrd"&gt;return&lt;/span&gt;;
            }

            &lt;span class="kwrd"&gt;string&lt;/span&gt; filename = args[0];
            ServerDocument doc = &lt;span class="kwrd"&gt;null&lt;/span&gt;;

            &lt;span class="kwrd"&gt;try&lt;/span&gt;
            {
                doc = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServerDocument(filename);

                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (CachedDataHostItem view &lt;span class="kwrd"&gt;in&lt;/span&gt;
                  doc.CachedData.HostItems)
                {
                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (CachedDataItem item &lt;span class="kwrd"&gt;in&lt;/span&gt; view.CachedData)
                    {
                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (item.Id == &lt;span class="str"&gt;&amp;quot;bugDataset&amp;quot;&lt;/span&gt;)
                        {
                            BugService.BugService bugService = &lt;span class="kwrd"&gt;new&lt;/span&gt; BugService.BugService();
                            DataSet ds = bugService.BulkDataExport(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);
                            item.SerializeDataInstance(ds);
                            doc.Save();
                            &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
                        }
                    }
                }
            }
            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)
            {
                Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Unexpected Exception:&amp;quot;&lt;/span&gt; + filename);
                Console.WriteLine(ex.ToString());
            }
            &lt;span class="kwrd"&gt;finally&lt;/span&gt;
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (doc != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    doc.Close();
                }
            }
        }
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now, to make this run, go back to the BugWorkbook project node, right click on it, and choose “Open Folder in Windows Explorer”.&amp;#160; We are trying to get the full path to the excel workbook that is being built by Visual Studio.&amp;#160; Double click on the bin directory, then the debug directory, then copy the whole path to the clipboard.&amp;#160; On my computer it is C:\Users\ecarter\Documents\Visual Studio 2008\Projects\BugService\BugWorkbook\bin\Debug\BugWorkbook.xlsx&lt;/p&gt;

&lt;p&gt;Right click on the UpdateExcelWorkbook project node, and choose properties.&amp;#160; Click the Debug tab.&amp;#160; In that tab, paste into the Command line arguments text box the full path to the workbook as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/5.VSTOBugTrackerUsingCachedData_12E60/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/5.VSTOBugTrackerUsingCachedData_12E60/image_thumb_1.png" width="644" height="405" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now, set the UpdateExcelWorkbook project to be the startup project by right clicking on the UpdateExcelWorkbook project node and choosing “Set as Startup Project”.&amp;#160; Clean and rebuild the solution.&amp;#160; This will rebuild the Excel workbook “ExcelWorkbook.xlsx” which will now have an empty data set in it called bugDataSet after the rebuild.&amp;#160; After the console application runs, bugDataSet will have been populated into the document.&lt;/p&gt;

&lt;p&gt;To verify that is so, navigate back to the directory where the excel workbook (now modified by the console application) lives (e.g. C:\Users\ecarter\Documents\Visual Studio 2008\Projects\BugService\BugWorkbook\bin\Debug\BugWorkbook.xlsx) and launch the workbook.&amp;#160; As it loads, note that the Status Bar of Excel does not display the text “Updating data from web service” because the dataset is already in the document.&amp;#160; When it starts up, it immediately binds the already populated dataset to the list object in the document.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616756" width="1" height="1"&gt;</description></item><item><title>4. VSTO Bug Tracker : Getting the data into Excel</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/14/4-vsto-bug-tracker-getting-the-data-into-excel.aspx</link><pubDate>Thu, 14 May 2009 18:14:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616753</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9616753.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9616753</wfw:commentRss><description>&lt;p&gt;The next step is to get more of the bug data into Excel so we can start to analyze it.&amp;#160; To do this, we will use VSTO’s data bind to ListObject support.&lt;/p&gt;  &lt;p&gt;I’m going to approach this in a different “more advanced” way that will make sense later in the demo. Long time VSTO developer will know that the simple way to bind data to a list object in VSTO is to create an Excel Workbook project, add a data source, then drag and drop the data source onto the Excel Workbook.&lt;/p&gt;  &lt;p&gt;The problem with that approach for this demo is that the code that is generated is deeply tied to the specific workbook being designed.&amp;#160; Since I’m going to show some advanced tips and tricks here including using document features in an add-in, I’m going to do this in a way that doesn’t tie it to a specific workbook project.&lt;/p&gt;  &lt;p&gt;We want to add the new Excel Workbook project to our existing solution that has our BugService project in it.&amp;#160; To do this, select File &amp;gt; Add &amp;gt; New Project.&amp;#160; Pick Visual Basic or Visual C# then Office then 2007 in the Project types outline.&amp;#160; Then pick Excel 2007 Workbook project and name it BugWorkbook:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_thumb.png" width="644" height="413" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Select Create a new document in the next dialog box that appears then click OK.&lt;/p&gt;  &lt;p&gt;Now we want to add a web reference to our BugService web service.&amp;#160; Right click on the BugWorkbook project node in Solution Explorer and choose Add Service Reference...&amp;#160; Then click on the Advanced button then the Add Web Reference.. button. Click the “Web Services in this Solution” link.&amp;#160; Then click “BugService”.&amp;#160; Change the web reference name from localhost to BugService and click the Add Reference button:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_thumb_2.png" width="644" height="449" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, right click on Sheet1.vb (or Sheet1.cs) and choose View Code.&lt;/p&gt;  &lt;p&gt;Add these two member variable to the ThisWorkbook class.&amp;#160; We need a variable to hold onto our dataset and one to hold onto a button we will be dynamically creating.&amp;#160; The reason we are using a dictionary object to store our button will be apparent later in the demo, for this section it will feel like overkill.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Public&lt;/span&gt; bugDataset &lt;span class="kwrd"&gt;As&lt;/span&gt; DataSet
    &lt;span class="kwrd"&gt;Public&lt;/span&gt; buttonDictionary &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Dictionary(Of Excel.Worksheet, Microsoft.Office.Tools.Excel.Controls.Button)&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Startup and Shutdown for the sheet look like this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Sheet1_Startup(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Startup
        PopulateSpreadsheet(&lt;span class="kwrd"&gt;True&lt;/span&gt;)
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Sheet1_Shutdown(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Shutdown
        CleanUpDynamicButton()
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/style&gt;

&lt;p&gt;The PopulateSpreadsheet method takes a boolean parameter that sets whether or not to force that the data be added.&amp;#160; The reason for this parameter will be apparent later as well.&amp;#160; This code finds the existing listobject with the bug data (if it has already been inserted into the spreadsheet in a previous run of the spreadsheet).&amp;#160; If it hasn’t yet been created, it creates the list.&amp;#160; It then contacts the web service (it does this every time the document opens), gets all the bug data, binds the resulting dataset to the&amp;#160; list object, then it disconnects from the list object once it has been populated.&amp;#160; Finally, it dynamically creates a button that if clicked will create a new sheet with a pivot table for the data in the list.&amp;#160; It puts the button in a dictionary along with the worksheet it was created on so it can be cleaned up later (in CleanUpDynamicButton).&amp;#160; The FindList method is a helper method that looks through the workbook to see if we’ve already added a listobject—it does this by looking for a listobject named “BugListObject”.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; PopulateSpreadsheet(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; alwaysAdd &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Boolean&lt;/span&gt;)
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; foundList &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.ListObject = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Worksheet = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;

        foundList = FindList()

        &lt;span class="rem"&gt;' If not there create it if always add is true&lt;/span&gt;
        &lt;span class="kwrd"&gt;If&lt;/span&gt; foundList &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; alwaysAdd = &lt;span class="kwrd"&gt;True&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                s = Application.ActiveSheet
                foundList = s.ListObjects.AddEx(Excel.XlListObjectSourceType.xlSrcRange, s.Range(&lt;span class="str"&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;D2&amp;quot;&lt;/span&gt;))
                foundList.Name = &lt;span class="str"&gt;&amp;quot;BugListObject&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;Else&lt;/span&gt;
                &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
        &lt;span class="kwrd"&gt;Else&lt;/span&gt;
            s = &lt;span class="kwrd"&gt;TryCast&lt;/span&gt;(foundList.Parent, Excel.Worksheet)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

        &lt;span class="rem"&gt;' Dynamically create the list object&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; vstoSheet &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Excel.Worksheet
        vstoSheet = GetVstoObject(s)

        &lt;span class="rem"&gt;' Do we already have a listobject, if so exit.&lt;/span&gt;
        &lt;span class="kwrd"&gt;If&lt;/span&gt; vstoSheet.Controls.Contains(&lt;span class="str"&gt;&amp;quot;BugListObject&amp;quot;&lt;/span&gt;) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; list &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Excel.ListObject = vstoSheet.Controls.AddListObject(foundList)

        &lt;span class="rem"&gt;'If NeedsFill(&amp;quot;bugDataset&amp;quot;) Then&lt;/span&gt;
        Application.StatusBar = &lt;span class="str"&gt;&amp;quot;Updating data from bug web service...&amp;quot;&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; bugService &lt;span class="kwrd"&gt;As&lt;/span&gt; BugService.BugService = &lt;span class="kwrd"&gt;New&lt;/span&gt; BugService.BugService()
        bugDataset = bugService.BulkDataExport(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)
        &lt;span class="rem"&gt;'End If&lt;/span&gt;

        list.AutoSetDataBoundColumnHeaders = &lt;span class="kwrd"&gt;True&lt;/span&gt;
        list.DataSource = bugDataset.Tables(0)
        list.Range.Columns.AutoFit()
        list.Disconnect()

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; buttonRange &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Range = s.Range(&lt;span class="str"&gt;&amp;quot;E1&amp;quot;&lt;/span&gt;)
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotButton &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Excel.Controls.Button
        pivotButton = vstoSheet.Controls.AddButton(buttonRange, &lt;span class="str"&gt;&amp;quot;CreatePivotTable&amp;quot;&lt;/span&gt;)
        buttonDictionary.Add(s, pivotButton)
        &lt;span class="kwrd"&gt;AddHandler&lt;/span&gt; pivotButton.Click, &lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; pivotButton_Click
        pivotButton.Text = &lt;span class="str"&gt;&amp;quot;Pivot&amp;quot;&lt;/span&gt;

        Application.StatusBar = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
        s.Name = &lt;span class="str"&gt;&amp;quot;Bug Data&amp;quot;&lt;/span&gt;
        s.Activate()
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; FindList() &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.ListObject
        &lt;span class="rem"&gt;' Do we already have a created list object?&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; l &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.ListObject = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Worksheet = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; s &lt;span class="kwrd"&gt;In&lt;/span&gt; Application.ActiveWorkbook.Worksheets
            &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; l &lt;span class="kwrd"&gt;In&lt;/span&gt; s.ListObjects
                &lt;span class="kwrd"&gt;If&lt;/span&gt; l.Name = &lt;span class="str"&gt;&amp;quot;BugListObject&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                    &lt;span class="kwrd"&gt;Return&lt;/span&gt; l
                &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;Next&lt;/span&gt;
        &lt;span class="kwrd"&gt;Next&lt;/span&gt;
        &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Function&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/style&gt;&lt;style type="text/css"&gt;


.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/style&gt;

&lt;p&gt;The callback function for the dynamically created button looks like this.&amp;#160; It creates a new pivot table on a new worksheet that is bound to the list object we created.&amp;#160; It creates two page fields to filter the data by team and column.&amp;#160; Finally, it prompts for the team name and sets the team filter to that team name (and sets the name of the newly created worksheet to the team name).&amp;#160; This is basic Excel code, but it took me a while to figure out the Pivot Table object model.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; pivotButton_Click(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs)
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.Worksheet = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotCache &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.PivotCache
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotTables &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.PivotTables
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotTable &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.PivotTable
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pivotField &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.PivotField

        s = Application.ActiveWorkbook.Worksheets.Add()
        pivotCache = s.Parent.PivotCaches.Create(Excel.XlPivotTableSourceType.xlDatabase, FindList().Range, Excel.XlPivotTableVersionList.xlPivotTableVersion12)
        pivotTables = s.PivotTables()
        pivotTable = pivotTables.Add(pivotCache, s.Range(&lt;span class="str"&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;))

        pivotTable.AddDataField(pivotTable.PivotFields(4))
        pivotTable.AddFields(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)

        pivotField = pivotTable.PivotFields(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;)
        pivotField.Orientation = Excel.XlPivotFieldOrientation.xlPageField
        pivotField.CurrentPage = &lt;span class="str"&gt;&amp;quot;Active&amp;quot;&lt;/span&gt;

        pivotField = pivotTable.PivotFields(&lt;span class="str"&gt;&amp;quot;Team&amp;quot;&lt;/span&gt;)
        pivotField.Orientation = Excel.XlPivotFieldOrientation.xlPageField
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; project &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = InputBox(&lt;span class="str"&gt;&amp;quot;Enter the team&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Team name&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Project - Office Client&amp;quot;&lt;/span&gt;)
        pivotField.CurrentPage = project

        s.Name = project
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/style&gt;

&lt;p&gt;Finally, the CleanUpDynamicButton method finds the dynamically created button in the dictionary and removes it and cleans up the event handler, etc.&amp;#160; This is in a try catch block just in case a button wasn’t created and therefore isn’t found in the dictionary which will be the case later in this demo.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; CleanUpDynamicButton()
        &lt;span class="kwrd"&gt;Try&lt;/span&gt;
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; l &lt;span class="kwrd"&gt;As&lt;/span&gt; Excel.ListObject = FindList()
            &lt;span class="kwrd"&gt;If&lt;/span&gt; (l &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; vstoButton &lt;span class="kwrd"&gt;As&lt;/span&gt; Microsoft.Office.Tools.Excel.Controls.Button
            vstoButton = buttonDictionary(&lt;span class="kwrd"&gt;l&lt;/span&gt;.Parent)
            &lt;span class="kwrd"&gt;RemoveHandler&lt;/span&gt; vstoButton.Click, &lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; pivotButton_Click
            buttonDictionary.Remove(l.Parent)
        &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; Exception

        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/style&gt;&lt;style type="text/css"&gt;


.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;Now set the BugWorkbook as the active project.&amp;#160; &lt;/strong&gt;So what’s the result when we run this document?&amp;#160; It adds a list object bound to the data set to the active worksheet along with a dynamically created button with the caption Pivot.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_10.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_thumb_4.png" width="644" height="458" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;When you click on the Pivot button, a new worksheet is created with a pivot table bound to the list object on the Bug Data worksheet.&amp;#160; You are prompted during this process to set the Team filter—here we se tit to “Project – Office Client”&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_14.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_thumb_6.png" width="644" height="458" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;From here, it is a simple matter to add a nice pivot chart as well.&amp;#160; Click on the Options tab in the Pivot Tables tab group, then press the PivotChart button.&amp;#160; I can quickly get a nice bug chart as shown below. Pretty, but I wish the bug count was going down!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_18.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerGettingthedataintoExcel_C008/image_thumb_8.png" width="644" height="461" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If I save my workbook then reopen it, the hook up code will run, detect that there is already a bug list object in the workbook, and it will fetch fresh data from the web service, rebind to the bug list object to update it, and re-add the dynamic “Pivot” button on the Bug Data page.&amp;#160; I can click the Pivot button as often as I want to add new worksheets with new pivots on the data—for example, looking at different teams or the same team and different columns.&lt;/p&gt;

&lt;p&gt;Sometimes the internal Microsoft server that returns the bug data can be slow or unavailable.&amp;#160; So rather than fetch fresh data from the web server every time you open the document, I’m going to show you how cached data can let you refresh the data in the document during off times—we’re going to write a console application that can update the data in the document without starting Excel.&amp;#160; It therefore could be run nightly on all my bug workbooks to refresh their data (since I don’t really need bug data more often than nightly anyway).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616753" width="1" height="1"&gt;</description></item><item><title>3. VSTO Bug Tracker : A UDF</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/14/3-vsto-bug-tracker-a-udf.aspx</link><pubDate>Thu, 14 May 2009 18:13:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616742</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9616742.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9616742</wfw:commentRss><description>&lt;p&gt;Now that we have our web service, lets get started by writing a managed UDF that uses the web method “GetColumnValue”.&amp;#160; In fact, the UDF will mirror this web method and make it so we can use it in Excel formulas.&lt;/p&gt;  &lt;p&gt;First, add a new C# or VB class library project to your solution using File &amp;gt; Add &amp;gt; New Project. Name the project BugAddIn. Next, lets add a web reference to the BugService.&lt;/p&gt;  &lt;p&gt;Now we want to add a web reference to our BugService web service.&amp;#160; Right click on the BugWorkbook project node in Solution Explorer and choose Add Service Reference...&amp;#160; Then click on the Advanced button then the Add Web Reference.. button. Click the “Web Services in this Solution” link.&amp;#160; Then click “BugService”.&amp;#160; Change the web reference name from localhost to BugService and click the Add Reference button:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerAUDF_F391/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerAUDF_F391/image_thumb_2.png" width="644" height="449" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In your Class1.cs or Class1.vb file created for you in the new project, replace Class1 with the code shown below.&amp;#160; Replace the GUID string in the listing with your own GUID by using Generate GUID in the Tools menu. In the Generate GUID dialog box, pick option 4, Registry Format. Then click the Copy button to put the new GUID string on the clipboard. Then click Exit to exit the Generate GUID tool. Finally, select the GUID string and replace it with your new GUID string. You’ll also have to remove the { } brackets that get copied as part of the GUID.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Imports&lt;/span&gt; System
&lt;span class="kwrd"&gt;Imports&lt;/span&gt; System.Collections.Generic
&lt;span class="kwrd"&gt;Imports&lt;/span&gt; System.Linq
&lt;span class="kwrd"&gt;Imports&lt;/span&gt; System.Text
&lt;span class="kwrd"&gt;Imports&lt;/span&gt; System.Runtime.InteropServices
&lt;span class="kwrd"&gt;Imports&lt;/span&gt; Microsoft.Win32

&lt;span class="kwrd"&gt;Namespace&lt;/span&gt; BugAddIn
    &lt;span class="rem"&gt;' Replace the Guid below with your own guid that&lt;/span&gt;
    &lt;span class="rem"&gt;' you generate using Create GUID from the Tools menu&lt;/span&gt;
    &amp;lt;Guid(&lt;span class="str"&gt;&amp;quot;6C0C5BEC-9F01-4743-97D3-CB4342644CDB&amp;quot;&lt;/span&gt;)&amp;gt; _
    &amp;lt;ClassInterface(ClassInterfaceType.AutoDual)&amp;gt; _
    &amp;lt;ComVisible(&lt;span class="kwrd"&gt;True&lt;/span&gt;)&amp;gt; _
    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt; BugFunctions

        &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt;()
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

        &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetColumnValue(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; team &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; column &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateGathered &lt;span class="kwrd"&gt;As&lt;/span&gt; DateTime) &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Double&lt;/span&gt;
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; bugService &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; BugService.BugService()
            &lt;span class="kwrd"&gt;Return&lt;/span&gt; Convert.ToDouble(bugService.GetColumnValue(team, column, dateGathered.[&lt;span class="kwrd"&gt;Date&lt;/span&gt;].ToShortDateString()))
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt;

        &amp;lt;ComRegisterFunctionAttribute()&amp;gt; _
        &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Shared&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; RegisterFunction(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; type &lt;span class="kwrd"&gt;As&lt;/span&gt; Type)
            Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, &lt;span class="str"&gt;&amp;quot;Programmable&amp;quot;&lt;/span&gt;))
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; key &lt;span class="kwrd"&gt;As&lt;/span&gt; RegistryKey = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, &lt;span class="str"&gt;&amp;quot;InprocServer32&amp;quot;&lt;/span&gt;), &lt;span class="kwrd"&gt;True&lt;/span&gt;)
            key.SetValue(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, System.Environment.SystemDirectory + &lt;span class="str"&gt;&amp;quot;\mscoree.dll&amp;quot;&lt;/span&gt;, RegistryValueKind.[&lt;span class="kwrd"&gt;String&lt;/span&gt;])
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

        &amp;lt;ComUnregisterFunctionAttribute()&amp;gt; _
        &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Shared&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; UnregisterFunction(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; type &lt;span class="kwrd"&gt;As&lt;/span&gt; Type)
            Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, &lt;span class="str"&gt;&amp;quot;Programmable&amp;quot;&lt;/span&gt;), &lt;span class="kwrd"&gt;False&lt;/span&gt;)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

        &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Shared&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetSubKeyName(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; type &lt;span class="kwrd"&gt;As&lt;/span&gt; Type, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; subKeyName &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;
            &lt;span class="kwrd"&gt;Dim&lt;/span&gt; s &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.Text.StringBuilder()

            s.Append(&lt;span class="str"&gt;&amp;quot;CLSID\{&amp;quot;&lt;/span&gt;)
            s.Append(type.GUID.ToString().ToUpper())
            s.Append(&lt;span class="str"&gt;&amp;quot;}\&amp;quot;&lt;/span&gt;)
            s.Append(subKeyName)

            &lt;span class="kwrd"&gt;Return&lt;/span&gt; s.ToString()
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt;
&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Namespace&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.InteropServices;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Win32;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BugAddIn
{
    &lt;span class="rem"&gt;// Replace the Guid below with your own guid that&lt;/span&gt;
    &lt;span class="rem"&gt;// you generate using Create GUID from the Tools menu&lt;/span&gt;
    [Guid(&lt;span class="str"&gt;&amp;quot;5268ABE2-9B09-439d-BE97-2EA60E103EF6&amp;quot;&lt;/span&gt;)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(&lt;span class="kwrd"&gt;true&lt;/span&gt;)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BugFunctions
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; BugFunctions()
        {

        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; GetColumnValue(&lt;span class="kwrd"&gt;string&lt;/span&gt; team, &lt;span class="kwrd"&gt;string&lt;/span&gt; column, DateTime dateGathered)
        {
            BugAddIn.BugService.BugService bugService = &lt;span class="kwrd"&gt;new&lt;/span&gt; BugService.BugService();
            &lt;span class="kwrd"&gt;return&lt;/span&gt; Convert.ToDouble(bugService.GetColumnValue(team, column, dateGathered.Date.ToShortDateString()));
        }

        [ComRegisterFunctionAttribute]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RegisterFunction(Type type)
        {
            Registry.ClassesRoot.CreateSubKey(
            GetSubKeyName(type, &lt;span class="str"&gt;&amp;quot;Programmable&amp;quot;&lt;/span&gt;));
            RegistryKey key = Registry.ClassesRoot.OpenSubKey(
            GetSubKeyName(type, &lt;span class="str"&gt;&amp;quot;InprocServer32&amp;quot;&lt;/span&gt;), &lt;span class="kwrd"&gt;true&lt;/span&gt;);
            key.SetValue(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,
            System.Environment.SystemDirectory + &lt;span class="str"&gt;@&amp;quot;\mscoree.dll&amp;quot;&lt;/span&gt;,
            RegistryValueKind.String);
        }

        [ComUnregisterFunctionAttribute]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; UnregisterFunction(Type type)
        {
            Registry.ClassesRoot.DeleteSubKey(
            GetSubKeyName(type, &lt;span class="str"&gt;&amp;quot;Programmable&amp;quot;&lt;/span&gt;), &lt;span class="kwrd"&gt;false&lt;/span&gt;);
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetSubKeyName(Type type, &lt;span class="kwrd"&gt;string&lt;/span&gt; subKeyName)
        {
            System.Text.StringBuilder s =
            &lt;span class="kwrd"&gt;new&lt;/span&gt; System.Text.StringBuilder();

            s.Append(&lt;span class="str"&gt;@&amp;quot;CLSID\{&amp;quot;&lt;/span&gt;);
            s.Append(type.GUID.ToString().ToUpper());
            s.Append(@&amp;quot;}\&amp;quot;);
            s.Append(subKeyName);

            &lt;span class="kwrd"&gt;return&lt;/span&gt; s.ToString();
        }
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;With this code written (remember to replace the GUID in the listing with your own GUID that you generate using Generate GUID in the Tools menu), you need to configure the project to be registered for COM interop so Excel can see it. Go to the properties for the project by double-clicking the Properties node under the BugAddIn project in Solution Explorer. In the properties designer that appears, click the Build tab and check the check box that says Register for COM interop as shown below This will cause Visual Studio to register the assembly for COM interop when the project is built.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerAUDF_F391/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/3.VSTOBugTrackerAUDF_F391/image_thumb_1.png" width="511" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you are running under Vista or later, you need to run Visual Studio as administrator since registering for COM interop requires administrative privileges. If you are not already running Visual Studio as administrator, save your project and exit Visual Studio. Then find the Visual Studio 2008 icon in the start menu, right click on it and choose Run as Administrator as shown in Figure 3-8. Now that Visual Studio is running as administrator, reopen your project and choose Rebuild Solution from the Build menu. Visual Studio will do the necessary registration to make your class visible to Excel.&lt;/p&gt;

&lt;p&gt;Now that the add-in is built and registered, to load the managed automation add-in into Excel, follow these steps.&lt;/p&gt;

&lt;p&gt;1. Launch Excel and click the Microsoft Office button in the top left corner of the window.&lt;/p&gt;

&lt;p&gt;2. Choose Excel Options.&lt;/p&gt;

&lt;p&gt;3. Click the Add-Ins tab in the Excel Options dialog.&lt;/p&gt;

&lt;p&gt;4. Choose Excel Add-Ins from the combo box labeled Manage. Then click the Go button.&lt;/p&gt;

&lt;p&gt;5. Click the Automation button in the Add-Ins dialog.&lt;/p&gt;

&lt;p&gt;6. Look through the list of Automation Servers and find the class you created—it will be listed as BugAddIn.MyFunctions.&lt;/p&gt;

&lt;p&gt;By clicking OK in this dialog, you have added the BugAddIn.MyFunctions class to the list of installed automation add-ins.&lt;/p&gt;

&lt;p&gt;Now, try to use the function GetColumnValue in an Excel formula. Click an empty cell in the workbook, and then click the Insert Function button (the button with the “fx” label) in the formula bar. From the dialog of available formulas, drop down the “Or select a category” drop-down box and choose BugAddIn.MyFunctions. Then click the GetColumnValue function.&amp;#160; When you click the OK button, Excel pops up a dialog to help select function arguments from cells in the spreadsheet.&lt;/p&gt;

&lt;p&gt;After you have selected function arguments, click OK.&lt;/p&gt;

&lt;p&gt;Note that Excel and .NET have some special issues when running on a non-english locale that may cause you to see an automation add-in to fail. VSTO add-ins have some additional features that protect you from these issues.&lt;/p&gt;

&lt;p&gt;Also note that to uninstall your add-in, run regasm BugAddIn.dll /unregister at an eleveated command prompt.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616742" width="1" height="1"&gt;</description></item><item><title>2. VSTO Bug Tracker : The Web Service</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/14/2-vsto-bug-tracker-the-web-service.aspx</link><pubDate>Thu, 14 May 2009 18:11:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616737</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9616737.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9616737</wfw:commentRss><description>&lt;p&gt;Within Microsoft, there is a web service already implemented that I can use in my solution to call the bug tracking system and get back the data described in the previous article.&amp;#160; For my demo, I’m going to implement a demo web service that will stand in for that internal Microsoft web service.&amp;#160; It will return the same basic data structures as the internal web service does, so when I run my own copy of VSTO bug tracker, I can swap out this demo web service for the real one.&lt;/p&gt;  &lt;p&gt;The demo web service will have three web methods.&amp;#160; The first method is called BulkDataExport.&amp;#160; This method takes a start date and an end date and returns back a dataset with all the bug data for that time period.&amp;#160; This is a simplified version of the Microsoft provided web service that I use internally.&amp;#160; That web method has more parameters to specify milestone, release, team, etc.&amp;#160;&amp;#160; But I will omit those for simplicity since my data is specific to my team.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&amp;lt;WebMethod()&amp;gt; _
&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; BulkDataExport(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateFrom &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, _&lt;br /&gt;  &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateTo &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; System.Data.DataSet&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;[WebMethod()]
&lt;span class="kwrd"&gt;public&lt;/span&gt; System.Data.DataSet BulkDataExport(&lt;span class="kwrd"&gt;string&lt;/span&gt; dateFrom, &lt;span class="kwrd"&gt;string&lt;/span&gt; dateTo)&lt;/pre&gt;
&lt;style type="text/css"&gt;







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The second method is called to get one particular bug stat value for one particular date.&amp;#160; This will be used by the UDF I will write later.&amp;#160; This takes a particular team (milestone and release I omit) as well as the name of the column I want to retrieve (e.g. “Active”) and the date for which I want to get the value.&amp;#160; So I can effectively ask the question through this web method, “How many active bugs did the VBA team have on May 1st?”&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&amp;lt;WebMethod()&amp;gt; _
&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetColumnValue(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; team &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, _&lt;br /&gt;  &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; column &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateGathered &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;
&lt;style type="text/css"&gt;










.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;pre class="csharpcode"&gt;[WebMethod()]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetColumnValue(&lt;span class="kwrd"&gt;string&lt;/span&gt; team, &lt;span class="kwrd"&gt;string&lt;/span&gt; column, &lt;span class="kwrd"&gt;string&lt;/span&gt; dateGathered)&lt;/pre&gt;
&lt;style type="text/css"&gt;







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The third method will be used by my Word solution.&amp;#160; It takes the date and returns a dataset with twenty columns representing the 4 key metrics for my 5 teams:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&amp;lt;WebMethod()&amp;gt; _
&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetDailyValues(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateGathered &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; DataSet&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;[WebMethod()]
&lt;span class="kwrd"&gt;public&lt;/span&gt; DataSet GetDailyValues(&lt;span class="kwrd"&gt;string&lt;/span&gt; dateGathered)&lt;/pre&gt;
&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Let’s walk through creating this web service.&lt;/p&gt;

&lt;p&gt;Fire up Visual Studio 2008, select File &amp;gt; New &amp;gt; Project…, then expand out the Visual Basic or C# node, click the Web category, then pick ASP.NET Web Service Application.&amp;#160; Name the project &lt;strong&gt;BugService&lt;/strong&gt;, then click OK.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/2.TheDemoStoryVSTOBugTracker_F48B/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/2.TheDemoStoryVSTOBugTracker_F48B/image_thumb.png" width="644" height="459" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now, let’s implement these two methods.&amp;#160; First, let’s get a web service created.&amp;#160; Delete the auto-created Service1.asmx file from your project.&amp;#160; Right click on the project node, choose Add &amp;gt; New Item… and from the Add New Item dialog, click on the Web category, then click Web Service.&amp;#160; Name the Web Service &lt;strong&gt;BugService.asmx&lt;/strong&gt;.&amp;#160; Then click Add. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/2.TheDemoStoryVSTOBugTracker_F48B/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/2.TheDemoStoryVSTOBugTracker_F48B/image_thumb_1.png" width="644" height="389" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Delete the “HelloWorld” web method that is created for you in the BugService.asmx file.&amp;#160; Add a “&lt;strong&gt;using System.Data;&lt;/strong&gt;” statement to the top of the file.&amp;#160; Then add a DataSet property to the BugService class that will contain our data.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Shared&lt;/span&gt; ds &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; DataSet
    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Shared&lt;/span&gt; &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; BugData() &lt;span class="kwrd"&gt;As&lt;/span&gt; DataSet
        &lt;span class="kwrd"&gt;Get&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; ds.Tables.Count = 0 &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                ds.ReadXml(&lt;span class="str"&gt;&amp;quot;C:\Users\ecarter\Documents\bugdata.xml&amp;quot;&lt;/span&gt;)
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;Return&lt;/span&gt; ds
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Property&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; DataSet ds = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataSet();
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataSet BugData
    {
        get
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (ds.Tables.Count == 0)
            {
                ds.ReadXml(&lt;span class="str"&gt;&amp;quot;C:\\Users\\ecarter\\Documents\\bugdata.xml&amp;quot;&lt;/span&gt;);
            }
            &lt;span class="kwrd"&gt;return&lt;/span&gt; ds;
        }
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;font size="2" face="Consolas"&gt;&lt;/font&gt;&lt;style type="text/css"&gt;









.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;As you can see, this code kind of cheats—it loads a pre-serialized data set from disk.&amp;#160; The data in this file has data that I originally obtained from Microsoft’s internal bug system.&amp;#160; For my demo, I won’t live connect to this system, so instead I’ve saved off some XML.&amp;#160; I also keep this around in a class level property so that I only have to load it once and subsequent web service calls that access this data won’t have to load all the bug data again and will therefore be quicker.&lt;/p&gt;

&lt;p&gt;I’ve provided a copy of this data so you can play along here: &lt;a title="http://ericca.members.winisp.net/bugdata.xml" href="http://ericca.members.winisp.net/bugdata.xml"&gt;http://ericca.members.winisp.net/bugdata.xml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, my implementation of the BulkDataExport web method.&amp;#160; This method is pretty simple.&amp;#160; It just grabs the data set with all the bug data and then does a restrictive query to only return the bug data between the dateFrom and dateTo.&amp;#160; There’s some wierdness going on here with converting dates to strings and so forth—this is because I need to match the original Microsoft internal web service which has everything typed as string.&amp;#160; For C#, be sure you add a &lt;font face="consolas"&gt;using System.Data&lt;/font&gt; to the top of the class file.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &amp;lt;WebMethod()&amp;gt; _
    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; BulkDataExport(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateFrom &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateTo &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; System.Data.DataSet
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; rows &lt;span class="kwrd"&gt;As&lt;/span&gt; DataTable = BugData.Tables(&lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;)

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; startDate &lt;span class="kwrd"&gt;As&lt;/span&gt; DateTime
        &lt;span class="kwrd"&gt;If&lt;/span&gt; (&lt;span class="kwrd"&gt;String&lt;/span&gt;.IsNullOrEmpty(dateFrom)) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            startDate = &lt;span class="kwrd"&gt;Date&lt;/span&gt;.MinValue
        &lt;span class="kwrd"&gt;Else&lt;/span&gt;
            startDate = System.Convert.ToDateTime(dateFrom)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; endDate &lt;span class="kwrd"&gt;As&lt;/span&gt; DateTime
        &lt;span class="kwrd"&gt;If&lt;/span&gt; (&lt;span class="kwrd"&gt;String&lt;/span&gt;.IsNullOrEmpty(dateTo)) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            endDate = &lt;span class="kwrd"&gt;Date&lt;/span&gt;.MaxValue
        &lt;span class="kwrd"&gt;Else&lt;/span&gt;
            endDate = System.Convert.ToDateTime(dateTo)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; query = From row &lt;span class="kwrd"&gt;In&lt;/span&gt; rows.AsEnumerable() _
                    Where System.Convert.ToDateTime(row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)).Date &amp;gt;= startDate.Date &lt;span class="kwrd"&gt;And&lt;/span&gt; _
                    System.Convert.ToDateTime(row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)).Date &amp;lt;= endDate.Date _
                    &lt;span class="kwrd"&gt;Select&lt;/span&gt; row

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; newrows &lt;span class="kwrd"&gt;As&lt;/span&gt; DataTable = query.CopyToDataTable()
        newrows.TableName = &lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; returnDataSet &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; DataSet()
        returnDataSet.Tables.Add(newrows)
        &lt;span class="kwrd"&gt;Return&lt;/span&gt; returnDataSet
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Function&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;    [WebMethod()]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Data.DataSet BulkDataExport(&lt;span class="kwrd"&gt;string&lt;/span&gt; dateFrom, &lt;span class="kwrd"&gt;string&lt;/span&gt; dateTo)
    {
        DataTable rows = BugData.Tables[&lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;];

        DateTime startDate;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; ((&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(dateFrom)))
        {
            startDate = System.DateTime.MinValue;
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt;
        {
            startDate = System.Convert.ToDateTime(dateFrom);
        }

        DateTime endDate;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; ((&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(dateTo)))
        {
            endDate = System.DateTime.MaxValue;
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt;
        {
            endDate = System.Convert.ToDateTime(dateTo);
        }

        var query = from row &lt;span class="kwrd"&gt;in&lt;/span&gt; rows.AsEnumerable()
                    &lt;span class="kwrd"&gt;where&lt;/span&gt; System.Convert.ToDateTime(row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)).Date &amp;gt;= startDate.Date &amp;amp;&amp;amp;
                    System.Convert.ToDateTime(row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)).Date &amp;lt;= endDate.Date
                    select row;

        DataTable newrows = query.CopyToDataTable();
        newrows.TableName = &lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;;

        DataSet returnDataSet = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataSet();
        returnDataSet.Tables.Add(newrows);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; returnDataSet;
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Next, the implementation of GetColumnValue.&amp;#160; This also does a basic query over the data to get back the row in the table that corresponds to the team, column, and date specified.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &amp;lt;WebMethod()&amp;gt; _
    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetColumnValue(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; team &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; column &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateGathered &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; rows &lt;span class="kwrd"&gt;As&lt;/span&gt; DataTable = BugData.Tables(&lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;)

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; startDate &lt;span class="kwrd"&gt;As&lt;/span&gt; DateTime = System.Convert.ToDateTime(dateGathered)

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; query = From row &lt;span class="kwrd"&gt;In&lt;/span&gt; rows.AsEnumerable() _
                    Where row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Team&amp;quot;&lt;/span&gt;) = team &lt;span class="kwrd"&gt;And&lt;/span&gt; _
                    row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) = column &lt;span class="kwrd"&gt;And&lt;/span&gt; _
                    System.DateTime.Compare(System.Convert.ToDateTime(row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)).&lt;span class="kwrd"&gt;Date&lt;/span&gt;, startDate.&lt;span class="kwrd"&gt;Date&lt;/span&gt;) = 0 _
                    &lt;span class="kwrd"&gt;Select&lt;/span&gt; row

        &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; row &lt;span class="kwrd"&gt;In&lt;/span&gt; query
            &lt;span class="kwrd"&gt;Return&lt;/span&gt; row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Value&amp;quot;&lt;/span&gt;)
        &lt;span class="kwrd"&gt;Next&lt;/span&gt;

        &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ERROR&amp;quot;&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Function&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;    [WebMethod()]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetColumnValue(&lt;span class="kwrd"&gt;string&lt;/span&gt; team, &lt;span class="kwrd"&gt;string&lt;/span&gt; column, &lt;span class="kwrd"&gt;string&lt;/span&gt; dateGathered)
    {
        DataTable rows = BugData.Tables[&lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;];

        DateTime startDate = System.Convert.ToDateTime(dateGathered);

        var query = from row &lt;span class="kwrd"&gt;in&lt;/span&gt; rows.AsEnumerable()
                    &lt;span class="kwrd"&gt;where&lt;/span&gt; row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Team&amp;quot;&lt;/span&gt;) == team &amp;amp;&amp;amp;
                    row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) == column &amp;amp;&amp;amp;
                    System.DateTime.Compare(System.Convert.ToDateTime(row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)).Date, startDate.Date) == 0
                    select row;

        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var row &lt;span class="kwrd"&gt;in&lt;/span&gt; query)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Value&amp;quot;&lt;/span&gt;);
        }

        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;ERROR&amp;quot;&lt;/span&gt;;
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;









.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Finally, the implementation of GetDailyValues:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &amp;lt;WebMethod()&amp;gt; _
    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetDailyValues(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; dateGathered &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; DataSet
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; rows &lt;span class="kwrd"&gt;As&lt;/span&gt; DataTable = BugData.Tables(&lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;)

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; startDate &lt;span class="kwrd"&gt;As&lt;/span&gt; DateTime = System.Convert.ToDateTime(dateGathered)

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; query = From row &lt;span class="kwrd"&gt;In&lt;/span&gt; rows.AsEnumerable() _
                    Where System.DateTime.Compare(System.Convert.ToDateTime(row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)).&lt;span class="kwrd"&gt;Date&lt;/span&gt;, startDate.&lt;span class="kwrd"&gt;Date&lt;/span&gt;) = 0 &lt;span class="kwrd"&gt;And&lt;/span&gt; _
                    (row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) = &lt;span class="str"&gt;&amp;quot;Active&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Or&lt;/span&gt; _
                     row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) = &lt;span class="str"&gt;&amp;quot;Incoming Rate (7 Day)&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Or&lt;/span&gt; _
                     row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) = &lt;span class="str"&gt;&amp;quot;Resolved Fixed Rate (7 Day)&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Or&lt;/span&gt; _
                     row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) = &lt;span class="str"&gt;&amp;quot;Resolved Rate (7 Day)&amp;quot;&lt;/span&gt;) _
                     Order By row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Team&amp;quot;&lt;/span&gt;), row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) _
                    &lt;span class="kwrd"&gt;Select&lt;/span&gt; row

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; newrows &lt;span class="kwrd"&gt;As&lt;/span&gt; DataTable = &lt;span class="kwrd"&gt;New&lt;/span&gt; DataTable(&lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;)
        newrows.TableName = &lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; i &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;
        &lt;span class="kwrd"&gt;For&lt;/span&gt; i = 1 &lt;span class="kwrd"&gt;To&lt;/span&gt; 20
            newrows.Columns.Add(i.ToString())
        &lt;span class="kwrd"&gt;Next&lt;/span&gt;

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; objectArray(19) &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;
        i = 0
        &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; row &lt;span class="kwrd"&gt;In&lt;/span&gt; query
            objectArray(i) = row.Field(Of &lt;span class="kwrd"&gt;String&lt;/span&gt;)(&lt;span class="str"&gt;&amp;quot;Value&amp;quot;&lt;/span&gt;)
            i = i + 1
        &lt;span class="kwrd"&gt;Next&lt;/span&gt;

        newrows.Rows.Add(objectArray)

        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; returnDataSet &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; DataSet()
        returnDataSet.Tables.Add(newrows)
        &lt;span class="kwrd"&gt;Return&lt;/span&gt; returnDataSet
    &lt;span class="kwrd"&gt;End&lt;/span&gt; Function&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;    [WebMethod()]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; DataSet GetDailyValues(&lt;span class="kwrd"&gt;string&lt;/span&gt; dateGathered)
    {
        DataTable rows = BugData.Tables[&lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;];
        DateTime startDate = System.Convert.ToDateTime(dateGathered);

        var query = from row &lt;span class="kwrd"&gt;in&lt;/span&gt; rows.AsEnumerable()
                    &lt;span class="kwrd"&gt;where&lt;/span&gt; System.DateTime.Compare(System.Convert.ToDateTime(row.Field&amp;lt;String&amp;gt;(&lt;span class="str"&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;)).Date, startDate.Date) == 0 &amp;amp;&amp;amp;
                    (row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) == &lt;span class="str"&gt;&amp;quot;Active&amp;quot;&lt;/span&gt; ||
                     row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) == &lt;span class="str"&gt;&amp;quot;Incoming Rate (7 Day)&amp;quot;&lt;/span&gt; ||
                     row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) == &lt;span class="str"&gt;&amp;quot;Resolved Fixed Rate (7 Day)&amp;quot;&lt;/span&gt; ||
                     row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;) == &lt;span class="str"&gt;&amp;quot;Resolved Rate (7 Day)&amp;quot;&lt;/span&gt;)
                    orderby row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Team&amp;quot;&lt;/span&gt;), row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Column&amp;quot;&lt;/span&gt;)
                    select row;

        DataTable newrows = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataTable(&lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;);
        newrows.TableName = &lt;span class="str"&gt;&amp;quot;Table&amp;quot;&lt;/span&gt;;
        &lt;span class="kwrd"&gt;int&lt;/span&gt; i;
        &lt;span class="kwrd"&gt;for&lt;/span&gt; (i = 1; i &amp;lt;= 20; i++)
        {
            newrows.Columns.Add(i.ToString());
        }

        &lt;span class="kwrd"&gt;object&lt;/span&gt;[] objectArray = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[20];
        i = 0;
        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var row &lt;span class="kwrd"&gt;in&lt;/span&gt; query)
        {
            objectArray[i] = row.Field&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;Value&amp;quot;&lt;/span&gt;);
            i = i + 1;
        }

        newrows.Rows.Add(objectArray);

        DataSet returnDataSet = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataSet();
        returnDataSet.Tables.Add(newrows);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; returnDataSet;
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;You should be able to run the web service project and test it.&lt;/p&gt;

&lt;p&gt;Now that we have a working web service, lets create a UDF that uses it.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616737" width="1" height="1"&gt;</description></item><item><title>1. VSTO Bug Tracker : The Data</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/14/1-vsto-bug-tracker-the-data.aspx</link><pubDate>Thu, 14 May 2009 18:08:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616724</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9616724.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9616724</wfw:commentRss><description>&lt;P&gt;For my TechEd&amp;nbsp;demo today, I will be showing a solution that helps me to do part of my job as a development manager: tracking the bug counts in the product.&amp;nbsp; At Microsoft, we have an internal system that tracks a ton of relevant bug stats in TFS and takes a snapshot of various key metrics in that system every day—for example, active bugs for a team on a given day day.&amp;nbsp; I will be writing a solution that brings that bug data into Excel and Word using VSTO so it can be further analyzed.&amp;nbsp; Ways I can analyze it in Excel will include using Pivot Tables and Pivot Charts against the data, grabbing this data to use in custom formulas in Excel, etc.&amp;nbsp; In Word, I can create nicely formatted bug mail that I can then send to the team.&lt;/P&gt;
&lt;P&gt;First, a bit more about the bug data.&amp;nbsp;&amp;nbsp; The bug data is tracked in a table that has these columns: Team, Column, Date, and Value.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Team&lt;/STRONG&gt; – The team we are tracking bugs for.&amp;nbsp; On my team I have 5 teams I track bugs for:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Project - VSTA &lt;/LI&gt;
&lt;LI&gt;Project - Office Server &lt;/LI&gt;
&lt;LI&gt;Project - Office Client &lt;/LI&gt;
&lt;LI&gt;Project - Pro Tools &lt;/LI&gt;
&lt;LI&gt;Project - VBA &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Column&lt;/STRONG&gt; – The name of the bug statistic being tracked.&amp;nbsp; Some examples:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Active – number of active bugs on a given day &lt;/LI&gt;
&lt;LI&gt;Resolved Fixed Rate (7 Day) – the 7 day average of bugs that were resolved fixed &lt;/LI&gt;
&lt;LI&gt;Resolved Rate (7 Day) – the 7 day average of total bugs were resolved (some bugs may be resolved without having an actual fix occur, for example because they are duplicate bugs) &lt;/LI&gt;
&lt;LI&gt;Incoming Rate (7 Day) – the 7 day average of bugs that were opened &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Date– &lt;/STRONG&gt;The date the bug statistic was gathered.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Value&lt;/STRONG&gt; – The value for the bug statistic on a given day, for example Active bugs for a particular team is 50 on a particular date.&lt;/P&gt;
&lt;P&gt;So, for my particular team, if I want to know the Active bug count for VSTA on May 1st, I would get back this set of values—this row in the table.&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Team&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;Project - VSTA&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Team&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Column&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;Active&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Column&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Date&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;5/1/2009&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Date&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Value&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;98&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Value&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616724" width="1" height="1"&gt;</description></item><item><title>If you are using Windows 7 RC and VSTO you better read this</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/08/if-you-are-using-windows-7-rc-and-vsto-you-better-read-this.aspx</link><pubDate>Fri, 08 May 2009 07:04:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9596112</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9596112.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9596112</wfw:commentRss><description>&lt;p&gt;Saurabh blogs about how to work around an error you get if you published a VSTO solution using VS2008 on a machine running the Windows 7 RC and then you try to install the solution on any machine you will see the following error: “The required version of the .NET Framework is not installed on this computer”:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/vsto/archive/2009/05/07/issues-with-installing-vsto-projects-that-were-published-from-visual-studio-2008-on-windows-7-rc-saurabh-bhatia.aspx"&gt;http://blogs.msdn.com/vsto/archive/2009/05/07/issues-with-installing-vsto-projects-that-were-published-from-visual-studio-2008-on-windows-7-rc-saurabh-bhatia.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9596112" width="1" height="1"&gt;</description></item><item><title>Advanced Word &amp; Excel 2007 Development in Visual Studio 2008 with VSTO (OFC 324)</title><link>http://blogs.msdn.com/eric_carter/archive/2009/05/06/advanced-word-excel-2007-development-in-visual-studio-2008-with-vsto-ofc-324.aspx</link><pubDate>Wed, 06 May 2009 17:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9591644</guid><dc:creator>Eric Carter</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9591644.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9591644</wfw:commentRss><description>&lt;P&gt;I will be at TechEd next week and will present a session on advanced VSTO:&lt;/P&gt;
&lt;P&gt;&lt;B&gt;OFC324&lt;/B&gt; &lt;BR&gt;&lt;B&gt;Advanced Microsoft Office Word and Excel 2007 Development in Microsoft Visual Studio 2008 with Visual Studio Tools for Office&lt;/B&gt; &lt;BR&gt;Eric Carter &lt;BR&gt;Thursday 5/14/2009 1:00PM-2:15PM &lt;BR&gt;Room 515A &lt;/P&gt;
&lt;P&gt;My session will be a very “demo heavy” session.&amp;nbsp; I've now started posting the full walkthrough of my demo.&lt;/P&gt;
&lt;P&gt;Here is what I plan to demo:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE12.png" mce_href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE12.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=artE12 border=0 alt=artE12 src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE12_thumb.png" width=19 height=19 mce_src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE12_thumb.png"&gt;&lt;/A&gt; UDFs in .NET for Excel&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE13.png" mce_href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE13.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=artE13 border=0 alt=artE13 src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE13_thumb.png" width=19 height=19 mce_src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE13_thumb.png"&gt;&lt;/A&gt; Bound Content Controls for Word&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE14.png" mce_href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE14.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=artE14 border=0 alt=artE14 src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE14_thumb.png" width=19 height=19 mce_src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE14_thumb.png"&gt;&lt;/A&gt; Cached Data&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE15.png" mce_href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE15.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=artE15 border=0 alt=artE15 src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE15_thumb.png" width=19 height=19 mce_src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE15_thumb.png"&gt;&lt;/A&gt; Advanced Ribbon Techniques&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE17.png" mce_href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE17.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=artE17 border=0 alt=artE17 src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE17_thumb.png" width=19 height=19 mce_src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE17_thumb.png"&gt;&lt;/A&gt; VSTO Document Features for Add-Ins&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE18.png" mce_href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE18.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=artE18 border=0 alt=artE18 src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE18_thumb.png" width=19 height=19 mce_src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/AdvancedWordExcel2007DevelopmentinVisual_9139/artE18_thumb.png"&gt;&lt;/A&gt; Preview of VSTO v.Next&lt;/P&gt;
&lt;P&gt;See you on Thursday at 1:00 PM.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9591644" width="1" height="1"&gt;</description></item><item><title>Creating a Research Service for Word 2007 in C# with Visual Studio 2008</title><link>http://blogs.msdn.com/eric_carter/archive/2009/04/10/creating-a-research-service-for-word-2007-in-c-with-visual-studio-2008.aspx</link><pubDate>Fri, 10 Apr 2009 21:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9544046</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9544046.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9544046</wfw:commentRss><description>&lt;p&gt;This post examines how to build research services for Word and other Office applications. Word has a task pane called the Research task pane that enables you to enter a search term and search various sources for that search term. To display the Research task pane, click the Research button in the Review tab of Word’s ribbon.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_thumb.png" width="169" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Office enables developers to write a special Web service called a research service that implements two Web methods defined by Office: Registration and Query. Both Web methods take a string and return a string. A research service can be registered with Office and used in Office’s Research task pane. For example, you might write a research service that searches for the search term in a corporate database.&lt;/p&gt;  &lt;p&gt;Although the signatures of the two Web methods you must declare are simple, the actual implementation of these methods is somewhat complex because Word has four separate XML schemas that must be used for the request passed to Registration, the response returned by Registration, the request passed to Query, and the response returned by Query.&lt;/p&gt;  &lt;p&gt;To build a research service, launch Visual Studio 2008 and choose New Project from the File menu. Select Web from the Visual C# Projects in the Project types window and click the ASP.NET Web Service Application in the Templates window, as shown here.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_thumb_1.png" width="525" height="354" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;When you click OK, a web service project is created for you. Within the project is a file called Service1.asmx.cs. Service1.asmx.cs contains a class called Service1 that contains one web method called HelloWorld. We are going to delete the HelloWorld web method and replace it with an implementation of the two web methods required by Research services: Registration and QueryResponse.&lt;/p&gt;  &lt;p&gt;Edit Service1.asmx.cs to produce the result shown below. If the user searches for the string “Eric” the service will send back information about me :)&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.ComponentModel;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Services;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Services.Protocols;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Util;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; ResearchService&lt;/pre&gt;

  &lt;pre class="alt"&gt;{&lt;/pre&gt;

  &lt;pre&gt;  [WebService(Namespace = &lt;span class="str"&gt;&amp;quot;urn:Microsoft.Search&amp;quot;&lt;/span&gt;, Description = &lt;span class="str"&gt;&amp;quot;My First C# Research Service&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]&lt;/pre&gt;

  &lt;pre&gt;  [ToolboxItem(&lt;span class="kwrd"&gt;false&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Service1 : System.Web.Services.WebService&lt;/pre&gt;

  &lt;pre&gt;  {&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [WebMethod]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Registration(&lt;span class="kwrd"&gt;string&lt;/span&gt; registrationXml)&lt;/pre&gt;

  &lt;pre class="alt"&gt;    {&lt;/pre&gt;

  &lt;pre&gt;      MemoryStream stream = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream();&lt;/pre&gt;

  &lt;pre class="alt"&gt;      XmlTextWriter writer = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlTextWriter(&lt;/pre&gt;

  &lt;pre&gt;        stream, System.Text.Encoding.UTF8);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      writer.Formatting = Formatting.Indented;    &lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteStartDocument();&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="rem"&gt;// Registration Response Packet&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;ProviderUpdate&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;urn:Microsoft.Search.Registration.Response&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;SUCCESS&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="rem"&gt;// Provider&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Providers&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Provider&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Message&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;This is an example research library written in Visual Studio 2008 with C#.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      &lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="str"&gt;&amp;quot;{C37EE888-D74E-47e5-B113-BA613D87F0B2}&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="str"&gt;&amp;quot;My First Research Service&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;QueryPath&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="str"&gt;@&amp;quot;http://&amp;quot;&lt;/span&gt; + HttpContext.Current.Request.Url.Host + &lt;span class="str"&gt;&amp;quot;:&amp;quot;&lt;/span&gt; +&lt;/pre&gt;

  &lt;pre class="alt"&gt;        HttpContext.Current.Request.Url.Port.ToString() +&lt;/pre&gt;

  &lt;pre&gt;        HttpContext.Current.Request.Url.AbsolutePath);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;RegistrationPath&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="str"&gt;@&amp;quot;http://&amp;quot;&lt;/span&gt; + HttpContext.Current.Request.Url.Host + &lt;span class="str"&gt;&amp;quot;:&amp;quot;&lt;/span&gt; +&lt;/pre&gt;

  &lt;pre&gt;        HttpContext.Current.Request.Url.Port.ToString() +&lt;/pre&gt;

  &lt;pre class="alt"&gt;        HttpContext.Current.Request.Url.AbsolutePath);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;SOAP&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="rem"&gt;// Services&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Services&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Service&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;{8DD063CA-94FC-4514-8D83-3B36B12432BE}&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="str"&gt;&amp;quot;My First Research Service in C#&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;My First Research Service, created in C# and Visual Studio 2008.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Copyright&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;(C) 2008&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Display&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;On&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Category&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;RESEARCH_GENERAL&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteEndElement(); &lt;span class="rem"&gt;// Service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteEndElement(); &lt;span class="rem"&gt;// Services&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteEndElement(); &lt;span class="rem"&gt;// Provider&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteEndElement(); &lt;span class="rem"&gt;// Providers&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteEndElement(); &lt;span class="rem"&gt;// ProviderUpdate&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteEndDocument();&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.Flush();&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      stream.Position = 0;&lt;/pre&gt;

  &lt;pre&gt;      StreamReader reader = &lt;span class="kwrd"&gt;new&lt;/span&gt; StreamReader(stream);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;string&lt;/span&gt; result = reader.ReadToEnd();&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; result;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [WebMethod]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Query(&lt;span class="kwrd"&gt;string&lt;/span&gt; queryXml)&lt;/pre&gt;

  &lt;pre class="alt"&gt;    {&lt;/pre&gt;

  &lt;pre&gt;      XmlDocument xmlQuery = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlDocument();&lt;/pre&gt;

  &lt;pre class="alt"&gt;      xmlQuery.LoadXml(queryXml);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      XmlNamespaceManager nm1 = &lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlNamespaceManager(xmlQuery.NameTable);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      nm1.AddNamespace(&lt;span class="str"&gt;&amp;quot;ns&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;urn:Microsoft.Search.Query&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      nm1.AddNamespace(&lt;span class="str"&gt;&amp;quot;oc&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;urn:Microsoft.Search.Query.Office.Context&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;string&lt;/span&gt; queryString = xmlQuery.SelectSingleNode(&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;//ns:QueryText&amp;quot;&lt;/span&gt;, nm1).InnerText;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      XmlNamespaceManager nm2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlNamespaceManager(&lt;/pre&gt;

  &lt;pre&gt;        xmlQuery.NameTable);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      nm2.AddNamespace(&lt;span class="str"&gt;&amp;quot;msq&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;urn:Microsoft.Search.Query&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;string&lt;/span&gt; domain = xmlQuery.SelectSingleNode(&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;/msq:QueryPacket/msq:Query&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;        nm2).Attributes.GetNamedItem(&lt;span class="str"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;).Value;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;string&lt;/span&gt; queryId = xmlQuery.SelectSingleNode(&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="str"&gt;&amp;quot;/msq:QueryPacket/msq:Query/msq:QueryId&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre class="alt"&gt;        nm2).InnerText;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      MemoryStream stream = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream();&lt;/pre&gt;

  &lt;pre&gt;      XmlTextWriter writer = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlTextWriter(stream, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.Formatting = Formatting.Indented;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="rem"&gt;// Compose the Query Response packet.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteStartDocument();&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;ResponsePacket&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="str"&gt;&amp;quot;urn:Microsoft.Search.Response&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="rem"&gt;// The providerRevision attribute can be used&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="rem"&gt;// to update the service.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteAttributeString(&lt;span class="str"&gt;&amp;quot;providerRevision&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Response&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="rem"&gt;// The domain attribute identifies the service &lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="rem"&gt;// that executed the query.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteAttributeString(&lt;span class="str"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;, domain);&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;QueryID&amp;quot;&lt;/span&gt;, queryId);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; (String.Compare(&lt;span class="str"&gt;&amp;quot;Eric&amp;quot;&lt;/span&gt;, queryString, &lt;span class="kwrd"&gt;true&lt;/span&gt;) == 0)&lt;/pre&gt;

  &lt;pre class="alt"&gt;      {&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Range&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Results&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;// Begin Document element&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Document&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="str"&gt;&amp;quot;urn:Microsoft.Search.Response.Document&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Eric Carter's Blog&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;LinkUrl&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteAttributeString(&lt;span class="str"&gt;&amp;quot;fileExt&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;htm&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteString(&lt;span class="str"&gt;&amp;quot;http://blogs.msdn.com/eric_carter&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//LinkUrl&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Action&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;DisplayUrl&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="str"&gt;&amp;quot;http://blogs.msdn.com/eric_carter&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="str"&gt;&amp;quot;.NET for Office, the blog of Eric Carter.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;// Include an image&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Media&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteAttributeString(&lt;span class="str"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;IMAGE&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;SrcUrl&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="str"&gt;&amp;quot;http://ericca.members.winisp.net/eric.jpg&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;AltText&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Eric Carter&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Media&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Document&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="rem"&gt;// Include additional text&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;// End Document element&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="rem"&gt;// Begin Content element&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Content&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="str"&gt;&amp;quot;urn:Microsoft.Search.Response.Content&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;HorizontalRule&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Horizontal rule&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="str"&gt;&amp;quot;.NET for Office Highlights&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;HorizontalRule&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Horizontal rule&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Heading&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Top Articles&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Heading&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Excel and UDFs&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;VSTO 3.0 Features&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteString(&lt;span class="str"&gt;&amp;quot;Using &amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteStartElement(&lt;span class="str"&gt;&amp;quot;Char&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteAttributeString(&lt;span class="str"&gt;&amp;quot;bold&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteString(&lt;span class="str"&gt;&amp;quot;.NET&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Char&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteString(&lt;span class="str"&gt;&amp;quot; in Office.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//P&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Content&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;// Finish up.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Results&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        writer.WriteEndElement(); &lt;span class="rem"&gt;//Range&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      }&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteElementString(&lt;span class="str"&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;SUCCESS&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteEndElement(); &lt;span class="rem"&gt;//Response&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      writer.WriteEndElement(); &lt;span class="rem"&gt;//ResponsePacket&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      writer.WriteEndDocument();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      writer.Flush();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="rem"&gt;// Move the results into a string.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      stream.Position = 0;&lt;/pre&gt;

  &lt;pre&gt;      StreamReader reader = &lt;span class="kwrd"&gt;new&lt;/span&gt; StreamReader(stream);&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;string&lt;/span&gt; result = reader.ReadToEnd();&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; result;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;After building the project, press Ctrl+F5 to run the project. A web browser window will appear with a page that you can use to invoke the web service. Copy the address from the address bar in the web browser (the address will be something like &lt;a href="http://localhost:2139/Service1.asmx"&gt;http://localhost:2139/Service1.asmx&lt;/a&gt;) as you will need this address to register the web service with Word.&lt;/p&gt;

&lt;p&gt;Launch Word. Then, bring up Word’s Research task pane by choosing Research from the Review tab in the Proofing group. At the very bottom of the Research task pane is some text that says Research options. Click that text to get to the Research options dialog. Then click the Add Services button. The dialog shown below appears. In this dialog, paste the address to the Web service .asmx file. Then click the Add button.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_thumb_2.png" width="584" height="333" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;When you click the Add button, Word calls the research service and invokes the Registration web method. The implementation of this method returns the block of XML shown here:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ProviderUpdate&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:Microsoft.Search.Registration.Response&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Status&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;SUCCESS&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Status&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Providers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Provider&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;This is an example research library written in &lt;/pre&gt;

  &lt;pre class="alt"&gt;        Visual Studio 2008 with C#.&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Id&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;{C37EE888-D74E-47e5-B113-BA613D87F0B2}&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Id&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;My First Research Service&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryPath&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;http://localhost:2139/Service1.asmx/&lt;/pre&gt;

  &lt;pre class="alt"&gt;        Registration&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryPath&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegistrationPath&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;http://localhost:2139/Service1.asmx/&lt;/pre&gt;

  &lt;pre class="alt"&gt;        Registration&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegistrationPath&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;SOAP&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Services&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Service&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Id&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;{8DD063CA-94FC-4514-8D83-3B36B12432BE}&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Id&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;My First Research Service in C#&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Description&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;My First Research Service, created in C# &lt;/pre&gt;

  &lt;pre&gt;            and Visual Studio 2008.&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Description&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Copyright&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;(C) 2008&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Copyright&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Display&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;On&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Display&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Category&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;RESEARCH_GENERAL&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Category&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Service&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Services&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Provider&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Providers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ProviderUpdate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Word then displays a dialog announcing the provider of the research service, as shown here.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_thumb_3.png" width="308" height="270" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Clicking Continue brings up a dialog showing details about the research service (as determined from the return value of Registration) shown below. Click Install to install the research service.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_10.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_thumb_4.png" width="365" height="320" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Clicking Install returns to the Research Options dialog shown below, which now has the newly added research service installed in the Research Sites category (since we returned RESEARCH_GENERAL in the Category element). Click OK to continue.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_12.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_thumb_5.png" width="384" height="311" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now, you can type the text &lt;i&gt;Eric&lt;/i&gt; in the Research task pane search box and drop down the list of sites to search to select My First Research Service in C#. Click the green arrow button to search. An alternative way to search for text is to type it in the document, select it, and then click it while holding down the Alt key. The research service is contacted, and the Query web method is called. The Query web method is passed XML from Word which is shown here.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryPacket&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:Microsoft.Search.Query&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;revision&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;build&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;(12.0.6213)&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Query&lt;/span&gt; &lt;span class="attr"&gt;domain&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{8DD063CA-94FC-4514-8D83-3B36B12432BE}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryId&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;{98E522B1-5680-4371-8804-72F9FE283807}&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryId&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;OriginatorId&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;{F6FF7BE0-F39C-4ddc-A7D0-&lt;/pre&gt;

  &lt;pre class="alt"&gt;      09A4C6C647A5}&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;OriginatorId&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;SupportedFormats&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Format&lt;/span&gt; &lt;span class="attr"&gt;revision&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;urn:Microsoft.Search.Response.&lt;/pre&gt;

  &lt;pre&gt;        Document:Document&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Format&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Format&lt;/span&gt; &lt;span class="attr"&gt;revision&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;urn:Microsoft.Search.Response.&lt;/pre&gt;

  &lt;pre&gt;        Content:Content&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Format&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Format&lt;/span&gt; &lt;span class="attr"&gt;revision&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;urn:Microsoft.Search.Response.&lt;/pre&gt;

  &lt;pre&gt;        Form:Form&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Format&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;SupportedFormats&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Context&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryText&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;STRING&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;language&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;en-us&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;eric&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryText&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;LanguagePreference&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;en-us&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;LanguagePreference&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Requery&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Context&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Range&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;result&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;OfficeContext&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:Microsoft.Search.Query.&lt;/pre&gt;

  &lt;pre class="alt"&gt;      Office.Context&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;revision&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;UserPreferences&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ParentalControl&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;false&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ParentalControl&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;UserPreferences&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ServiceData&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ApplicationContext&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Microsoft Office Word&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Version&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;(12.0.6213)&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Version&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;SystemInformation&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;SkuLanguage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;en-us&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;SkuLanguage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;LanguagePack&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;en-us&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;LanguagePack&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;InterfaceLanguage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;en-us&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;InterfaceLanguage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Location&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;US&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Location&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;SystemInformation&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ApplicationContext&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryLanguage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;en-us&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryLanguage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;KeyboardLanguage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;en-us&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;KeyboardLanguage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;OfficeContext&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Keywords&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:Microsoft.Search.Query.&lt;/pre&gt;

  &lt;pre&gt;      Office.Keywords&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;revision&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryText&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;eric&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryText&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Keyword&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Word&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;eric&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Word&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StemWord&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;eric&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StemWord&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Keyword&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Keywords&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Query&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryPacket&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The implementation of the web method Query reads the input XML above and extracts from it the query text—the text searched for by the user. It also extracts the query id and domain, which are returned to Office in the response to the web method call. If the query text matches “Eric” then the Query method returns the response shown below. If the query text does not match “Eric” then the Query method returns the response shown below but omits everything within the Range element. The response uses a schema defined by Office for returning results—this schema is documented in the Research Service SDK, but you can get an idea for the types of results Office can render by looking at the picture below which shows what Word renders in the research pane for the XML shown below.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ResponsePacket&lt;/span&gt; &lt;span class="attr"&gt;providerRevision&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:Microsoft.Search.Response&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Response&lt;/span&gt; &lt;span class="attr"&gt;domain&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{8DD063CA-94FC-4514-8D83-3B36B12432BE}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryID&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;{98E522B1-5680-4371-8804-72F9FE283807}&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryID&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Range&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Results&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Document&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:Microsoft.Search.Response.Document&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Eric Carter's Blog&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Action&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;LinkUrl&lt;/span&gt; &lt;span class="attr"&gt;fileExt&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;htm&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;http://blogs.msdn.com/&lt;/pre&gt;

  &lt;pre class="alt"&gt;              eric_carter&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;LinkUrl&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Action&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DisplayUrl&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;http://blogs.msdn.com/&lt;/pre&gt;

  &lt;pre&gt;              eric_carter&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DisplayUrl&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Description&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;.NET for Office, the blog of Eric&lt;/pre&gt;

  &lt;pre&gt;               Carter.&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Description&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Media&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;IMAGE&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;SrcUrl&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;http://ericca.members.winisp.net/&lt;/pre&gt;

  &lt;pre class="alt"&gt;              eric.jpg&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;SrcUrl&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AltText&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Eric Carter&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;AltText&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Media&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Document&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Content&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:Microsoft.Search.Response.Content&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HorizontalRule&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;.NET for Office Highlights&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HorizontalRule&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Heading&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Top Articles&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Heading&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Excel and UDFs&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;VSTO 3.0 Features&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            Using&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Char&lt;/span&gt; &lt;span class="attr"&gt;bold&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;.NET&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Char&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            in Office.&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;P&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Results&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Range&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Status&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;SUCCESS&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Status&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Response&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ResponsePacket&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_14.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/CreatingaResearchServiceforWord2007inCwi_C76A/image_thumb_6.png" width="282" height="555" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This has been a brief introduction to how to get started creating research service in C# using Visual Studio. For more information about creating research services, search http://msdn.microsoft.com for the phrase “research services.” You will find an SDK (listed under Office 2003) which documents the schemas and provides additional sample research services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Excerpted from the book &lt;a href="http://www.informit.com/ShowCover.aspx?isbn=0321533216&amp;amp;type=f"&gt;Visual Studio Tools for Office 2007&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9544046" width="1" height="1"&gt;</description></item><item><title>VSTO Community Activities in Vienna</title><link>http://blogs.msdn.com/eric_carter/archive/2009/03/25/vsto-community-activities-in-vienna.aspx</link><pubDate>Wed, 25 Mar 2009 17:05:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9507845</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9507845.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9507845</wfw:commentRss><description>&lt;p&gt;There are some great VSTO community activities going on in Vienna.&amp;#160; Office Community Day is being held on May 8th in Vienna and is free.&amp;#160; They will be covering:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Introduction to VSTO&lt;/li&gt;    &lt;li&gt;OpenXML&lt;/li&gt;    &lt;li&gt;Deployment in VSTO&lt;/li&gt;    &lt;li&gt;SharePoint Workflows&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;and more.&amp;#160; Mario Meir-Huber and Lars Keller are driving this, and having spoken before with Mario, he knows his VSTO!&amp;#160; The information page for the event is at &lt;a href="http://www.vsto-taskforce.de"&gt;http://www.vsto-taskforce.de&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9507845" width="1" height="1"&gt;</description></item><item><title>Content Control Event Model in Word 2007</title><link>http://blogs.msdn.com/eric_carter/archive/2009/03/24/content-control-event-model-in-word-2007.aspx</link><pubDate>Tue, 24 Mar 2009 17:19:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9504724</guid><dc:creator>Eric Carter</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9504724.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9504724</wfw:commentRss><description>&lt;p&gt;New in Word 2007, content controls can be inserted into a document to provide more structure and control—for example when you have a section of the document that you want to allow the user to put a picture into or pick a value from a drop-down list. There are eight content controls: rich text, plain text, picture, combo box, drop-down list, date picker, group, and building block gallery. These controls can be found in the Developer tab of Word’s Ribbon. The developer tab isn’t displayed by default in Word—to display it, choose Word Options from the Office menu, then select Show Developer tab in the Ribbon from the Popular tab of the Word Options dialog. Here is the Controls group in the Developer tab of the Ribbon:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/ContentControlEventModelinWord2007_9098/figure7_11.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="figure7_11" border="0" alt="figure7_11" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/ContentControlEventModelinWord2007_9098/figure7_11_thumb.png" width="211" height="90" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Shown below is the result of inserting a rich text control into a blank document. When the rich text control is selected as it has been below, the control displays with a border UI to which you can add a title to identify the control. When the control is deselected, it displays without the border UI and optional title and just looks like any other region of text in the document. This is important as it allows you to have a control paradigm in the document but only while the user is editing the contents of the control—when the user reads or prints the document, no control border UI is displayed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/ContentControlEventModelinWord2007_9098/figure7_12.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="figure7_12" border="0" alt="figure7_12" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/ContentControlEventModelinWord2007_9098/figure7_12_thumb.png" width="244" height="122" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Lets examine the events that can be raised on content controls.&lt;/p&gt;  &lt;p&gt;• &lt;strong&gt;Document.ContentControlAfterAdd&lt;/strong&gt; is raised after a content control is added to the document. Word passes the ContentControl object for the newly added content control as a parameter to this event. It also passes an inUndoRedo bool parameter that indicates whether the content control was added because undo or redo was invoked.&lt;/p&gt;  &lt;p&gt;• &lt;strong&gt;Document.ContentControlBeforeDelete&lt;/strong&gt; is raised before a content control is deleted from the document. Word passes the ContentControl object for the content control that is about to be deleted as a parameter to this event. It also passes an inUndoRedo bool parameter that indicates whether the content control was deleted because undo or redo was invoked.&lt;/p&gt;  &lt;p&gt;• &lt;strong&gt;Document.ContentControlOnExit&lt;/strong&gt; is raised when a user leaves a content control that currently has focus and sets the focus to another part of the document. Word passes the ContentControl object for the content control that lost focus as a parameter to this event. It also passes by reference a bool cancel parameter. The cancel parameter can be set to true by your event handler to prevent the user from leaving the content control.&lt;/p&gt;  &lt;p&gt;• &lt;strong&gt;Document.ContentControlOnEnter&lt;/strong&gt; is raised when a user enters a content control by setting the focus to the content control. Word passes the ContentControl object for the content control that gained focus as a parameter to this event.&lt;/p&gt;  &lt;p&gt;• &lt;strong&gt;Document.ContentControlBeforeStoreUpdate&lt;/strong&gt; is raised when a content control that is bound to a CustomXMLPart in the document (using the XMLMapping property) has an update to pass to the XML data store. Word passes the ContentControl object for the content control that is about to update the CustomXMLPart. It also passes by reference a string content parameter. The content parameter can be modified by your event handler to change the data before it is put in the CustomXMLPart.&lt;/p&gt;  &lt;p&gt;• &lt;strong&gt;Document.ContentControlBeforeContentUpdate&lt;/strong&gt; is raised when a content control that is bound to a CustomXMLPart in the document (using the XMLMapping property) is updated from the CustomXMLPart. Word passes the ContentControl object for the content control that is about to be updated from the CustomXMLPart. It also passes by reference a string content parameter. The content parameter can be modified by your event handler to change the data coming from the CustomXMLPart before it updates the bound content control.&lt;/p&gt;  &lt;p&gt;• &lt;strong&gt;Document.BuildingBlockInsert&lt;/strong&gt; is raised when a building block (a block of pre-defined content in a Word template that can include text, images, etc) is added to the document. Word passes the Range object for where the building block is inserted in the document as a parameter to this event. Word passes the name of the building block in the string name parameter, the category of the building block in the string category parameter, the type of the building block in the string type parameter, and the name of the template that contains the building block in the string template parameter.&lt;/p&gt;  &lt;p&gt;The code below shows a VSTO Word document customization that handles the content control related events. To see all these event handlers work, add the code to a document and while running the document, add content controls to the document by clicking on the control icons in the Controls group in the Developer tab.&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ThisDocument&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_Startup(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, &lt;/pre&gt;

  &lt;pre&gt;    System.EventArgs e)&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_Shutdown(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender,&lt;/pre&gt;

  &lt;pre class="alt"&gt;    System.EventArgs e)&lt;/pre&gt;

  &lt;pre&gt;  {&lt;/pre&gt;

  &lt;pre class="alt"&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="preproc"&gt;#region&lt;/span&gt; VSTO Designer generated code&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; InternalStartup()&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.ContentControlBeforeStoreUpdate +=&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; Word.DocumentEvents2_ContentControlBeforeStoreUpdateEventHandler(&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_ContentControlBeforeStoreUpdate);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.BuildingBlockInsert +=&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; Word.DocumentEvents2_BuildingBlockInsertEventHandler(&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_BuildingBlockInsert);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.ContentControlAfterAdd +=&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; Word.DocumentEvents2_ContentControlAfterAddEventHandler(&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_ContentControlAfterAdd);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.ContentControlOnEnter +=&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; Word.DocumentEvents2_ContentControlOnEnterEventHandler(&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_ContentControlOnEnter);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.Shutdown += &lt;span class="kwrd"&gt;new&lt;/span&gt; System.EventHandler(&lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_Shutdown);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.ContentControlOnExit +=&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; Word.DocumentEvents2_ContentControlOnExitEventHandler(&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_ContentControlOnExit);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.ContentControlBeforeDelete +=&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; Word.DocumentEvents2_ContentControlBeforeDeleteEventHandler(&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_ContentControlBeforeDelete);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.Startup += &lt;span class="kwrd"&gt;new&lt;/span&gt; System.EventHandler(&lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_Startup);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.ContentControlBeforeContentUpdate +=&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;new&lt;/span&gt; Word.DocumentEvents2_ContentControlBeforeContentUpdateEventHandler(&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ThisDocument_ContentControlBeforeContentUpdate);&lt;/pre&gt;

  &lt;pre class="alt"&gt;  }&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_ContentControlAfterAdd(&lt;/pre&gt;

  &lt;pre class="alt"&gt;    Word.ContentControl newContentControl,&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;bool&lt;/span&gt; inUndoRedo)&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;    MessageBox.Show(String.Format(&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="str"&gt;&amp;quot;ContentControl of type {0} with ID {1} added.&amp;quot;&lt;/span&gt; +&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="str"&gt;&amp;quot;  inUndoRedo is {2}.&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;      newContentControl.Type, newContentControl.ID, inUndoRedo));&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_ContentControlBeforeContentUpdate(&lt;/pre&gt;

  &lt;pre class="alt"&gt;    Word.ContentControl contentControl,&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;ref&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; content)&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;    MessageBox.Show(String.Format(&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="str"&gt;&amp;quot;ContentControl of type {0} with ID {1} updated.&amp;quot;&lt;/span&gt; +&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="str"&gt;&amp;quot;  New content is {2}.&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;      contentControl.Type, contentControl.ID, content));&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_ContentControlBeforeDelete(&lt;/pre&gt;

  &lt;pre class="alt"&gt;    Word.ContentControl oldContentControl,&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;bool&lt;/span&gt; inUndoRedo)&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;    MessageBox.Show(String.Format(&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="str"&gt;&amp;quot;ContentControl of type {0} with ID {1} deleted.&amp;quot;&lt;/span&gt; +&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="str"&gt;&amp;quot;  inUndoRedo is {2}.&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;      oldContentControl.Type, oldContentControl.ID, inUndoRedo));&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_ContentControlBeforeStoreUpdate(&lt;/pre&gt;

  &lt;pre class="alt"&gt;    Word.ContentControl contentControl,&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;ref&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; content)&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;    MessageBox.Show(String.Format(&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="str"&gt;&amp;quot;ContentControl of type {0} with ID {1} updating &amp;quot;&lt;/span&gt; + &lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="str"&gt;&amp;quot;XML Store with content {2}.&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;      contentControl.Type, contentControl.ID, content));&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_ContentControlOnEnter(&lt;/pre&gt;

  &lt;pre class="alt"&gt;    Word.ContentControl contentControl)&lt;/pre&gt;

  &lt;pre&gt;  {&lt;/pre&gt;

  &lt;pre class="alt"&gt;    MessageBox.Show(String.Format(&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="str"&gt;&amp;quot;ContentControl of type {0} with ID {1} entered.&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;      contentControl.Type, contentControl.ID));&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_ContentControlOnExit(&lt;/pre&gt;

  &lt;pre class="alt"&gt;    Word.ContentControl contentControl,&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;ref&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; cancel)&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;    MessageBox.Show(String.Format(&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="str"&gt;&amp;quot;ContentControl of type {0} with ID {1} exited.&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;      contentControl.Type, contentControl.ID));&lt;/pre&gt;

  &lt;pre class="alt"&gt;  }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisDocument_BuildingBlockInsert(&lt;/pre&gt;

  &lt;pre&gt;    Word.Range range, &lt;span class="kwrd"&gt;string&lt;/span&gt; name,&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; category, &lt;span class="kwrd"&gt;string&lt;/span&gt; blockType,&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; template)&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;    MessageBox.Show(String.Format(&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="str"&gt;&amp;quot;BuildingBlock added at position {0} with name {1}, &amp;quot;&lt;/span&gt; +&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="str"&gt;&amp;quot;category {2}, blockType {3}, from template {4}.&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;      range.Start, name, category, blockType, template));&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;To see the ContentControlBeforeStoreUpdate and ContentControlBeforeContentUpdate events fire, you need to add a content control that is bound to the XML store in the document. The easiest way to do this is to use the Quick Parts drop down in the Insert tab. From the Quick Parts drop down, add a document property like Author from the Document Property menu. The content control that is added will be mapped to Author in the document properties in the XML data store. When you edit the content control then exit the content control, the ContentControlBeforeStoreUpdate event will be raised as the contents of the content control get written back to the Author property in the XML data store. To see the ContentControlBeforeContentUpdate event fire, use the Office menu, pick Prepare, then Properties. The document properties will be shown in the document information pane. Edit the author field in the document properties pane then exit the author field. This will cause the ContentControlBeforeContentUpdate event to be raised as the change you made in the document information pane is pushed from the XML data store back to the bound content control in the document. The picture below shows a Word document with a content control bound to the Author property in the XML data store. It also shows the document information pane where the Author property is displayed directly out of the XML data store. &lt;/p&gt;

&lt;p&gt;Finally, to see the BuildingBlockInsert event, use the Quick Parts drop down in the Insert tab and select Building Blocks Organizer. From the Building Block Organizer dialog, pick a building block to insert and click on the Insert button. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/ContentControlEventModelinWord2007_9098/figure7_13.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="figure7_13" border="0" alt="figure7_13" src="http://blogs.msdn.com/blogfiles/eric_carter/WindowsLiveWriter/ContentControlEventModelinWord2007_9098/figure7_13_thumb.png" width="560" height="310" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the book “Visual Studio Tools for Office 2007”&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.informit.com/store/product.aspx?isbn=0321533216"&gt;&lt;img src="http://www.informit.com/ShowCover.aspx?isbn=0321533216&amp;amp;type=f" width="86" height="114" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9504724" width="1" height="1"&gt;</description></item><item><title>Object Model Changes for Developers Between Excel 2003 and Excel 2007</title><link>http://blogs.msdn.com/eric_carter/archive/2009/03/19/object-model-changes-for-developers-between-excel-2003-and-excel-2007.aspx</link><pubDate>Thu, 19 Mar 2009 22:32:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9491285</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9491285.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9491285</wfw:commentRss><description>&lt;p&gt;There a lot of changes between Excel 2003 and Excel 2007 for developers.&amp;#160; Here are some highlights that I found interesting in the object model.&amp;#160; Note that &lt;a href="http://blogs.msdn.com/eric_carter/archive/2008/03/28/fun-with-oleview-to-discover-what-s-new-in-office-2007.aspx"&gt;you should use the trick I blog about in this post for more detailed comparisons&lt;/a&gt;.&amp;#160; There is also a nice resource on MSDN to see object model changes here: &lt;a title="http://msdn.microsoft.com/en-us/library/bb149069.aspx" href="http://msdn.microsoft.com/en-us/library/bb149069.aspx"&gt;http://msdn.microsoft.com/en-us/library/bb149069.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;u&gt;New Object Model Objects&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;Excel 2007 introduces 51 new objects to the object model. These new objects are, listed alphabetically: AboveAverage, Action, Actions, ChartFormat, ChartView, ColorScale, ColorScaleCriteria, ColorScaleCriterion, ColorStop, ColorStops, ConditionValue, Connections, Databar, DialogSheetView, FormatColor, HeaderFooter, Icon, IconCriteria, IconCriterion, IconSet, IconSetCondition, IconSets, LinearGradient, ModuleView, MultiThreadedCalculation, ODBCConnection, OLEDBConnection, Page, Pages, PivotAxis, PivotFilter, PivotFilters, PivotLine, PivotLineCells, PivotLines, Ranges, RectangularGradient, Research, ServerViewableItems, SheetViews, Sort, SortField, SortFields, TableStyle, TableStyleElement, TableStyleElements, TableStyles, Top10, UniqueValues, WorkbookConnection, and WorksheetView.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Events&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;Application.AfterCalculate is a new event in Excel 2007 that is raised when all calculations that are pending are complete. This event can be use to determine if all workbooks have been completely updated by any calculations or queries that are in progress.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;New Functions in Excel 2007&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;There are 98 new functions in Excel 2007. The new functions in alphabetical order are AccrInt, AccrIntM, AmorDegrc, AmorLinc, AverageIf, AverageIfs, BesselI, BesselJ, BesselK, BesselY, Bin2Dec, Bin2Hex, Bin2Oct, Complex, Convert, CountIfs, CoupDayBs, CoupDays, CoupDaysNc, CoupNcd, CoupNum, CoupPcd, CumIPmt, CumPrinc, Dec2Bin, Dec2Hex, Dec2Oct, Delta, Disc, DollarDe, DollarFr, Duration, EDate, Effect, EoMonth, Erf, ErfC, FactDouble, FVSchedule, Gcd, GeStep, Hex2Bin, Hex2Dec, Hex2Oct, IfError, ImAbs, Imaginary, ImArgument, ImConjugate, ImCos, ImDiv, ImExp, ImLn, ImLog10, ImLog2, ImPower, ImProduct, ImReal, ImSin, ImSqrt, ImSub, ImSum, IntRate, IsEven, IsOdd, Lcm, MDuration, MRound, MultiNomial, NetworkDays, Nominal, Oct2Bin, Oct2Dec, Oct2Hex, OddFPrice, OddFYield, OddLPrice, OddLYield, Price, PriceDisc, PriceMat, Quotient, RandBetween, Received, SeriesSum, SqrtPi, SumIfs, TBillEq, TBillPrice, TBillYield, WeekNum, WorkDay, Xirr, Xnpv, YearFrac, YieldDisc, and YieldMat.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;New Built-in Document Properties&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;Content type   &lt;br /&gt;Content status    &lt;br /&gt;Document version    &lt;br /&gt;Language&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Table versus List versus ListObject&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;Tables were introduced in Excel 2003 but in that version of Excel they were called lists. In Excel 2007, the naming was changed in the Excel UI to Table. However, the object model object representing a table is called ListObject reflecting the earlier naming in Excel 2003. No matter what you call them (Tables/Lists/ListObjects) they are a key feature of Excel that is well supported by VSTO—VSTO allows you to do complex data binding to Table.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;There are also some big additional changes that go beyond object model like Ribbon support, application level task panes, and ClickOnce support.&amp;#160; But these are some highlights in the object model.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9491285" width="1" height="1"&gt;</description></item><item><title>Changes in the Add-In Model between VSTO 2.0 and VSTO 3.0</title><link>http://blogs.msdn.com/eric_carter/archive/2009/03/17/changes-in-the-add-in-model-between-vsto-2-0-and-vsto-3-0.aspx</link><pubDate>Tue, 17 Mar 2009 22:36:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9485015</guid><dc:creator>Eric Carter</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/eric_carter/comments/9485015.aspx</comments><wfw:commentRss>http://blogs.msdn.com/eric_carter/commentrss.aspx?PostID=9485015</wfw:commentRss><description>&lt;p&gt;It is instructive to compare code from the previous edition of my book to see what changed between Outlook 2003 and Outlook 2007 as well as the changes to the add-in model between VSTO 2.0 and VSTO 3.0.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;This is a VSTO Outlook add-in that handles the ItemSend event and checks if there are more than 25 recipients to warn you that you are sending to a lot of people.&lt;/p&gt;  &lt;p&gt;Here is the VSTO 2.0 and Outlook 2003 version:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.VisualStudio.Tools.Applications.Runtime;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Outlook = Microsoft.Office.Interop.Outlook;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; OutlookAddin1&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ThisApplication&lt;/pre&gt;

  &lt;pre&gt;  {&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisApplication_Startup(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;this&lt;/span&gt;.ItemSend += &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;        Outlook.ApplicationEvents_11_ItemSendEventHandler(&lt;/pre&gt;

  &lt;pre class="alt"&gt;        ThisApplication_ItemSend);&lt;/pre&gt;

  &lt;pre&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisApplication_ItemSend(&lt;span class="kwrd"&gt;object&lt;/span&gt; item, &lt;span class="kwrd"&gt;ref&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; cancel)&lt;/pre&gt;

  &lt;pre class="alt"&gt;    {&lt;/pre&gt;

  &lt;pre&gt;      Outlook.MailItem myItem = item &lt;span class="kwrd"&gt;as&lt;/span&gt; Outlook.MailItem;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; (myItem != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre class="alt"&gt;      {&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Outlook.Recipient recip &lt;span class="kwrd"&gt;in&lt;/span&gt; myItem.Recipients)&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;          &lt;span class="kwrd"&gt;if&lt;/span&gt; (recip.AddressEntry.Members.Count &amp;gt; 25)&lt;/pre&gt;

  &lt;pre class="alt"&gt;          {&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="rem"&gt;// Ask the user if she really wants to send this e-mail&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; message = &lt;span class="str"&gt;&amp;quot;Send mail to {0} with {1} people?&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; caption = &lt;span class="str"&gt;&amp;quot;More than 25 recipients&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            MessageBoxButtons buttons = MessageBoxButtons.YesNo;&lt;/pre&gt;

  &lt;pre&gt;            DialogResult result;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;            result = MessageBox.Show(String.Format(message,&lt;/pre&gt;

  &lt;pre class="alt"&gt;              recip.AddressEntry.Name,&lt;/pre&gt;

  &lt;pre&gt;              recip.AddressEntry.Members.Count),&lt;/pre&gt;

  &lt;pre class="alt"&gt;              caption, buttons);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (result == DialogResult.No)&lt;/pre&gt;

  &lt;pre&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;              cancel = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;              &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            }&lt;/pre&gt;

  &lt;pre&gt;          }&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;      }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisApplication_Shutdown(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="preproc"&gt;#region&lt;/span&gt; VSTO Designer generated code&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; InternalStartup()&lt;/pre&gt;

  &lt;pre class="alt"&gt;    {&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Startup += &lt;span class="kwrd"&gt;new&lt;/span&gt; System.&lt;/pre&gt;

  &lt;pre class="alt"&gt;        EventHandler(ThisApplication_Startup);&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Shutdown += &lt;span class="kwrd"&gt;new&lt;/span&gt; System.&lt;/pre&gt;

  &lt;pre class="alt"&gt;        EventHandler(ThisApplication_Shutdown);&lt;/pre&gt;

  &lt;pre&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Here is the VSTO 3.0 and Outlook 2007 version:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml.Linq;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Outlook = Microsoft.Office.Interop.Outlook;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Office = Microsoft.Office.Core;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; OutlookAddIn1&lt;/pre&gt;

  &lt;pre class="alt"&gt;{&lt;/pre&gt;

  &lt;pre&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ThisAddIn&lt;/pre&gt;

  &lt;pre class="alt"&gt;  {&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThisAddIn_Startup(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender,&lt;/pre&gt;

  &lt;pre class="alt"&gt;      System.EventArgs e)&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Application.ItemSend += &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;        Outlook.ApplicationEvents_11_ItemSendEventHandler( &lt;/pre&gt;

  &lt;pre class="alt"&gt;        Application_ItemSend);&lt;/pre&gt;

  &lt;pre&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; CountRecipients(Outlook.AddressEntry entry)&lt;/pre&gt;

  &lt;pre class="alt"&gt;    {&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;int&lt;/span&gt; count = 1;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; (entry.Members == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; 1;&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;      {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Outlook.AddressEntry e &lt;span class="kwrd"&gt;in&lt;/span&gt; entry.Members)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;          count = count + CountRecipients(e);&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;      }&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; count;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; Application_ItemSend(&lt;span class="kwrd"&gt;object&lt;/span&gt; Item, &lt;span class="kwrd"&gt;ref&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Cancel)&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;      Outlook.MailItem myItem = Item &lt;span class="kwrd"&gt;as&lt;/span&gt; Outlook.MailItem;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;int&lt;/span&gt; recipientCount = 0;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; (myItem != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre class="alt"&gt;      {&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Outlook.Recipient recip &lt;span class="kwrd"&gt;in&lt;/span&gt; myItem.Recipients)&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;          recipientCount += CountRecipients(recip.AddressEntry);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (recipientCount &amp;gt; 25)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// Ask the user if she really wants to send this e-mail&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; message = &lt;span class="str"&gt;&amp;quot;Send mail to {0} people?&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; caption = &lt;span class="str"&gt;&amp;quot;More than 25 recipients&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;            MessageBoxButtons buttons = MessageBoxButtons.YesNo;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            DialogResult result;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            result = MessageBox.Show(String.Format(message,&lt;/pre&gt;

  &lt;pre&gt;              recipientCount),&lt;/pre&gt;

  &lt;pre class="alt"&gt;              caption, buttons);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (result == DialogResult.No)&lt;/pre&gt;

  &lt;pre&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;              Cancel = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;              &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            }&lt;/pre&gt;

  &lt;pre&gt;          }&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;      }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="preproc"&gt;#region&lt;/span&gt; VSTO generated code&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; InternalStartup()&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Startup += &lt;span class="kwrd"&gt;new&lt;/span&gt; System.EventHandler(ThisAddIn_Startup);&lt;/pre&gt;

  &lt;pre&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;  }&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;What has changed?&lt;/p&gt;

&lt;p&gt;First, the add-in class is now called ThisAddIn rather than ThisApplication and is found in the file “ThisAddIn.cs” rather than “ThisApplication.cs”. Note that this change was made in the VSTO 2005 Second edition release—a free point release we did between VSTO 2.0 and VSTO 3.0.&amp;#160; Because the Outlook Application object is now provided via a member variable called Application rather than as an aggregate of the base class, the event hookup code that previously started with &lt;strong&gt;this.ItemSend&lt;/strong&gt; in the VSTO 2.0 add-in model is now &lt;strong&gt;this.Application.ItemSend&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Also interesting is one line that did not change between versions—the delegate definition &lt;strong&gt;ApplicationEvents_11_ItemSendEventHandler&lt;/strong&gt;. One would think that this would have changed to be prefaced with ApplicationEvents_12 as 12 is the internal version number for Outlook 2007. But the Outlook team decided to not create a new events interface for Outlook 2007 and instead extended the existing ApplicationEvents_11 interface. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9485015" width="1" height="1"&gt;</description></item></channel></rss>