<?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>Beth Massi - Sharing the goodness that is VB : VS2008</title><link>http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx</link><description>Tags: VS2008</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Office Development with Visual Studio Tutorial Series – Part 2</title><link>http://blogs.msdn.com/bethmassi/archive/2009/12/08/office-development-with-visual-studio-2008-tutorial-series-part-2.aspx</link><pubDate>Tue, 08 Dec 2009 18:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9934207</guid><dc:creator>Beth Massi</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9934207.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9934207</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9934207</wfw:comment><description>&lt;P&gt;Last month &lt;A href="https://mvp.support.microsoft.com/profile=169AE602-45EF-47E6-8868-CA3E91D0A1EE" mce_href="https://mvp.support.microsoft.com/profile=169AE602-45EF-47E6-8868-CA3E91D0A1EE"&gt;Robert Green&lt;/A&gt;, VSTO MVP, started a series of tutorials on building on Office 2007. Today we published part 2 of his step-by-step tutorials. Thanks Robert!&lt;/P&gt;
&lt;P&gt;In this second part of the series of tutorials on Office Business Applications, learn how to create a Word 2007 price quote generation solution using Visual Studio 2008. This tutorial shows you how to create a custom task pane to display data from a database and binding that data to content controls. This step-by-step tutorial also includes full source code in Visual Basic. Check out the tutorial on the &lt;A href="http://msdn.microsoft.com/en-us/vsto/ee620548.aspx" mce_href="http://msdn.microsoft.com/en-us/vsto/ee620548.aspx"&gt;VSTO Developer Center&lt;/A&gt;: &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;A href="http://msdn.microsoft.com/en-us/vsto/ee861194.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/vsto/ee861194.aspx"&gt;Building an Office Business Application Part 2 – Generating Automobile Quotes&lt;/A&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;And if you missed part 1:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/en-us/vsto/ee620548.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/vsto/ee620548.aspx"&gt;Building an Office Business Application Part 1 - Scheduling Customer Appointments&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;If you’re just getting started with Office development in Visual Studio, this is a great place to start.&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9934207" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Community/default.aspx">Community</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/OBA/default.aspx">OBA</category></item><item><title>SF Bay.NET UG Tonight: Create a Custom Outlook Add-In using VSTO</title><link>http://blogs.msdn.com/bethmassi/archive/2009/11/18/sf-bay-net-ug-tonight-create-a-custom-outlook-add-in-using-vsto.aspx</link><pubDate>Wed, 18 Nov 2009 22:23:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9924788</guid><dc:creator>Beth Massi</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9924788.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9924788</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9924788</wfw:comment><description>&lt;p&gt;If you’re in the Bay Area, come on out to downtown SF where &lt;a href="http://robindotnet.wordpress.com/" target="_blank"&gt;Robin&lt;/a&gt; will be talking about Outlook Add-ins tonight. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.baynetug.org/DesktopModules/DetailXEvents.aspx?ItemID=393&amp;amp;mid=49" target="_blank"&gt;&lt;strong&gt;Create a custom Outlook Add-In using VSTO&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;:&amp;#160; Wednesday, 11/18/2009 at 6:30 PM    &lt;br /&gt;&lt;strong&gt;Where&lt;/strong&gt;: Microsoft San Francisco Office, 835 Market Street, Suite 700, San Francisco&lt;/p&gt;  &lt;p&gt;Visual Studio 2008 and Office 2007 made it easier than ever to create add-ins for Office. In this session, Robin Shahan will show how to program an add-in for Outlook that modifies the Quick Access Toolbar, adds your own section to the Office Ribbon, and adds a command bar to the main Outlook window. Then she will show you how to deploy the application via ClickOnce deployment.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Presenter's Bio&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Robin Shahan has over 20 years of experience developing complex, business-critical applications. She is currently the Director of Engineering for GoldMail, a small company based in San Francisco whose product provides voice-over-visual messages. Robin is a moderator in the MSDN Forum for ClickOnce and Setup &amp;amp; Deployment projects, and vows to learn Windows Installer some day. She is also a Microsoft MVP in Client App Dev; you can follow her blog at &lt;a href="http://robindotnet.wordpress.com/" target="_blank"&gt;http://robindotnet.wordpress.com/&lt;/a&gt;, or on Twitter, @RobinDotNet.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.baynetug.org/DesktopModules/DetailXEvents.aspx?ItemID=393&amp;amp;mid=49" target="_blank"&gt;&lt;strong&gt;Register for this talk tonight on the Bay.NET website&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;See you there!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9924788" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Community/default.aspx">Community</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2010/default.aspx">VS2010</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VSTO/default.aspx">VSTO</category></item><item><title>Interop Between VBA and Visual Studio Office Solutions (VSTO)</title><link>http://blogs.msdn.com/bethmassi/archive/2009/11/05/interop-between-vba-and-visual-studio-office-solutions-vsto.aspx</link><pubDate>Fri, 06 Nov 2009 05:03:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9918383</guid><dc:creator>Beth Massi</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9918383.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9918383</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9918383</wfw:comment><description>&lt;p&gt;Couple weeks ago when &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/10/20/sdc-2009-recap-surprise.aspx" target="_blank"&gt;I was in Holland speaking at SDC&lt;/a&gt; an attendee asked me how he could call methods in an Office solution (VSTO) from VBA functions defined in a document and vice versa. I thought I’d follow up with a post on how to do this, but first a little background on why this architecture would make sense. &lt;/p&gt;  &lt;p&gt;There are many reasons why you would build an Office solution using Visual Studio (VSTO) as opposed to a pure VBA solution. &lt;a href="http://geeks.netindonesia.net/blogs/andriyadi/default.aspx"&gt;Andri Yadi&lt;/a&gt;, VSTO MVP, &lt;a href="http://geeks.netindonesia.net/blogs/andriyadi/archive/2008/08/20/vba-vs-vsto.aspx" target="_blank"&gt;wrote a great piece on his blog a while back explaining the benefits of VSTO compared to VBA&lt;/a&gt;. He broke it down into 10 areas, of which the main benefits are the tools and designers you have available in Visual Studio as well as the entire .NET framework and modern languages at your disposal. &lt;/p&gt;  &lt;p&gt;However, there are probably many VBA assets that people in your company have already written, like complex algorithms or other business logic that you really don’t want to rewrite. Or maybe you still want to allow users to customize these functions in the VBA editor but it’s necessary for you to call them from your .NET code. &lt;/p&gt;  &lt;p&gt;Likewise, you may want to develop a customization that takes advantage of WCF services or a WPF UI, modern language features, or any other feature of the .NET framework that would be difficult or impossible to do in VBA, and you want the user to be able to access these methods from their VBA functions. The attendee at SDC didn’t go into much detail on what his Office customization was doing exactly but he wanted to make some of his public methods available to his VBA users and this makes sense in a lot of situations. Luckily Visual Studio makes this very easy to do. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Creating an Excel Document Customization&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;For this example I’ll create an Excel document customization that accesses data through a WCF service and does some calculations on that data. The calculations, however, will be in VBA. To access the remote data over the internet I’ll create an ADO.NET Data Service. I want to pull up data in a Northwind view called &lt;em&gt;Sales Totals By Amount&lt;/em&gt;. I’ve shown how to create an ADO.NET Data Service many times before so I won’t go into too much detail here. Please refer to the steps shown in the &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx" target="_blank"&gt;Using ADO.NET Data Services&lt;/a&gt; article. The only difference in this case is I selected the View &lt;em&gt;Sales Totals By Amount&lt;/em&gt; into my Entity Framework model when I performed that step. &lt;/p&gt;  &lt;p&gt;I have an Excel macro-enabled workbook that already has a simple VBA function that Sums all the columns below the first row. The function is sitting in a module called MyFunctions. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_2.png" target="_blank"&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/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb.png" width="669" height="251" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;To create the new&amp;#160; Excel workbook customization I’m going to add a new project to my solution and select Office 2007 Excel Workbook. Next it will ask if you want to create a new document or use an existing one, here’s where I’ll specify the macro-enabled workbook I already have above.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_6.png" target="_blank"&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/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb_2.png" width="613" height="446" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Next Add a Service Reference to the ADO.NET Data Service (which I called NorthwindReportService) &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx" target="_blank"&gt;just like I showed here&lt;/a&gt; and copy the URI into your clipboard. Then create a setting to store the URI, just double-click on My Project (Properties in C#) and select the Settings tab and enter an application scope property called ServiceURI.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_8.png" target="_blank"&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/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb_3.png" width="684" height="115" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;When you add the service reference this generates client-side proxy types that you can use. I’m going to bind the data returned from Sales_Totals_by_Amount to an Excel ListObject. Open the Data Source window (Data –&amp;gt; Show Data Sources) and then add a new data source (Data –&amp;gt; Add New Data Source…). In the Data Source Connection Wizard select Object, then Next, then expand the types in your project’s NorthwindReportService namespace. Select Sales_Totals_by_Amount and then click Finish and you will see the type’s properties appear in the Data Sources Window:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_10.png" target="_blank"&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/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb_4.png" width="670" height="515" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Double-click on Sheet1 in the project and drag the Sales_Totals_by_Amount from the Data Sources window onto the &lt;strong&gt;second &lt;/strong&gt;row of the sheet (our macro is going to sum into the first row so we want to place the data starting on the second row). This will automatically set up a BindingSource in the system tray that we will use to set our list of data coming from the service. If you are familiar with Winforms development this should seem very familiar. The ListObject is the main data object you work with in Excel solutions. For this example I’m going to select the OrderId column, right-click and then Delete. I’ll do the same to the ShippedDate column because I only want to display the CompanyName and SaleAmount for this example. Finally I’ll set the formatting (Home Tab on the Excel Designer) to Currency for the first cell. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_12.png" target="_blank"&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/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb_5.png" width="589" height="373" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now we’re ready to write some code to load our data. Right-click on ThisWorkbook and select View Code. Here I’m going to create a Friend ReadOnly Property so we can easily access the service reference from anywhere in the project. I’m making this Friend so that it won’t be visible outside of the .NET assembly. I’m also creating a Public method that gets the data from our service and optionally accepts a Company Name. The results are then set to the DataSource of the ListObject’s BindingSource on Sheet1:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;VBATest.NorthwindReportService

&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;ThisWorkbook

    &lt;span style="color: blue"&gt;Private &lt;/span&gt;_ReportService &lt;span style="color: blue"&gt;As New &lt;/span&gt;NorthwindEntities(&lt;span style="color: blue"&gt;New &lt;/span&gt;Uri(&lt;span style="color: blue"&gt;My&lt;/span&gt;.Settings.ServiceURI))
    &lt;span style="color: blue"&gt;Friend ReadOnly Property &lt;/span&gt;ReportService() &lt;span style="color: blue"&gt;As &lt;/span&gt;NorthwindEntities
        &lt;span style="color: blue"&gt;Get
            Return &lt;/span&gt;_ReportService
        &lt;span style="color: blue"&gt;End Get
    End Property

    Public Sub &lt;/span&gt;GetData(&lt;span style="color: blue"&gt;Optional ByVal &lt;/span&gt;companyName = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;Try
            If &lt;/span&gt;Globals.Sheet1 &lt;span style="color: blue"&gt;IsNot Nothing Then

                Dim &lt;/span&gt;results &lt;span style="color: blue"&gt;As &lt;/span&gt;IEnumerable(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Sales_Totals_by_Amount)

                &lt;span style="color: blue"&gt;If &lt;/span&gt;companyName = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot; &lt;/span&gt;&lt;span style="color: blue"&gt;Then
                    &lt;/span&gt;results = &lt;span style="color: blue"&gt;Me&lt;/span&gt;.ReportService.Sales_Totals_by_Amount
                &lt;span style="color: blue"&gt;Else
                    &lt;/span&gt;results = &lt;span style="color: blue"&gt;From &lt;/span&gt;s &lt;span style="color: blue"&gt;In Me&lt;/span&gt;.ReportService.Sales_Totals_by_Amount _
                              &lt;span style="color: blue"&gt;Where &lt;/span&gt;s.CompanyName.StartsWith(companyName)
                &lt;span style="color: blue"&gt;End If

                &lt;/span&gt;Globals.Sheet1.Sales_Totals_by_AmountBindingSource.DataSource = results.ToList()
            &lt;span style="color: blue"&gt;End If
        Catch &lt;/span&gt;ex &lt;span style="color: blue"&gt;As &lt;/span&gt;Exception
            &lt;span style="color: green"&gt;'TODO: Error Handling
            &lt;/span&gt;MsgBox(ex.ToString())
        &lt;span style="color: blue"&gt;End Try
    End Sub

    Private Sub &lt;/span&gt;ThisWorkbook_Startup() &lt;span style="color: blue"&gt;Handles Me&lt;/span&gt;.Startup

    &lt;span style="color: blue"&gt;End Sub

    Private Sub &lt;/span&gt;ThisWorkbook_Shutdown() &lt;span style="color: blue"&gt;Handles Me&lt;/span&gt;.Shutdown

    &lt;span style="color: blue"&gt;End Sub

End Class&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Calling VBA from VSTO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next I want to create a button on the ribbon that will first call the GetData method, then select the first cell in Sheet1, and finally call the VBA function SumBelow. In order to call a VBA method from VSTO you call Globals.ThisWorkbook.Application.Run passing it the&lt;strong&gt; full name&lt;/strong&gt; to the VBA method. For this example that would be VBATest.xlsm!MyFunctions.SumBelow. &lt;/p&gt;

&lt;p&gt;Add a New Item to the project and select Office, Ribbon (Visual Designer) and then drag a Button from the Office Ribbon Controls to the Group and Label it “Get Data”. I also specified an OfficeImageId to make it look pretty. (BTW, a nice way to browse the Office Images is to &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9&amp;amp;displaylang=en" target="_blank"&gt;install the VSTO Power Tools&lt;/a&gt; and install the RibbonID Add-in like &lt;a href="http://msdn.microsoft.com/en-us/vsto/dd229920.aspx" target="_blank"&gt;Ty shows in this video&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_14.png" target="_blank"&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/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb_6.png" width="675" height="400" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Double-click on the Get Data button to add a click event handler and we’ll write the following code to load all the data and then call the VBA function. You need to make sure you set up proper error handling here because if the VBA function is removed or renamed the code here will fail. This code will also fail if the appropriate access is not granted to VBA macros in Excel. By default, VBA macros are not enabled but you can enable them on a per workbook basis (there’s a button at the top of the first sheet when you run it). This scenario assumes you have existing VBA code that has permission to run and you’re now calling those existing functions from VSTO.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;VBATest.NorthwindReportService
&lt;span style="color: blue"&gt;Imports &lt;/span&gt;Microsoft.Office.Tools.Ribbon

&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;Ribbon1

    &lt;span style="color: blue"&gt;Private Sub &lt;/span&gt;Button1_Click() &lt;span style="color: blue"&gt;Handles &lt;/span&gt;Button1.Click
        &lt;span style="color: green"&gt;'load the data from the service
        &lt;/span&gt;Globals.ThisWorkbook.GetData()
        &lt;span style="color: blue"&gt;Try
            &lt;/span&gt;&lt;span style="color: green"&gt;'Make sure the first cell is selected
            &lt;/span&gt;Globals.Sheet1.Range(&lt;span style="color: #a31515"&gt;&amp;quot;A1&amp;quot;&lt;/span&gt;).Select()
            &lt;span style="color: green"&gt;'Run the VBA function. This will result in a runtime error if the function 
            ' is removed or renamed or not allowed to run so make sure to provide &lt;br /&gt;            ' adequate error handling.             
            &lt;/span&gt;Globals.ThisWorkbook.Application.Run(&lt;span style="color: #a31515"&gt;&amp;quot;VBATest.xlsm!MyFunctions.SumBelow&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;Catch &lt;/span&gt;ex &lt;span style="color: blue"&gt;As &lt;/span&gt;Exception
            &lt;span style="color: green"&gt;'Todo: Error handling
            &lt;/span&gt;MsgBox(ex.ToString())
        &lt;span style="color: blue"&gt;End Try
    End Sub
End Class&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Hit F5 to run. If you see a Security Warning (the default) that Macros are disabled, then just click Options and select “Enable this content”. Select the Add-Ins tab on the Ribbon and click the GetData button to see the data get loaded from the service and then the SumBelow VBA function will be called which will auto-sum the SaleAmount field and show the total in the first row.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calling VSTO methods from VBA&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As you can see it’s really easy to call VBA code from your Office solution in Visual Studio (VSTO) but it’s also fragile because of the late-bound architecture and the requirement that macros be enabled for the Workbook. Like all late-bound code, you need to have adequate error handling to prevent crashes. Much less fragile is calling VSTO methods from VBA functions because these methods are compiled into your .NET assembly and exposed via COM-interop which makes them available to VBA. &lt;/p&gt;

&lt;p&gt;If we go back to our project and double-click on ThisWorkbook and look in the Properties window, you should see a property called EnableVbaCallers. Setting that Property to True will expose all Public methods in the ThisWorkbook class via COM to VBA. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_16.png" target="_blank"&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/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb_7.png" width="325" height="196" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you now go back into the code-behind for ThisWorkbook you will see some COM attributes added to the class:&lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;Microsoft.VisualBasic.ComClassAttribute()&amp;gt; _
&amp;lt;System.Runtime.InteropServices.ComVisibleAttribute(&lt;span style="color: blue"&gt;True&lt;/span&gt;)&amp;gt; _
&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;ThisWorkbook&lt;br /&gt;...&lt;/pre&gt;

&lt;p&gt;Now we can call the GetData method from VBA code. Hit F5 to run and enable the macros (if asked) on the Workbook again. Select the Developer tab and launch the Visual Basic editor. (If you don’t see a developer tab click the Office icon – the globe in the left-hand corner – select Excel Options, and then on the Popular tab check the “Show Developer tab in the Ribbon”.) &lt;/p&gt;

&lt;p&gt;Double-click on the ThisWorkbook and you will see that Visual Studio added a property to our VBA code for us called CallVSTOAssembly. This allows us to call any public method we defined in the ThisWorkbook class back in Visual Studio. Let’s add another function to the MyFunctions module that collects input from the user on the company name to look up and then fetches the data by calling the GetData method in .NET.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_20.png" target="_blank"&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/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb_9.png" width="686" height="392" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Save your code here and close the VBA Editor. Now back on the Developer tab on the Ribbon select Macros and then you should see the one we just wrote called GetDataAndSumBelow, select it and click Run. It will prompt for a company name (just type ‘S’ for instance) and it will run the ADO.NET Data Service query via the call to the .NET GetData method and then will return and call the SumBelow VBA function. Cool! &lt;/p&gt;

&lt;p&gt;BUT WAIT… DON’T CLOSE EXCEL YET! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips Editing VBA Code when Debugging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because we wrote the second VBA function above while we were in debug mode in Visual Studio once we close Excel we will lose all the VBA code we wrote when we debug again. &lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_22.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; margin: 5px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InteroptoVBAFunctionsFromYourVisualStudi_A978/image_thumb_10.png" width="284" height="360" /&gt;&lt;/a&gt;Because of the way Visual Studio works with Office solutions, we aren’t actually editing the xlsm file in the project, we’re editing the running xlsm file in the \bin directory that has the VSTO solution attached. You &lt;strong&gt;cannot &lt;/strong&gt;just copy this one in the \bin folder back into the project otherwise Visual Studio will report an error that a customization is already attached to the document when you compile again. So what do we do?&lt;/p&gt;

&lt;p&gt;There’s probably other ways to do this but what I found the easiest was to open the Visual Basic editor again, select the MyFunctions module where all my code is stored and then right-click and select “Export File”. This will allow you to save the code outside the Workbook. Then when you debug again you can just import it by right-clicking again (delete the current one first). &lt;/p&gt;

&lt;p&gt;When you’re finally satisfied with your VBA – VSTO code interop, close Visual Studio and open the .xlsm file in the &lt;strong&gt;project directory&lt;/strong&gt; (not the \bin) and re-import your code again into that version. Then restart Visual Studio and it will be in there when you start debugging again. I find this easier than copying my code into the clipboard, closing VS, modifying the document, reopening VS every time. Just be aware of what version of the document you’re modifying when you tweak your VBA code and you should be OK.&lt;/p&gt;

&lt;p&gt;I’ve uploaded the code for this example onto Code Gallery so have a look: &lt;a title="http://code.msdn.microsoft.com/VBAVSTOInterop" href="http://code.msdn.microsoft.com/VBAVSTOInterop"&gt;http://code.msdn.microsoft.com/VBAVSTOInterop&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More Resources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For more information on VBA – VSTO interop with Visual Studio please check out the following resources:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163373.aspx" target="_blank"&gt;MSDN Magazine: Extend Your VBA Code With VSTO&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb931201.aspx" target="_blank"&gt;MSDN Article: VBA Interoperability with Visual Studio Tools for the Office System (3.0)&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb814696.aspx" target="_blank"&gt;Visual How To: Interoperability Between VBA and Visual Studio Tools for the Office System (3.0)&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vsto/cc178910.aspx" target="_blank"&gt;How Do I: Call VSTO Code from VBA?&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vsto/cc748594.aspx"&gt;How Do I: Enable an Office Application Add-In using a VSTO Add-in?&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9918383" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/ADO.NET+Data+Services/default.aspx">ADO.NET Data Services</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VBA/default.aspx">VBA</category></item><item><title>Building Occasionally Connected Smart Clients with WPF</title><link>http://blogs.msdn.com/bethmassi/archive/2009/11/02/building-occasionally-connected-smart-clients-with-wpf.aspx</link><pubDate>Mon, 02 Nov 2009 22:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9916434</guid><dc:creator>Beth Massi</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9916434.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9916434</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9916434</wfw:comment><description>&lt;p&gt;This month Dev Pro Connections has an article by Milind Lele on using Sync Services in a WPF application:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.devproconnections.com/tabId/180/itemId/4586/Building-Occasionally-Connected-Smart-Clients-with.aspx" target="_blank"&gt;Building Occasionally Connected Smart Clients with WPF&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;With Sync Services and Visual Studio 2008 you can visually design your local data cache and have it automatically synchronize your data with the backend remote database. So instead of figuring out your own caching mechanisms on the client, you can use SQL CE to store the local data and then use the sync framework to merge data with the backend.&lt;/p&gt;  &lt;p&gt;If you’re looking to improve scalability of your client applications then you should consider caching data that is read-only, user-specific, changes rarely, or can tolerate some staleness. ADO.NET Sync Services can really help here. &lt;/p&gt;  &lt;p&gt;You can catch more of Milind and team over on the VS Data Team Blog: &lt;a title="http://blogs.msdn.com/vsdata/" href="http://blogs.msdn.com/vsdata/"&gt;http://blogs.msdn.com/vsdata/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9916434" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category></item><item><title>History of Visual Studio</title><link>http://blogs.msdn.com/bethmassi/archive/2009/10/28/history-of-visual-studio.aspx</link><pubDate>Wed, 28 Oct 2009 20:07:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9914300</guid><dc:creator>Beth Massi</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9914300.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9914300</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9914300</wfw:comment><description>&lt;p&gt;I just started catching up on a cool series on Channel 9: &lt;a href="http://channel9.msdn.com/shows/VisualStudioDocumentary/" target="_blank"&gt;&lt;strong&gt;The Visual Studio Documentary&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://channel9.msdn.com/shows/VisualStudioDocumentary/The-Visual-Studio-Documentary-Part-One/" target="_blank"&gt;documentary kicks off&lt;/a&gt; by taking you back to the days of MS-DOS and Alan Cooper who originally sold Visual Basic to Bill Gates back in 1988. It has a lot of BASIC and Windows history and it’s pretty fun to watch. (How the heck did Huckaby get in that video?) ;-) It’s also cool to see the beginnings of how Microsoft fostered the developer community, realizing that it was super-important to create a developer ecosystem and support system. I’m sure glad they did :-). Dee Dee has some funny stories about some of the earliest “geek fests”. &lt;/p&gt;  &lt;p&gt;Last time I was up in Redmond I bumped into &lt;a href="http://blogs.msdn.com/ricom/default.aspx" target="_blank"&gt;Rico Mariani&lt;/a&gt;, Visual Studio Architect, and he mentioned to me that he had started a series of blog posts on &lt;a href="http://blogs.msdn.com/ricom/archive/tags/History+of+Visual+Studio/default.aspx" target="_blank"&gt;his history building Visual Studio&lt;/a&gt; as a follow-up to the documentary that takes a different perspective based on his history working on C/C++. I finally read through all of his posts recounting his memories building developer products at Microsoft. If you’ve ever chatted with Rico, you know what an amazingly personable, excited and approachable person he is and it really shows in his writing. He keeps you laughing and interested the whole time, I highly recommend reading them. Thanks, Rico!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/ricom/archive/tags/History+of+Visual+Studio/default.aspx" target="_blank"&gt;&lt;strong&gt;Rico Mariani: My History of Visual Studio&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I came from a different background (dbase), and not a Microsoft product until 1990 (they bought FoxPro). Always a data-based programmer I didn’t have much experience with C++ back then, and only a tiny bit of Visual Basic. (Why would I, VFP had LINQ and OOP in 1995 ;-)) &lt;/p&gt;  &lt;p&gt;I learned a lot about the colorful history of how Visual Studio came to be so if you have some time to spare check it out. And don’t forget to download the latest piece of history -- &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx" target="_blank"&gt;Visual Studio 2010 Beta 2&lt;/a&gt;. ;-)&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9914300" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2005/default.aspx">VS2005</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Community/default.aspx">Community</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2010/default.aspx">VS2010</category></item><item><title>XAML Power Toys Released for Visual Studio 2010</title><link>http://blogs.msdn.com/bethmassi/archive/2009/10/26/xaml-power-toys-released-for-visual-studio-2010.aspx</link><pubDate>Mon, 26 Oct 2009 23:25:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9913239</guid><dc:creator>Beth Massi</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9913239.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9913239</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9913239</wfw:comment><description>&lt;p&gt;I finally made my way back home from Europe and I’m still digging through all my email, newsletters, feeds, etc. But one of the items that grabbed my attention is this week &lt;a href="http://karlshifflett.wordpress.com/" target="_blank"&gt;Karl Shifflett&lt;/a&gt; released updated XAML Power Tools for Visual Studio 2008 as well as a new set for &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx" target="_blank"&gt;Visual Studio 2010&lt;/a&gt;:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;&lt;a href="http://karlshifflett.wordpress.com/2009/10/25/xaml-power-toys-for-visual-studio-2008-v5-0-0-1-released/" target="_blank"&gt;Updated: XAML Power Toys for Visual Studio 2008&lt;/a&gt;&lt;/strong&gt; v5.0.0001 &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;&lt;a href="http://karlshifflett.wordpress.com/2009/10/25/xaml-power-toys-for-visual-studio-2010-beta2/" target="_blank"&gt;New: XAML Power Toys for Visual Studio 2010 Beta2&lt;/a&gt;&lt;/strong&gt; v5.1.0001 - same features as the 2008 version above for Beta2.&amp;#160; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;&lt;a href="http://karlshifflett.wordpress.com/2009/10/25/xaml-power-toys-for-visual-studio-2010-beta2-cider-designer/" target="_blank"&gt;New: XAML Power Toys for Visual Studio 2010 Beta2 for Cider&lt;/a&gt;&lt;/strong&gt;&lt;u&gt;&lt;/u&gt; v1.0 - new product for the WPF Designer&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you’re not familiar with these tools, XAML Power Toys are Visual Studio Add-Ins that makes WPF &amp;amp; Silverlight developers much more productive especially for Line of Business applications. They contain form generation tools, Grid tools,&amp;#160; DataForm, DataGrid and ListView generation tools that really shorten the time it takes to lay out UI controls on a WPF form. Thanks Karl!&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9913239" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2010/default.aspx">VS2010</category></item><item><title>Merging Text &amp; Photos into a Word Document using Open XML SDK</title><link>http://blogs.msdn.com/bethmassi/archive/2009/09/24/merging-text-photos-into-a-word-document-using-open-xml-sdk.aspx</link><pubDate>Fri, 25 Sep 2009 00:55:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9899172</guid><dc:creator>Beth Massi</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9899172.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9899172</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9899172</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/09/23/mail-merging-into-a-single-word-document-using-xml-literals.aspx" target="_blank"&gt;Yesterday I posted&lt;/a&gt; about how we could create a letter generator (mail merge) that took data from a database to create a Word 2007 document using the System.IO.Packaging class. I showed how to take data from Northwind using a single LINQ query to create XDocument objects representing letters to customers and then create a single document of all the data using XML Literals. &lt;/p&gt; &lt;p&gt;Today I want to show how we can embed images into the documents as well as text. Since we’re using Northwind for this example, we’ll use the Employee.Photo field from that database. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Letter Template with Photo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The first thing to do is create a letter template with our field placeholders as well as an image placeholder. We’ll also need to insert a page break at the end because we’re going to merge all the letters into a single document for easy printing:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MergingTextPhotosintoaSingleWordDocument_E6F4/image_2.png" target="_blank"&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/bethmassi/WindowsLiveWriter/MergingTextPhotosintoaSingleWordDocument_E6F4/image_thumb.png" width="668" height="555"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;The next step is to grab the document.xml from this docx file. Because it’s an Open XML package, as I showed in &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/09/23/mail-merging-into-a-single-word-document-using-xml-literals.aspx" target="_blank"&gt;yesterday’s post&lt;/a&gt;, we can just rename this file with a .zip extension temporarily and drill into the word\document.xml. However, there’s an easier way to work with these packages by installing the &lt;a href="http://blogs.msdn.com/bethmassi/archive/2008/07/29/handy-visual-studio-add-in-to-view-office-2007-files.aspx" target="_blank"&gt;Open XML package editor&lt;/a&gt; Visual Studio add-in from the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9&amp;amp;displaylang=en" target="_blank"&gt;VSTO Power Tools download&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MergingTextPhotosintoaSingleWordDocument_E6F4/image_8.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MergingTextPhotosintoaSingleWordDocument_E6F4/image_thumb_3.png" width="457" height="327"&gt;&lt;/a&gt;Once you install the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9&amp;amp;displaylang=en" target="_blank"&gt;VSTO Power tools&lt;/a&gt;, save this template in your project. Then you can just double-click on the .docx file in the Solution Explorer and it will open the package editor (it also works with .pptx and .xslx files). Now you can drill into the document.xml directly in Visual Studio and inspect all the parts of the package easily. &lt;/p&gt; &lt;p&gt;The difference between this template and the template we used yesterday is there is an image imbedded into the document. So you will see an image embedded into the package in the media folder. This is referred to as an “image part”. This part is linked to the “main document part” which is the word\document.xml file. The Open XML package editor shows the links (relationships) to all the parts. When you look at the relationship properties you’ll see that it has a unique ID. This is the same ID that you will see in the main document part at the point where we embedded the image, in our case it’s set to &lt;strong&gt;rId4&lt;/strong&gt;. (I’ve omitted all the WordProccessingML for clarity):&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml &lt;/span&gt;&lt;span style="color: red"&gt;version&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;1.0&lt;/span&gt;" &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;" &lt;span style="color: red"&gt;standalone&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;yes&lt;/span&gt;"&lt;span style="color: blue"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:document ...&lt;br&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; ...&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:drawing&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; ...&lt;br&gt;&lt;/pre&gt;&lt;/span&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;              &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:graphic &lt;/span&gt;&lt;span style="color: red"&gt;xmlns:a&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://schemas.openxmlformats.org/drawingml/2006/main&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
              &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:graphicData &lt;/span&gt;&lt;span style="color: red"&gt;uri&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://schemas.openxmlformats.org/drawingml/2006/picture&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:pic &lt;/span&gt;&lt;span style="color: red"&gt;xmlns:pic&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://schemas.openxmlformats.org/drawingml/2006/picture&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
                  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:nvPicPr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:cNvPr &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;0&lt;/span&gt;" &lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;image1.png&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:cNvPicPr&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
                  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:nvPicPr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:blipFill&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:blip &lt;/span&gt;&lt;strong&gt;&lt;span style="color: red"&gt;r:embed&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;rId4&lt;/span&gt;"&lt;/strong&gt; &lt;span style="color: red"&gt;cstate&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;print&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:stretch&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:fillRect&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:stretch&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:blipFill&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:spPr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:xfrm&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:off &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;0&lt;/span&gt;" &lt;span style="color: red"&gt;y&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;0&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
                      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:ext &lt;/span&gt;&lt;span style="color: red"&gt;cx&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;1829055&lt;/span&gt;" &lt;span style="color: red"&gt;cy&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;2124372&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:xfrm&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:prstGeom &lt;/span&gt;&lt;span style="color: red"&gt;prst&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;rect&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
                      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:avLst&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:prstGeom&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:spPr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;pic:pic&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
              &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:graphicData&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;a:graphic&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; ...
          &lt;/span&gt;&lt;span style="color: blue"&gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:drawing&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; ...&lt;br&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:p &lt;/span&gt;&lt;span style="color: red"&gt;w:rsidR&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;00622A50&lt;/span&gt;" &lt;span style="color: red"&gt;w:rsidRDefault&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;00622A50&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:r&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:br &lt;/span&gt;&lt;span style="color: red"&gt;w:type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;page&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:r&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; ...&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;w:document&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;strong&gt;Installing the Open XML SDK&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As I mentioned yesterday, manipulating the package directly with the System.IO.Packaging classes gets a little bit tricky when you have to start adding embedded images and objects and linking them together. Instead, it’s easier to use the Open XML SDK to do this because it will handle linking new image parts we add to the package automatically for us. The SDK provides a strongly-typed way of accessing the parts in a package so it cuts down on the amount of code you have to write yourself.&amp;nbsp; Version 1.0 requires only .NET 2.0, Version 2 requires .NET 3.5 and uses LINQ to provide more functionality when querying the parts. This version is currently a CTP. For what we’re doing you can use either version but I have Version 2 installed. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=AD0B72FB-4A1D-4C52-BDB5-7DD7E816D046&amp;amp;displaylang=en" target="_blank"&gt;Download Open XML Format SDK 1.0&lt;/a&gt; 
&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&amp;amp;DisplayLang=en" target="_blank"&gt;Download Open XML Format SDK 2.0&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The assembly that is installed in the GAC when you install the SDK is called DocumentFormat.OpenXml.dll and you’ll need to add a project reference to this. When you distribute your application you can simply xcopy the assembly with your application for easy deployment. (After you add the reference, select it in the Server Explorer and then in the Properties window set Copy Local to True in order to have it outputted to the \bin folder when you build your application.)&lt;/p&gt;
&lt;p&gt;Now we can add the namespace imports we’ll be working with at the top of our program, including the DocumentFormat.OpenXml.Packaging namespace:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #b96464"&gt;xmlns:w&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;http://schemas.openxmlformats.org/wordprocessingml/2006/main&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.Xml
&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.IO
&lt;span style="color: blue"&gt;Imports &lt;/span&gt;DocumentFormat.OpenXml.Packaging&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;strong&gt;Modifying the Letter Class and LINQ Query to Get the Photo&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In order to create letters for our customers in the database, we want to end up with a collection of XDocuments with our data merged into them. I created a Letter class that has two properties, CustomerID As String and Document As XDocument. We’re also going to add a new property for the photo byte array called EmployeePhoto As Byte() and OrderID as Integer. Next we need to modify the query so that it selects the photo as well as add the above WordProcessingML into our XML Literal to specify where the image should appear in the document. Because the relationship IDs must be unique, I’m going to use the OrderID as the suffix for the relationship ID for each of the images we want to embed. Like before, we can use embedded expressions to merge the data into the right places in the XDocument. 
&lt;p&gt;(I’ve omitted all the XML with the embedded expressions for clarity, take a loot at &lt;a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=openxmlvb&amp;amp;DownloadId=7325"&gt;the code sample&lt;/a&gt; for the whole listing.) The bolded areas show the modified sections of the query:&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;letters = _
&lt;span style="color: blue"&gt;  From &lt;/span&gt;Order &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Orders _
&lt;span style="color: blue"&gt;  Join &lt;/span&gt;Employee &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Employees _
&lt;span style="color: blue"&gt;    On &lt;/span&gt;Order.EmployeeID &lt;span style="color: blue"&gt;Equals &lt;/span&gt;Employee.EmployeeID _
&lt;span style="color: blue"&gt;  Where &lt;/span&gt;Order.OrderDate &lt;span style="color: blue"&gt;IsNot Nothing AndAlso &lt;/span&gt;_
    Order.ShippedDate &lt;span style="color: blue"&gt;IsNot Nothing AndAlso &lt;/span&gt;_
    Order.ShippedDate.Value.Date &amp;gt;= #1/1/1998# _
&lt;span style="color: blue"&gt;  Let &lt;/span&gt;DateOrder = Order.OrderDate.Value.ToShortDateString _
&lt;span style="color: blue"&gt;  Let &lt;/span&gt;DateShip = Order.ShippedDate.Value.ToShortDateString _
&lt;span style="color: blue"&gt;  Select New &lt;/span&gt;Letter &lt;span style="color: blue"&gt;With &lt;/span&gt;{ _
    .CustomerID = Order.CustomerID, _&lt;br&gt;    &lt;strong&gt;.OrderID = Order.OrderID, _
&lt;br&gt;&lt;br&gt;&lt;br&gt;    .EmployeePhoto = &lt;span style="color: blue"&gt;If&lt;/span&gt;(Employee.Photo &lt;span style="color: blue"&gt;IsNot Nothing&lt;/span&gt;, Employee.Photo.ToArray, &lt;span style="color: blue"&gt;Nothing&lt;/span&gt;), _&lt;/strong&gt;
    .Document = &lt;span style="color: #6464b9"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #844646"&gt;xml &lt;/span&gt;&lt;span style="color: #b96464"&gt;version&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;1.0&lt;/span&gt;&lt;span style="color: #555555"&gt;" &lt;/span&gt;&lt;span style="color: #b96464"&gt;encoding&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;utf-8&lt;/span&gt;&lt;span style="color: #555555"&gt;" &lt;/span&gt;&lt;span style="color: #b96464"&gt;standalone&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;yes&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;?&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:document ... &lt;br&gt;&lt;/span&gt;&lt;span style="color: #6464b9"&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:body&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt; ...
&lt;/span&gt;&lt;span style="color: #6464b9"&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:p &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:rsidR&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;00A9498E&lt;/span&gt;&lt;span style="color: #555555"&gt;" &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:rsidRDefault&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;00A9498E&lt;/span&gt;&lt;span style="color: #555555"&gt;" &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:rsidP&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;00AA2EC6&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t &lt;/span&gt;&lt;span style="color: #b96464"&gt;xml:space&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;preserve&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #555555"&gt;If you have any issues please contact &lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:proofErr &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:type&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;spellStart&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;/&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background: #fffebf; color: #555555"&gt;&amp;lt;%=&lt;/span&gt; Employee.FirstName &amp;amp; &lt;span style="color: #a31515"&gt;" " &lt;/span&gt;&amp;amp; Employee.LastName &lt;span style="background: #fffebf; color: #555555"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:proofErr &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:type&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;spellEnd&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;/&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t &lt;/span&gt;&lt;span style="color: #b96464"&gt;xml:space&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;preserve&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt; &lt;/span&gt;&lt;span style="color: #555555"&gt;at&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:rsidR&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;005F35D6&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t &lt;/span&gt;&lt;span style="color: #b96464"&gt;xml:space&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;preserve&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt; &lt;/span&gt;&lt;span style="color: #555555"&gt;ext.&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t &lt;/span&gt;&lt;span style="color: #b96464"&gt;xml:space&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;preserve&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:rsidR&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;005F35D6&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background: #fffebf; color: #555555"&gt;&amp;lt;%=&lt;/span&gt; Employee.Extension &lt;span style="background: #fffebf; color: #555555"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:t&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:p&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt; ...
                        &lt;/span&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:drawing&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;&amp;gt; ...
&lt;/span&gt;&lt;span style="color: #6464b9"&gt;                            &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;pic:blipFill&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;&amp;gt; ...
                                &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;a:blip &lt;/span&gt;&lt;span style="color: #b96464"&gt;r:embed&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="background: #fffebf; color: #555555"&gt;&amp;lt;%=&lt;/span&gt; &lt;/strong&gt;&lt;span style="color: #a31515"&gt;"rId" &lt;/span&gt;&amp;amp; &lt;strong&gt;Order.OrderID &lt;span style="background: #fffebf; color: #555555"&gt;%&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;/&amp;gt; ...
&lt;/span&gt;&lt;span style="color: #6464b9"&gt;                        &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:drawing&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;&amp;gt; ...
&lt;/span&gt;&lt;span style="color: #6464b9"&gt;                        &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:p &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:rsidR&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;00622A50&lt;/span&gt;&lt;span style="color: #555555"&gt;" &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:rsidRDefault&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;00622A50&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                                &amp;lt;&lt;/span&gt;&lt;span style="color: #844646"&gt;w:br &lt;/span&gt;&lt;span style="color: #b96464"&gt;w:type&lt;/span&gt;&lt;span style="color: #6464b9"&gt;=&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;span style="color: #6464b9"&gt;page&lt;/span&gt;&lt;span style="color: #555555"&gt;"&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;/&amp;gt;
                            &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:r&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:p&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: #6464b9"&gt;&lt;strong&gt;&amp;gt; ...&lt;/strong&gt;
&lt;/span&gt;&lt;span style="color: #6464b9"&gt;                    &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:body&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: #844646"&gt;w:document&lt;/span&gt;&lt;span style="color: #6464b9"&gt;&amp;gt;&lt;/span&gt;}&lt;/pre&gt;
&lt;p&gt;The query returns an IEnumerable(Of Letter) objects with the Document property set to the document.xml data for that customer and the EmployeePhoto set to the photo byte array. If we wanted to create separate documents (which is exactly what I demonstrated in my &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/08/17/devproconnections-article-taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx" target="_blank"&gt;DevProConnections article&lt;/a&gt;) it’s actually pretty simple because all we need to do is copy the template and then replace the document.xml and the image data, we don’t have to mess with the relationship ID at all. However if we want to create a single document with all our letters we need to delete the placeholder image part and add new unique image parts for the Letter.EmployeePhoto. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Adding and Linking the Images into a Single Word Document&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Because relationship IDs must be unique in a document I used the OrderID as the embedded expression for the r:embed attribute in the XML Literal above. You can choose to use any unique ID you want but it must start with an alpha character, that’s why I prefixed it with “rId”. When you use the Open XML SDK to add the new image parts we have to specify the relationship ID to use. To update the code we wrote yesterday to work with the Open XML SDK and also work with images we first need to add a call to open the Word document template, grab the main document part and then delete the image part by calling DeletePart:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: green"&gt;'Place the letters in a separate directory
&lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;sourceFile = CurDir() &amp;amp; &lt;span style="color: #a31515"&gt;"\LetterTemplate.docx"
&lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;letterDir = CurDir() &amp;amp; &lt;span style="color: #a31515"&gt;"\Letters\"
&lt;/span&gt;&lt;span style="color: blue"&gt;My&lt;/span&gt;.Computer.FileSystem.CreateDirectory(letterDir)

&lt;span style="color: blue"&gt;Dim &lt;/span&gt;mergeFile = letterDir &amp;amp; &lt;span style="color: #a31515"&gt;"AllLetters.docx"
&lt;/span&gt;&lt;span style="color: blue"&gt;My&lt;/span&gt;.Computer.FileSystem.CopyFile(sourceFile, mergeFile, &lt;span style="color: blue"&gt;True&lt;/span&gt;)

&lt;span style="color: green"&gt;'Open the Document template using the Open XML SDK
&lt;/span&gt;&lt;span style="color: blue"&gt;Using &lt;/span&gt;wordDoc = WordprocessingDocument.Open(mergeFile, &lt;span style="color: blue"&gt;True&lt;/span&gt;)

&lt;span style="color: green"&gt;    'get the main document part (document.xml)
    &lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;mainPart = wordDoc.MainDocumentPart()

    &lt;span style="color: green"&gt;'Delete the placeholder image from the template so we can replace it with the real photos
    &lt;/span&gt;mainPart.DeletePart(&lt;span style="color: #a31515"&gt;"rId4"&lt;/span&gt;)&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This opens the Word document as read/write and then deletes the placeholder image. You should also notice at this point that the code is a bit simpler to open the package than yesterday because we don’t have to declare the relative URI’s or content types. The Open XML SDK helps us here. Next we need to load the document.xml into an XElement object and grab the body:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    Dim &lt;/span&gt;mainDocumentXML &lt;span style="color: blue"&gt;As &lt;/span&gt;XElement
    &lt;span style="color: blue"&gt;Using &lt;/span&gt;sr &lt;span style="color: blue"&gt;As New &lt;/span&gt;StreamReader(mainPart.GetStream)
        mainDocumentXML = XElement.Load(sr)
    &lt;span style="color: blue"&gt;End Using

    Dim &lt;/span&gt;mainBody = mainDocumentXML...&lt;span style="color: #6464b9"&gt;&amp;lt;&lt;/span&gt;w:body&lt;span style="color: #6464b9"&gt;&amp;gt;&lt;/span&gt;.First()
    &lt;span style="color: blue"&gt;Dim &lt;/span&gt;i = 0&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Now we can loop through all the letters, grab the body of those XDocuments and then add an image part. We need to specify the content type and the relationship ID that must match what we embedded in the XML Literal in our query. Then we can either replace the main document body with the first letter (overwrite our placeholder data) otherwise we append the rest of the letter contents into the document:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    For Each &lt;/span&gt;letter &lt;span style="color: blue"&gt;In &lt;/span&gt;letters
        &lt;span style="color: blue"&gt;Dim &lt;/span&gt;nextBody = letter.Document...&lt;span style="color: #6464b9"&gt;&amp;lt;&lt;/span&gt;w:body&lt;span style="color: #6464b9"&gt;&amp;gt;&lt;/span&gt;.First()
        &lt;span&gt;'Add the new imagePart. The SDK takes care of linking this properly.
       &lt;strong&gt; Dim &lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;imagePart = mainPart.AddImagePart(&lt;span style="color: #a31515"&gt;"image/png"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"rId" &lt;/span&gt;&amp;amp; letter.OrderID)&lt;/strong&gt;

        &lt;span style="color: blue"&gt;If &lt;/span&gt;i = 0 &lt;span style="color: blue"&gt;Then
           &lt;/span&gt;&lt;span style="color: green"&gt;'Replace the first body contents in the template
           &lt;/span&gt;mainBody.ReplaceNodes(nextBody.Elements())
        &lt;span style="color: blue"&gt;Else
           &lt;/span&gt;&lt;span style="color: green"&gt;'Otherwise append the next letter contents
           &lt;/span&gt;mainBody.Add(nextBody.Elements())
        &lt;span style="color: blue"&gt;End If&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Next we need to feed the byte array data into the ImagePart. Note that since I’m using Northwind for this example there is an OLE header on those images that we must strip off that is 78 bytes. If you are using your own images stored in SQL Server you won’t have to do that:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: green"&gt;        'Now feed the byte array into the ImagePart
        &lt;/span&gt;&lt;span style="color: blue"&gt;If &lt;/span&gt;letter.EmployeePhoto &lt;span style="color: blue"&gt;IsNot Nothing Then
            &lt;/span&gt;&lt;span style="color: green"&gt;'Using ms As New System.IO.MemoryStream(letter.EmployeePhoto.ToArray)
            'NOTE: Northwind Photos have an OLE header on them that we must strip off.
            ' You don't have to do this if you are using your own SQL-server stored images
            &lt;/span&gt;&lt;span style="color: blue"&gt;Using &lt;/span&gt;ms &lt;span style="color: blue"&gt;As New &lt;/span&gt;System.IO.MemoryStream(letter.EmployeePhoto, 78, _
                                                   letter.EmployeePhoto.Length - 78)
                imagePart.FeedData(ms)
            &lt;span style="color: blue"&gt;End Using
        End If

        &lt;/span&gt;i += 1
    &lt;span style="color: blue"&gt;Next&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Now that we’ve built up the document XML, added our image parts and linked them properly, the final step is to replace the document part with our XML just like before:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: green"&gt;    'Replace the document part with our XML
    &lt;/span&gt;&lt;span style="color: blue"&gt;Using &lt;/span&gt;sw &lt;span style="color: blue"&gt;As New &lt;/span&gt;StreamWriter(mainPart.GetStream(FileMode.Create))
        mainDocumentXML.Save(sw)
    &lt;span style="color: blue"&gt;End Using

End Using&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Now when we run the application you will see a single document with all the letters, including photos, that’s much easier to print than multiple files. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MergingTextPhotosintoaSingleWordDocument_E6F4/image_12.png" target="_blank"&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/bethmassi/WindowsLiveWriter/MergingTextPhotosintoaSingleWordDocument_E6F4/image_thumb_5.png" width="687" height="255"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There’s Always Room for Improvement&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LINQ &amp;amp; Northwind savvy folks may notice that I’m actually creating duplicates of the employee photos. Since I’m flattening out the data in my query to have 1 photo per order there could be an unnecessary amount of duplicate images. This can cause the document to get bloated. To be more efficient we should reuse the relationship ID’s to the images if they are the same on multiple orders. One approach would be to modify the LINQ query and Letter object to select the EmployeePhoto and then have a collection of order &amp;amp; document data under that. I’ll leave that experiment up to you :-)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=openxmlvb&amp;amp;DownloadId=7325" target="_blank"&gt;Take a look at the full code listing for this example&lt;/a&gt; as well as the &lt;a href="http://code.msdn.microsoft.com/openxmlvb" target="_blank"&gt;complete project with other Open XML examples here on Code Gallery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899172" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/XML/default.aspx">XML</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VSTO/default.aspx">VSTO</category></item><item><title>Mail Merging Into a Single Word Document Using XML Literals</title><link>http://blogs.msdn.com/bethmassi/archive/2009/09/23/mail-merging-into-a-single-word-document-using-xml-literals.aspx</link><pubDate>Thu, 24 Sep 2009 02:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9898711</guid><dc:creator>Beth Massi</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9898711.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9898711</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9898711</wfw:comment><description>&lt;P&gt;With the release of Microsoft Office 2007 we can work with a much simpler, standard, XML format called &lt;A href="http://www.ecma-international.org/publications/standards/Ecma-376.htm" target=_blank mce_href="http://www.ecma-international.org/publications/standards/Ecma-376.htm"&gt;Open XML&lt;/A&gt; which opens the door for many types of applications that cannot work via COM. What if you needed to build a scalable web service that processes many documents in high volume? What if you wanted to quickly read or write to these formats from a client application but wanted to have minimal dependencies on other applications? These types of programs do not want to require Microsoft Office be installed to run. The cool thing is you have the tools already with Visual Basic 2008. XML Literals are an easy way to manipulate any kind of XML, including Open XML.&lt;/P&gt;
&lt;P&gt;I’ve written before on how to use XML Literals to manipulate Word documents, if you missed them:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/08/17/devproconnections-article-taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2009/08/17/devproconnections-article-taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx"&gt;&lt;STRONG&gt;DevProConnections Article: Taking Advantage of LINQ and XML in Microsoft Office 2007&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Sample: &lt;A href="http://code.msdn.microsoft.com/openxmlvb" mce_href="http://code.msdn.microsoft.com/openxmlvb"&gt;Working with Open XML in Visual Basic&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/02/12/oba-part-3-storing-and-reading-data-in-word-documents.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2009/02/12/oba-part-3-storing-and-reading-data-in-word-documents.aspx"&gt;OBA Part 3 - Storing and Reading Data in Word Documents&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/07/30/accessing-openxml-document-parts-with-the-openxml-sdk.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2008/07/30/accessing-openxml-document-parts-with-the-openxml-sdk.aspx"&gt;Accessing Open XML Document Parts with the Open XML SDK&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2007/12/06/mail-merging-with-word-and-linq-to-xml-in-vb.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2007/12/06/mail-merging-with-word-and-linq-to-xml-in-vb.aspx"&gt;Mail Merging with Word, LINQ and XML Literals in VB&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;If you aren’t familiar with XML Literals or Open XML then I’d suggest reading the article &lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/08/17/devproconnections-article-taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/08/17/devproconnections-article-taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx"&gt;in the first bullet above&lt;/A&gt; first. It’s a great intro into XML Literals, Open XML and it also demonstrates a couple practical ways of reading and writing to Word document formats directly. &lt;/P&gt;
&lt;P&gt;Recently I got a great question on how to change the program outlined in the &lt;A href="http://blogs.msdn.com/bethmassi/archive/2007/12/06/mail-merging-with-word-and-linq-to-xml-in-vb.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2007/12/06/mail-merging-with-word-and-linq-to-xml-in-vb.aspx"&gt;last bullet above&lt;/A&gt; to merge letters we were creating on the fly from a database into a single document instead of multiple documents like we’re doing. This would make it much easier for an end user to print them. That’s such an obvious thing I can’t believe I didn’t think of that! For those of you that aren’t familiar with what we did I’ll give a quick recap of that application. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Creating Word Documents with XML Literals&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;What I wanted to do is take all the Customers in the Northwind database who had some orders shipping today and send them thank you letters. To get started I created a new Word 2007 document with the letter text and some placeholder field names to indicate where I want the data:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MailMergingaSingleWordDocumentUsingXMLLi_C84D/image_6.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MailMergingaSingleWordDocumentUsingXMLLi_C84D/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/bethmassi/WindowsLiveWriter/MailMergingaSingleWordDocumentUsingXMLLi_C84D/image_thumb_2.png" width=687 height=385 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MailMergingaSingleWordDocumentUsingXMLLi_C84D/image_thumb_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Save the document (I named it Doc1.docx) and then rename the .docx extension to .zip and you can drill into the package and see a bunch of XML documents inside it. If we drill down through the zip file we'll see that the text we just typed is located in the \word\document.xml file. Copy this xml and paste it into the Visual Basic editor, it will infer it as an XDocument object, and then you can use embedded expressions to replace the placeholders. (If I’ve lost you, &lt;A href="http://blogs.msdn.com/bethmassi/archive/2007/12/06/mail-merging-with-word-and-linq-to-xml-in-vb.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2007/12/06/mail-merging-with-word-and-linq-to-xml-in-vb.aspx"&gt;read this article which explains it step-by-step&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;In order to create letters for our customers in the database, we want to end up with a collection of XDocuments with our data merged into them. I created a simple class called Letter that has two properties, CustomerID As String and Document As XDocument. Then I wrote a LINQ query to select the data and embed it into the document (I’ve omitted all the WordProcessingML for clarity, take a loot at &lt;A href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=openxmlvb&amp;amp;DownloadId=7325" target=_blank mce_href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=openxmlvb&amp;amp;DownloadId=7325"&gt;the code sample&lt;/A&gt; for the whole listing.)&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;letters = _
&lt;SPAN style="COLOR: blue"&gt;    From &lt;/SPAN&gt;Order &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;db.Orders _
&lt;SPAN style="COLOR: blue"&gt;    Join &lt;/SPAN&gt;Employee &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;db.Employees _
&lt;SPAN style="COLOR: blue"&gt;        On &lt;/SPAN&gt;Order.EmployeeID &lt;SPAN style="COLOR: blue"&gt;Equals &lt;/SPAN&gt;Employee.EmployeeID _
&lt;SPAN style="COLOR: blue"&gt;    Where &lt;/SPAN&gt;Order.OrderDate &lt;SPAN style="COLOR: blue"&gt;IsNot Nothing AndAlso &lt;/SPAN&gt;_
        Order.ShippedDate &lt;SPAN style="COLOR: blue"&gt;IsNot Nothing AndAlso &lt;/SPAN&gt;_
        Order.ShippedDate.Value.Date &amp;gt;= #1/1/2007# _
&lt;SPAN style="COLOR: blue"&gt;    Let &lt;/SPAN&gt;DateOrder = Order.OrderDate.Value.ToShortDateString _
&lt;SPAN style="COLOR: blue"&gt;    Let &lt;/SPAN&gt;DateShip = Order.ShippedDate.Value.ToShortDateString _
&lt;SPAN style="COLOR: blue"&gt;    Select New &lt;/SPAN&gt;Letter &lt;SPAN style="COLOR: blue"&gt;With &lt;/SPAN&gt;{ _
        .CustomerID = Order.Customer.CustomerID, _
        .Document = &lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;?&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;xml &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;version&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;1.0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;" &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;encoding&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;utf-8&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;" &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;standalone&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;yes&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;?&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:document &lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;...&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:p &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidR&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00705CFF&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;" &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidRDefault&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00112228&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;" &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidP&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00AA2EC6&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:br&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;/&amp;gt;
        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidR&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;007A5236&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;xml:space&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;preserve&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;Dear &lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:proofErr &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;spellStart&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;/&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="BACKGROUND: #fffebf; COLOR: #555555"&gt;&amp;lt;%=&lt;/SPAN&gt; Order.Customer.ContactName &lt;SPAN style="BACKGROUND: #fffebf; COLOR: #555555"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:proofErr &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;spellEnd&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;/&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidR&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00AA2EC6&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
                &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;,&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
     &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:p&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;     &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:p &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidR&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00E04FB0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;" &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidRDefault&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00AA2EC6&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;" &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidP&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00AA2EC6&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;xml:space&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;preserve&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;We’d like to inform you that the order you placed on &lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:proofErr &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;spellStart&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;/&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidR&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00112228&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
                &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="BACKGROUND: #fffebf; COLOR: #555555"&gt;&amp;lt;%=&lt;/SPAN&gt; DateOrder &lt;SPAN style="BACKGROUND: #fffebf; COLOR: #555555"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:proofErr &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;spellEnd&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;/&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidR&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00806521&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
                &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;xml:space&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;preserve&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;has shipped on &lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:proofErr &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;spellStart&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;/&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidR&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00112228&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
                &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="BACKGROUND: #fffebf; COLOR: #555555"&gt;&amp;lt;%=&lt;/SPAN&gt; DateShip &lt;SPAN style="BACKGROUND: #fffebf; COLOR: #555555"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:t&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
            &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
... &lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:document&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The query returns an IEnumerable(Of Letter) objects with the Document property set to the document.xml data for that customer. The next step involved taking the template Doc1.docx file, making a copy of it and then simply replacing the document.xml part inside the package with the one here in the Letter class for each letter. However, what I did was create separate letters for each customer. Instead we want to create one .docx file with &lt;STRONG&gt;ALL&lt;/STRONG&gt; the letter data merged inside. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Merging into a Single Word Document&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The first thing we need to do is insert a page break between all our letters. The easiest thing to do is to open back up your template Doc1.docx file in Word and insert a page break, save it, and then look at the document.xml again in the package. You should see this WordProccessingML element inserted near the end:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:p &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidR&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00622A50&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;" &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:rsidRDefault&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;00622A50&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:br &lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;w:type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;page&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;/&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:r&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:p&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Paste this into the query above in the document exactly where you pulled it out of the document.xml. &lt;/P&gt;
&lt;P&gt;Next we have a couple options on how to manipulate the package (docx file). I’ve shown &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/07/30/accessing-openxml-document-parts-with-the-openxml-sdk.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/07/30/accessing-openxml-document-parts-with-the-openxml-sdk.aspx"&gt;how to use the Open XML SDK before to manipulate documents&lt;/A&gt; but in this simple case we can use the System.IO.Packaging classes directly. This is because all we’re doing is working with text in the document. If we were working with images or embedded objects it would be easier to use the SDK. In the next post we’ll add photos of the employees on each order into the document, but for this post let’s just focus on how to merge the text. &lt;/P&gt;
&lt;P&gt;So the first thing we need to do is Import some namespaces including an XML namespace that we’re going to use:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #b96464"&gt;xmlns:w&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;http://schemas.openxmlformats.org/wordprocessingml/2006/main&lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.IO
&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.IO.Packaging&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;Next we need to set up some variables and copy the Doc1.docx template to a new file I’m calling AllLetters.docx.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;uri &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;Uri(&lt;SPAN style="COLOR: #a31515"&gt;"/word/document.xml"&lt;/SPAN&gt;, UriKind.Relative)
&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;contentType = &lt;SPAN style="COLOR: #a31515"&gt;"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;sourceFile = CurDir() &amp;amp; &lt;SPAN style="COLOR: #a31515"&gt;"\Doc1.docx"
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;letterDir = CurDir() &amp;amp; &lt;SPAN style="COLOR: #a31515"&gt;"\Letters\"
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;My&lt;/SPAN&gt;.Computer.FileSystem.CreateDirectory(letterDir)

&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;mergeFile = letterDir &amp;amp; &lt;SPAN style="COLOR: #a31515"&gt;"AllLetters.docx"
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;My&lt;/SPAN&gt;.Computer.FileSystem.CopyFile(sourceFile, mergeFile, &lt;SPAN style="COLOR: blue"&gt;True&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now we can open the template package and load the main document part as an XElement:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Using &lt;/SPAN&gt;p &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;Package = Package.Open(mergeFile)

&lt;SPAN style="COLOR: green"&gt;    'get the main document part (document.xml)
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;mainPart = p.GetPart(uri)
    &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;mainDocumentXML &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;XElement&lt;BR&gt;
&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;    &lt;SPAN style="COLOR: blue"&gt;Using &lt;/SPAN&gt;sr &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;StreamReader(mainPart.GetStream)
        mainDocumentXML = XElement.Load(sr)
    &lt;SPAN style="COLOR: blue"&gt;End Using&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The next part is where it gets fun. A word document has a top element structure like this:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:document&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:body&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
       &lt;/SPAN&gt;&lt;SPAN style="COLOR: #555555"&gt;...
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:body&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;
&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #844646"&gt;w:document&lt;/SPAN&gt;&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;So what we need to do is grab the body of the template, replace it with the first customer’s document body we have and then append the rest of the elements inside the bodies of the rest of the documents. A word document can only have one &amp;lt;w:body&amp;gt; element for it to be legal. The way we get the &amp;lt;w:body&amp;gt; XElement from the document is using the descendants syntax with the three dot notation (…): &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;    Dim &lt;/SPAN&gt;mainBody = mainDocumentXML...&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;&lt;/SPAN&gt;w:body&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;.First()
    &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;i = 0

    &lt;SPAN style="COLOR: blue"&gt;For Each &lt;/SPAN&gt;letter &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;letters
        &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;nextBody = letter.Document...&lt;SPAN style="COLOR: #6464b9"&gt;&amp;lt;&lt;/SPAN&gt;w:body&lt;SPAN style="COLOR: #6464b9"&gt;&amp;gt;&lt;/SPAN&gt;.First()
        &lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;i = 0 &lt;SPAN style="COLOR: blue"&gt;Then
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'Replace the first body contents in the template
            &lt;/SPAN&gt;mainBody.ReplaceNodes(nextBody.Elements())
        &lt;SPAN style="COLOR: blue"&gt;Else
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'Append the new contents for the rest of the customers
            &lt;/SPAN&gt;mainBody.Add(nextBody.Elements())
        &lt;SPAN style="COLOR: blue"&gt;End If
        &lt;/SPAN&gt;i += 1
    &lt;SPAN style="COLOR: blue"&gt;Next&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Now that we’ve built up the right body with all our letter data in it, we can replace the main document.xml part in the package and close it.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;    'Delete the current document.xml file in the template
    &lt;/SPAN&gt;p.DeletePart(uri)
    &lt;SPAN style="COLOR: green"&gt;'Replace that part with our new merged XDocument
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;replace &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;PackagePart = p.CreatePart(uri, contentType)&lt;BR&gt;
    &lt;SPAN style="COLOR: blue"&gt;Using &lt;/SPAN&gt;sw &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;StreamWriter(replace.GetStream())
        mainDocumentXML.Save(sw)
        sw.Close()
    &lt;SPAN style="COLOR: blue"&gt;End Using

&lt;/SPAN&gt;    p.Close()
&lt;SPAN style="COLOR: blue"&gt;End Using&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Now when we run this, all the letters will be mail merged into the same document for easy printing:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MailMergingaSingleWordDocumentUsingXMLLi_C84D/image_4.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MailMergingaSingleWordDocumentUsingXMLLi_C84D/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/bethmassi/WindowsLiveWriter/MailMergingaSingleWordDocumentUsingXMLLi_C84D/image_thumb_1.png" width=703 height=253 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MailMergingaSingleWordDocumentUsingXMLLi_C84D/image_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;As I mentioned if we have embedded images or objects that we need to replace it gets a little trickier. In the &lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/08/17/devproconnections-article-taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2009/08/17/devproconnections-article-taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx"&gt;DevProConnections Article&lt;/A&gt; I have an example of how to create multiple documents with embedded pictures of the employee’s photo. In the next post I’ll show you how we can use the &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&amp;amp;DisplayLang=en" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&amp;amp;DisplayLang=en"&gt;Open XML SDK&lt;/A&gt; to create a single document with embedded pictures as well. &lt;/P&gt;
&lt;P&gt;Until then, have a look &lt;A href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=openxmlvb&amp;amp;DownloadId=7325" target=_blank mce_href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=openxmlvb&amp;amp;DownloadId=7325"&gt;at the complete code I put up on Code Gallery&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;[UPDATE:&amp;nbsp;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/09/24/merging-text-photos-into-a-word-document-using-open-xml-sdk.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2009/09/24/merging-text-photos-into-a-word-document-using-open-xml-sdk.aspx"&gt;Merging Text &lt;STRONG&gt;&amp;amp; Photos &lt;/STRONG&gt;into a Word Document using Open XML SDK&lt;/A&gt;]&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9898711" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/XML/default.aspx">XML</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Office/default.aspx">Office</category></item><item><title>Inserting Master-Detail Data into a SQL-Server Compact Edition Database</title><link>http://blogs.msdn.com/bethmassi/archive/2009/09/15/inserting-master-detail-data-into-a-sql-server-compact-edition-database.aspx</link><pubDate>Wed, 16 Sep 2009 05:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9895646</guid><dc:creator>Beth Massi</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9895646.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9895646</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9895646</wfw:comment><description>&lt;P&gt;Yesterday John posted on the &lt;A href="http://blogs.msdn.com/vsdata/default.aspx" mce_href="http://blogs.msdn.com/vsdata/default.aspx"&gt;Visual Studio Data&lt;/A&gt; blog how to &lt;A href="http://blogs.msdn.com/vsdata/archive/2009/09/14/refresh-the-primary-key-identity-column-during-insert-operation.aspx" mce_href="http://blogs.msdn.com/vsdata/archive/2009/09/14/refresh-the-primary-key-identity-column-during-insert-operation.aspx"&gt;Refresh the Primary Key Identity Column during an Insert Operation&lt;/A&gt; using SQL Server. In that post he shows how the DataSet designer sets up a batch Insert statement to retrieve identity keys automatically. A while back &lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/05/14/using-tableadapters-to-insert-related-data-into-an-ms-access-database.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/05/14/using-tableadapters-to-insert-related-data-into-an-ms-access-database.aspx"&gt;I wrote about how to insert data into an Access database using TableAdapters and identity keys&lt;/A&gt;. Because Access doesn’t support batch statements, the Visual Studio Dataset designer doesn’t generate the code to retrieve the identity on new rows, so you end up having to write a bit of code yourself to do this as I showed in that post. &lt;/P&gt;
&lt;P&gt;Since then I’ve had similar questions about how to do the same thing but using a SQL CE (Compact Edition) database so I thought I’d present the updated code to work with this type of database. Let’s take a look at how to do that, but first some background. (If you don’t care, just skip to the end for the code and &lt;A href="http://code.msdn.microsoft.com/InsertSQLCE/" target=_blank mce_href="http://code.msdn.microsoft.com/InsertSQLCE/"&gt;sample download&lt;/A&gt; ;-))&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What is SQL-Server Compact Edition (SQL CE)?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/ms172448.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms172448.aspx"&gt;SQL CE&lt;/A&gt; is a file-based, single-user database that is really handy to use as local storage for your client applications because of its small footprint. And it’s included with Visual Studio 2008. &lt;A href="http://msdn.microsoft.com/en-us/library/ms172417.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms172417.aspx"&gt;Check out what’s new in SQL CE 3.5 here&lt;/A&gt;. One very typical use of SQL CE is as a local data cache to your SQL Server backend data using sync services in order to create an &lt;A href="http://msdn.microsoft.com/en-us/library/bb384572.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb384572.aspx"&gt;occasionally connected application&lt;/A&gt;. You can &lt;A href="http://msdn.microsoft.com/en-us/library/cc281959.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/cc281959.aspx"&gt;learn about the sync framework here&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/en-us/library/bb384585.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb384585.aspx"&gt;how to create a local data cache in Visual Studio 2008 here&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Setting up Parent-Child Tables and Relationships in SQL CE 3.5 Using Visual Studio 2008&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To add a local database file to your Visual Studio 2008 project just select Add –&amp;gt; New Item, choose the Data category and then select Local Database. This will add a SQL CE database file with an .sdf extension to your project.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_2.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/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/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb.png" width=681 height=410 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;This will trigger the Data Sources wizard to start but first we need to create some tables in our database so cancel the wizard. Next open up the Server Explorer (or Database Explorer if you are using VS Express) and you should see your SQL CE database listed under Data Connections. Expand the database node and then right-click on Tables and select &lt;STRONG&gt;New Table&lt;/STRONG&gt;. A dialog will open that allows you to design your table schema. &lt;/P&gt;
&lt;P&gt;For this example I’ll create a parent Categories table and a child Products table with just a few fields to illustrate the concepts here. It’s important when you create a primary key that you choose the &lt;STRONG&gt;int&lt;/STRONG&gt; data type, set Unique to &lt;STRONG&gt;Yes&lt;/STRONG&gt; and then below in the column properties you set Identity to &lt;STRONG&gt;True&lt;/STRONG&gt;. This will create an auto-incrementing, unique primary key. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_6.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/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/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_2.png" width=681 height=556 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Click OK when you’re done and then repeat the same process to add a new Products table. This time though we need to specify a field for the CategoryID foreign key and I’m going to make this a required field by setting Allow Nulls to &lt;STRONG&gt;No&lt;/STRONG&gt;. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_8.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/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/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_3.png" width=679 height=551 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_3.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now we need to add a relationship between these tables so that our little database will maintain referential integrity for us. We’re saying that a Product cannot exist without specifying a Category. We want the database to enforce this so that if we try to delete a Category it will prevent us from doing so if there are any Products. SQL CE 3.5 can maintain this kind of referential integrity for us, just go back to the Server Explorer and right-click on the Products table again but this time select &lt;STRONG&gt;Table Properties&lt;/STRONG&gt;. Select the &lt;STRONG&gt;Add Relations &lt;/STRONG&gt;page.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_10.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/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/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_4.png" width=713 height=581 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_4.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Type in the name of the relation you want to create and then select the Foreign Key Table Column, in my case I select CategoryID. Notice that you can also set up cascading or set null/default update and delete rules as well, but for this example we want to leave the rules as NO ACTION. Click Add Columns button then Add Relations button then click OK to save and close. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Setting up the Parent-Child DataSet &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Now that we have the database set up we can design our DataSet. This is going to be almost exactly the same as &lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/05/14/using-tableadapters-to-insert-related-data-into-an-ms-access-database.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/05/14/using-tableadapters-to-insert-related-data-into-an-ms-access-database.aspx"&gt;how we set up our Access DataSet here&lt;/A&gt; so take a look at that post for the screen-shots, they’ll be the same here. To recap, you need to make sure you set up the relationship on the DataSet properly so that the primary key on the parent will cascade to the foreign key on the child. Right click on the relation in the DataSet designer and select "Both Relation and Foreign Key Constraint" and then set the Update and Delete rules to &lt;STRONG&gt;Cascade&lt;/STRONG&gt;. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_12.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_12.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px 20px 0px 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image align=left src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_5.png" width=228 height=341 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_5.png"&gt;&lt;/A&gt;The other important thing you need to do is set the Primary Key fields on both DataTables to ReadOnly &lt;STRONG&gt;False&lt;/STRONG&gt;. We need to do this so we can set them in code and have the DataRelation cascade rules work correctly.&lt;/P&gt;
&lt;P&gt;The DataSet designer will set all the rest of the properties and statements up correctly so you don’t have to modify anything else, though I do encourage you to take a look through them. One important thing to notice is the AutoIncrement, AutoIncrementSeed and AutoIncrementStep properties here. These are set to True, –1 and –1 respectively. This means that on the DataSet (client side) the referential integrity on new rows is maintained between the products and categories DataTables using temporary primary keys that are negative integers. &lt;STRONG&gt;These do NOT correspond to the keys in the database for new rows.&lt;/STRONG&gt; It’s not until we send the updates to the database that we get the real identity keys so keep that in mind. (And these properties are the same regardless if you are using SQL CE, Access, or SQL Server identity keys.)&lt;/P&gt;
&lt;P&gt;Okay so now we are ready to design our master-detail form. This should be a familiar process at this point but just in case here’s a recap. Open the Data Sources window (Main Menu –&amp;gt; Data –&amp;gt; Show Data Sources) and you should see the Categories and Products DataTables that are in the DataSet we just created. Design your Master-Detail form like normal. For this example I drag the Categories as details and then select the &lt;EM&gt;related &lt;/EM&gt;Products by expanding the Categories node and dragging the Products table under there. This will set up a relationship on the form as well so that when we select a Category, it will only show those related products. This is also important to get our inserts to work correctly because the temporary identity key (-1, –2, –3, etc) on the CategoryID will automatically cascade to the Product’s CategoryID. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_16.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_16.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/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_7.png" width=675 height=380 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_7.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Loading and Editing the Parent-Child DataSet&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Now that the DataSet is set to enforce the foreign key relationships, this means that you &lt;STRONG&gt;must&lt;/STRONG&gt; have a parent for every child so you have to load the data in parent then child order. Remember, you have to &lt;STRONG&gt;make sure that every row in the child DataTable will have a corresponding parent row in the parent DataTable&lt;/STRONG&gt;. This also means that you have to make sure to call EndEdit on any new parent BindingSource before any children can be added. I’m doing this by adding a handler to the grid’s Enter event. So the code-behind for this form is the same as the &lt;A href="http://code.msdn.microsoft.com/AccessDataVS/" target=_blank mce_href="http://code.msdn.microsoft.com/AccessDataVS/"&gt;Access sample I showed before&lt;/A&gt;:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Public Class &lt;/SPAN&gt;Form1

    &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;CategoriesBindingNavigatorSaveItem_Click() _&lt;BR&gt;                &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;CategoriesBindingNavigatorSaveItem.Click
        &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Validate()
        &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.CategoriesBindingSource.EndEdit()
        &lt;SPAN style="COLOR: green"&gt;'Make sure to call EndEdit on all BindingSources before an update
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.ProductsBindingSource.EndEdit()
        &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.TableAdapterManager.UpdateAll(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MyDatabaseDataSet)
    &lt;SPAN style="COLOR: blue"&gt;End Sub

    Private Sub &lt;/SPAN&gt;Form1_Load() &lt;SPAN style="COLOR: blue"&gt;Handles MyBase&lt;/SPAN&gt;.Load
        &lt;SPAN style="COLOR: green"&gt;'Load parent before child because contraints are enabled on the DataSet
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.CategoriesTableAdapter.Fill(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MyDatabaseDataSet.Categories)
        &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.ProductsTableAdapter.Fill(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MyDatabaseDataSet.Products)
    &lt;SPAN style="COLOR: blue"&gt;End Sub
   
    Private Sub &lt;/SPAN&gt;ProductsDataGridView_Enter() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;ProductsDataGridView.Enter
        &lt;SPAN style="COLOR: green"&gt;'You must commit the parent row to the DataTable before adding child rows 
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.CategoriesBindingSource.EndEdit()
    &lt;SPAN style="COLOR: blue"&gt;End Sub
End Class&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;&lt;STRONG&gt;Adding Code to Handle Inserts to SQL CE Databases&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;We need a way to set the primary key on the parent right after the row is inserted into the database and before any children are inserted. Now that we have keys cascading we just need to write code to handle the RowUpdated event on the DataAdapter inside the TableAdapter partial class. TableAdapters are generated classes that Visual Studio creates for us from the DataSet designer. These classes are declared as &lt;A href="http://msdn.microsoft.com/en-us/library/yfzd5350.aspx" mce_href="http://msdn.microsoft.com/en-us/library/yfzd5350.aspx"&gt;Partial Classes&lt;/A&gt; so that means we can add code to the same class even if it’s in a separate file. Right-click on the TableAdapter class in the DataSet Designer and select View Code and the partial class file that you can edit will be created for you.&lt;/P&gt;
&lt;P&gt;Now we can write code to automatically query the database for the identity key because SQL CE supports the @@IDENTITY command just like Access. We need to execute this query after each &lt;STRONG&gt;new &lt;/STRONG&gt;row has been inserted into the database, but before any children. If you’re using Visual Studio 2008 then the TableAdapterManager will handle sending parents first then children for insert operations so all we need to do is handle the DataAdapter’s RowUpdated event. Here’s the complete code listing for the DataSet and TableAdapter partial classes which includes code to set default values on the new rows. Notice it’s very similar to the Access code.&amp;nbsp; We’re just working with a different data access client library by importing the System.Data.SqlServerCe instead of System.Data.OleDb.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.Data.SqlServerCe

&lt;SPAN style="COLOR: blue"&gt;Public Class &lt;/SPAN&gt;SQLCEIDHelper
    &lt;SPAN style="COLOR: green"&gt;''' &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;''' Retrieves the primary key auto-number identity values from SQL CE
    ''' &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;''' &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Public Shared Sub &lt;/SPAN&gt;SetPrimaryKey(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;trans &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;SqlCeTransaction, _
                                    &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;e &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;SqlCeRowUpdatedEventArgs)

        &lt;SPAN style="COLOR: green"&gt;' If this is an INSERT operation...
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;e.Status = UpdateStatus.Continue &lt;SPAN style="COLOR: blue"&gt;AndAlso &lt;/SPAN&gt;_
           e.StatementType = StatementType.Insert &lt;SPAN style="COLOR: blue"&gt;Then
            Dim &lt;/SPAN&gt;pk = e.Row.Table.PrimaryKey
            &lt;SPAN style="COLOR: green"&gt;' and a primary key PK column exists...
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;pk &lt;SPAN style="COLOR: blue"&gt;IsNot Nothing AndAlso &lt;/SPAN&gt;pk.Count = 1 &lt;SPAN style="COLOR: blue"&gt;Then
                &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'Set up the post-update query to fetch new @@Identity
                &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;cmdGetIdentity &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;SqlCeCommand(&lt;SPAN style="COLOR: #a31515"&gt;"SELECT @@IDENTITY"&lt;/SPAN&gt;, _
                                                       &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(trans.Connection, SqlCeConnection), _
                                                       trans)
                
                &lt;SPAN style="COLOR: green"&gt;'Execute the command and set the result identity value to the PK
                &lt;/SPAN&gt;e.Row(pk(0)) = &lt;SPAN style="COLOR: blue"&gt;CInt&lt;/SPAN&gt;(cmdGetIdentity.ExecuteScalar)
                e.Row.AcceptChanges()

            &lt;SPAN style="COLOR: blue"&gt;End If
        End If
    End Sub
End Class

Namespace &lt;/SPAN&gt;MyDatabaseDataSetTableAdapters
    &lt;SPAN style="COLOR: blue"&gt;Partial Public Class &lt;/SPAN&gt;CategoriesTableAdapter
        &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;_adapter_RowUpdated(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;sender &lt;SPAN style="COLOR: blue"&gt;As Object&lt;/SPAN&gt;, _
                                        &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;e &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;SqlCeRowUpdatedEventArgs) _
                                        &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;_adapter.RowUpdated

            SQLCEIDHelper.SetPrimaryKey(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Transaction, e)
        &lt;SPAN style="COLOR: blue"&gt;End Sub
    End Class

    Partial Public Class &lt;/SPAN&gt;ProductsTableAdapter
        &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;_adapter_RowUpdated(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;sender &lt;SPAN style="COLOR: blue"&gt;As Object&lt;/SPAN&gt;, _
                                        &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;e &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;SqlCeRowUpdatedEventArgs) _
                                        &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;_adapter.RowUpdated

            SQLCEIDHelper.SetPrimaryKey(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Transaction, e)
        &lt;SPAN style="COLOR: blue"&gt;End Sub
    End Class
End Namespace

Partial Class &lt;/SPAN&gt;MyDatabaseDataSet
    &lt;SPAN style="COLOR: blue"&gt;Partial Class &lt;/SPAN&gt;CategoriesDataTable
        &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;CategoriesDataTable_TableNewRow(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;sender &lt;SPAN style="COLOR: blue"&gt;As Object&lt;/SPAN&gt;, _
                                            &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;e &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;System.Data.DataTableNewRowEventArgs) _
                                            &lt;SPAN style="COLOR: blue"&gt;Handles Me&lt;/SPAN&gt;.TableNewRow
            &lt;SPAN style="COLOR: green"&gt;'Set defaults so that constraints don't fail when EndEdit is called
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;cat = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(e.Row, CategoriesRow)
            cat.CategoryName = &lt;SPAN style="COLOR: #a31515"&gt;"[new]"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End Sub
    End Class

    Partial Class &lt;/SPAN&gt;ProductsDataTable
        &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;ProductsDataTable_TableNewRow(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;sender &lt;SPAN style="COLOR: blue"&gt;As Object&lt;/SPAN&gt;, _
                                             &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;e &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;System.Data.DataTableNewRowEventArgs) _
                                             &lt;SPAN style="COLOR: blue"&gt;Handles Me&lt;/SPAN&gt;.TableNewRow
            &lt;SPAN style="COLOR: green"&gt;'Set defaults so that constraints don't fail when EndEdit is called
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;product = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(e.Row, ProductsRow)
            product.ProductName = &lt;SPAN style="COLOR: #a31515"&gt;"[new]"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End Sub
    End Class
End Class&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now when we run our form, click the Add button on the ToolStrip to add a new Category and then enter new Products in the DataGridView below. Click Save and you will see the identity keys refresh back into the DataTables from our SQL CE database. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_18.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_18.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/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_8.png" width=580 height=333 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/InsertingMasterDetailDataintoaSQLServerC_C610/image_thumb_8.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;So to recap:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create your SQL CE tables, set the PKs to an Identity Integer column and then set up the relation to enforce referential integrity&lt;/LI&gt;
&lt;LI&gt;Create your DataSet and edit the relation and set it to a “Relation and Foreign Key Constraint” then set the Update and Delete rules to Cascade&lt;/LI&gt;
&lt;LI&gt;Make sure the PKs on the DataTables in the designer are set ReadOnly False&lt;/LI&gt;
&lt;LI&gt;Make sure to design your form so that the parent and &lt;EM&gt;related &lt;/EM&gt;children BindingSources are set up properly&lt;/LI&gt;
&lt;LI&gt;Call EndEdit on the ParentBindingSource before you attempt to insert any child rows into the child DataTable so that the parent row is committed to the parent DataTable&lt;/LI&gt;
&lt;LI&gt;Use the TableAdapterManager to handle updating parents and children in proper order (this happens by default if you use the designer)&lt;/LI&gt;
&lt;LI&gt;Add a handler to the DataAdapter’s RowUpdated event to query the database for the new identity (SELECT @@IDENTITY) and set the PK on the DataRow to that value and this will cascade to any related children automatically&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;A href="http://code.msdn.microsoft.com/InsertSQLCE/" target=_blank mce_href="http://code.msdn.microsoft.com/InsertSQLCE/"&gt;&lt;STRONG&gt;Download the sample application from Code Gallery.&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;I hope that clears up the confusion on how to work with file-based databases like Access and SQL CE that don’t support batch statements. Once you understand how ADO.NET is working with your DataSets then it’s much easier to understand how to configure things like this. SQL CE is a great FREE database for single-user applications and I encourage you to have a look at it if you’re building these types of client applications. &lt;/P&gt;
&lt;P&gt;SQL CE also supports the Entity Framework so that would probably be a good follow-up post to this one… next time! ;-)&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9895646" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category></item><item><title>“Moving in” to Windows 7: My Favorite Features &amp; Some Tips on Setup</title><link>http://blogs.msdn.com/bethmassi/archive/2009/09/01/moving-in-to-windows-7-my-favorite-features-some-tips-on-setup.aspx</link><pubDate>Wed, 02 Sep 2009 03:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9890150</guid><dc:creator>Beth Massi</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9890150.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9890150</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9890150</wfw:comment><description>&lt;P&gt;Last week I installed Windows 7 Enterprise on my main laptop – a Lenovo T60p ThinkPad. I was up in Redmond and MSIT made it available via a super-easy network boot that installs Office Enterprise, all the IT-required software like anti-virus, and all the drivers you need automatically. (I can’t say enough great things about MSIT but that’s another post.) It took about an hour and a half and I was cooking with gas. &lt;/P&gt;
&lt;P&gt;Like moving into a new apartment, moving into a new operating system can take a little time to see the awesomeness as well as understand the quirks. Now that I’ve been doing my “normal work routine” on it for a week I thought I’d post some of my favorite features of this OS as well as share some tips when I was setting up my system and installing programs like Visual Studio and SQL Server 2008.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;3 Favorite Windows 7 Features&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;My #1 favorite feature&lt;/STRONG&gt;, hands down, is being able to boot from a VHD. You can create Windows 7 or Windows 2008 RC Server images via Hyper-V, run sysprep on them, and then copy them to your hard drive. Then you use bcdedit to put an entry in your boot menu and Windows will happily boot right into it like normal. You can even access all your files from the image just like it was another partition. Plus, since my laptop supports 64-bit I can create 32 and 64-bit images and boot from any of them. Now when I am testing or demoing Visual Studio 2010 &amp;amp; Office/SharePoint 2010 it will be almost as fast as if I installed on the metal. Yippie! (I say almost, but I only noticed a bit of sluggishness on startup.)&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.technet.com/aviraj/archive/2009/01/18/windows-7-boot-from-vhd-first-impression-part-2.aspx" target=_blank mce_href="http://blogs.technet.com/aviraj/archive/2009/01/18/windows-7-boot-from-vhd-first-impression-part-2.aspx"&gt;Here’s the instructions I used to set it up.&lt;/A&gt; Many thanks to &lt;A href="http://blogs.technet.com/aviraj" target=_blank mce_href="http://blogs.technet.com/aviraj"&gt;Aviraj&lt;/A&gt; for this information and thanks to my co-worker Sam for pointing me to it :-)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;My #2 favorite feature &lt;/STRONG&gt;is the window docking. Scott Hanselman showed me this at Denver code camp in the beginning of the year. Take any window and drag it near the left or right of your screen and it will dock there, filling up exactly half the screen. This is super helpful if you don’t have two monitors (like on a laptop) but need to see the contents of two windows at once. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_2.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/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/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb.png" width=683 height=427 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;If you drag the window to the top of the screen it will automatically maximize. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;My #3 favorite feature &lt;/STRONG&gt;is that the Taskbar buttons combine and preview, especially for IE browser windows, but it works for any application. In the picture below (click to enlarge) my mouse is hovering over the IE icon on the taskbar and Windows 7 automatically previews all the open windows &lt;STRONG&gt;and tabs. &lt;/STRONG&gt;Here I have three browser windows open and 11 tabs total:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_6.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/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/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb_2.png" width=684 height=77 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb_2.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Clicking the taskbar icon also does the same thing if there are multiple previews. When you hover over the previews, the full size window will come into view. It’s a really nice feature when you have a lot of windows open for a particular program. However, especially with IE, sometimes you just want to open any of them so you can navigate somewhere else. If you Ctrl+click then it will open the last window you accessed. If you Shift+click then it will open a new instance of the program. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Taskbar Tips&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In the pictures above you may have noticed I have a “&lt;STRONG&gt;Quick Launch Bar&lt;/STRONG&gt;” (at least that’s what it was called in Vista) next to the Start menu. In Windows 7 there’s no such thing so you have to create it yourself. Right-click the Taskbar, select Toolbars, New Toolbar… and that will open a dialog that wants you to select a folder. That seemed a bit odd to me but I played along and selected somewhere in my Documents library. Name the folder whatever you want, like MyToolbar. Now there’s some text on your Taskbar called MyToolbar next to your system tray. Clicking on it does nothing. Hmmm. &lt;/P&gt;
&lt;P&gt;Well it turns out what you need to do is go back into that folder you created and start adding shortcuts! Right-click on MyToolbar, select Open Folder, and then you can start right-dragging and creating shortcuts to all your favorite programs. Now you will see a little double left arrow next to MyToolbar and clicking it will show all your shortcuts: &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_10.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_10.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb_4.png" width=247 height=213 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb_4.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;In order to get the toolbar to look like the old Quick Launch you need to right-click on the Taskbar and uncheck “Lock the Taskbar”. Then you can right-click on MyToolbar and uncheck “Show Text” and “Show Title”: &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_12.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_12.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px 10px 0px 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb_5.png" width=248 height=241 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb_5.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Now since the Taskbar is unlocked you can stretch out the toolbar and move it to where you want. If you want it on the left then slide it all the way past the Taskbar icons then slide the Taskbar icons back to where you want them. When you’re done, lock the Taskbar again and you should be a happy camper. &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;“Show Desktop” on the Left&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;One thing that annoys me about the Taskbar is that you can’t move the Show Desktop which is now at the end of the Taskbar on the right (the black box). I’ve tried for a week to train myself to go to the right instead of the left (like where it was in XP and Vista) but it’s been too many years of my brain on those OSes so I can’t break the habit. &lt;/P&gt;
&lt;P&gt;If you’re like me and want the Show Desktop on the left next to the Start menu then create a toolbar like I showed above. Next, open up Notepad and write the following Explorer commands:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;[Shell] &lt;BR&gt;Command=2 &lt;BR&gt;IconFile=explorer.exe,3 &lt;BR&gt;[Taskbar] &lt;BR&gt;Command=ToggleDesktop&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Then save the file in the the toolbar folder you created and name it “Show Desktop.scf” (use the quotes in Notepad’s Save dialog so that it doesn’t append the txt extension). Now you can move it on your toolbar all the way to the left and all will be right with the world (or at least your Taskbar):&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_14.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/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/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb_6.png" width=213 height=59 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/MyFavoriteWindows7FeaturesSoFar_C3AA/image_thumb_6.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Tips on Installing Visual Studio and SQL Server 2008&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;There is a known compatibility issue with SQL Server 2008 and Windows 7 that is fixed with &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=66AB3DBB-BF3E-4F46-9559-CCC6A4F9DC19&amp;amp;displaylang=en" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=66AB3DBB-BF3E-4F46-9559-CCC6A4F9DC19&amp;amp;displaylang=en"&gt;Service Pack 1&lt;/A&gt;. So if you are installing SQL Server 2008 (any version including Express) then you’ll get a compatibility warning. You can just click past it but then make sure you install Service Pack 1 right away (also available via Windows Update). &lt;A href="http://blogs.msdn.com/petersad/archive/2009/08/11/sql-server-on-windows-7.aspx" target=_blank mce_href="http://blogs.msdn.com/petersad/archive/2009/08/11/sql-server-on-windows-7.aspx"&gt;See this post for details on SQL Server Setup on Windows 7&lt;/A&gt;. You’ll also want to do the same thing for Visual Studio 2008, install &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=FBEE1648-7106-44A7-9649-6D9F6D58056E&amp;amp;displaylang=en" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=FBEE1648-7106-44A7-9649-6D9F6D58056E&amp;amp;displaylang=en"&gt;Service Pack 1&lt;/A&gt;. You’ll need to do this because if SQL Server SP1 is installed then Visual Studio will need to also have SP1 installed. Finally, make sure you head to Windows Update to get any other latest fixes. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The Windows API Code Pack &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To wrap up this Windows 7 post, I’ll leave you with a link to the &lt;A href="http://code.msdn.microsoft.com/WindowsAPICodePack" target=_blank mce_href="http://code.msdn.microsoft.com/WindowsAPICodePack"&gt;Windows API Code Pack&lt;/A&gt; that’s been featured on the &lt;A href="http://msdn.com/vbasic" target=_blank mce_href="http://msdn.com/vbasic"&gt;Visual Basic Developer Center&lt;/A&gt; for a few weeks now. This pack provides a source code library that can be used to access Windows features from managed code and includes 20+ samples in Visual Basic and C#. &lt;A href="http://www.hanselman.com/blog/TheWeeklySourceCode45KickingButtOnWindows7AndWindowsXP.aspx" target=_blank mce_href="http://www.hanselman.com/blog/TheWeeklySourceCode45KickingButtOnWindows7AndWindowsXP.aspx"&gt;Scott Hanselman digs into it this week&lt;/A&gt;. It looks like a pretty easy way to take advantage of Windows 7 features in your .NET applications. &lt;/P&gt;
&lt;P mce_keep="true"&gt;Enjoy Windows 7!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9890150" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Windows+7/default.aspx">Windows 7</category></item><item><title>New “How Do I” Videos Released on Entity Framework &amp; WPF</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/26/new-how-do-i-videos-released-on-entity-framework-wpf.aspx</link><pubDate>Wed, 26 Aug 2009 20:18:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9885620</guid><dc:creator>Beth Massi</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9885620.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9885620</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9885620</wfw:comment><description>&lt;p&gt;Yesterday we released a couple more videos onto the &lt;a href="http://msdn.com/vbasic"&gt;Visual Basic Developer Center&lt;/a&gt; on building WPF data-entry forms with Entity Framework:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/ee364700.aspx"&gt;How Do I: Hook Up and Display Validation in WPF using Entity Framework?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/ee364701.aspx"&gt;How Do I: Build a WPF Master-Detail Data Entry Form Using Entity Framework?&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That makes 5 videos total on &lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#wpfentity"&gt;working with EF in WPF applications&lt;/a&gt;. Others released previously:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776537.aspx"&gt;How Do I: Get Started with Entity Framework in WPF Applications?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776540.aspx"&gt;How Do I: Build a WPF Data Entry Form Using Entity Framework?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776544.aspx"&gt;How Do I: Create a WPF Lookup Combobox using Entity Framework?&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These videos are based on articles I’ve posted here in the past. So if you like reading better that watching videos here you go:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/04/30/data-binding-wpf-lookup-combobox-values-to-ef-entities.aspx"&gt;Data Binding WPF Lookup Combobox Values to EF Entities&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx"&gt;Notifying the UI when Entity References Change in Lookup Comboboxes&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx"&gt;Using the WPF ObservableCollection with EF Entities&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/07/07/implementing-validation-in-wpf-on-entity-framework-entities.aspx"&gt;Implementing Validation in WPF on Entity Framework Entities&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/07/14/master-detail-data-binding-in-wpf-with-entity-framework.aspx"&gt;Master-Detail Data Binding in WPF with Entity Framework&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/07/16/filtering-entity-framework-collections-in-master-detail-forms.aspx"&gt;Filtering Entity Framework Collections in Master-Detail Forms&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are also additional resources listed on the How Do I video pages themselves pointing to topics in the MSDN Library.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9885620" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Videos/default.aspx">Videos</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Using the ReportViewer with ADO.NET Data Services and Entity Framework</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/19/using-the-reportviewer-with-ado-net-data-services-and-entity-framework.aspx</link><pubDate>Thu, 20 Aug 2009 07:57:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9876342</guid><dc:creator>Beth Massi</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9876342.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9876342</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9876342</wfw:comment><description>&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/ms251671.aspx" target="_blank"&gt;Winforms ReportViewer&lt;/a&gt; in Visual Studio Pro will allow you define client reports with a variety of data sources. If you’re not familiar with creating client-side reports using the ReportViewer, take a look at these videos:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/ee309360.aspx" target="_blank"&gt;How Do I: Create a report from a database?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd638039.aspx" target="_blank"&gt;How Do I: Create a report from a business object?&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;(The ReportViewer can also display server-based reports a la SQL Reporting Services and has a whole boatload of features that I’m not going to talk about here. For more information on this freely redistributable control, please read &lt;a href="http://msdn.microsoft.com/en-us/library/ms251671.aspx" target="_blank"&gt;ReportViewer Controls (Visual Studio)&lt;/a&gt; in the MSDN library.)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" target="_blank"&gt;ADO.NET Data Services&lt;/a&gt; was released with &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&amp;amp;displaylang=en" target="_blank"&gt;Visual Studio 2008 SP1&lt;/a&gt; and is basically a framework for exposing your data models via RESTful web services. So if you are building a remote CRUD data access layer then this is a technology that will make that super-simple, especially if you just want to expose a few data entities as read-only report sources. (I’ve written a lot about how to use ADO.NET Data Services in a variety of ways &lt;a href="http://blogs.msdn.com/bethmassi/archive/tags/ADO.NET+Data+Services/Article/default.aspx" target="_blank"&gt;so check out these posts if you’re interested&lt;/a&gt;.) Entity Framework was released at the same time and you can use EF as the data model behind your ADO.NET Data Service and expose it easily. If you’ve never created one before, &lt;a href="http://msdn.microsoft.com/en-us/library/cc668796.aspx" target="_blank"&gt;check out this quick start here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What’s the Problem?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you’ve ever tried to use the ReportViewer to design a client-side report with an &lt;a href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" target="_blank"&gt;ADO.NET Data Service&lt;/a&gt; data source (or use an &lt;a href="http://msdn.microsoft.com/en-us/library/bb738482.aspx" target="_blank"&gt;Entity Data Model&lt;/a&gt; directly) you may be disappointed. If you try to design a new report, the wizard may crash Visual Studio when selecting an entity. Yikes! &lt;/p&gt;  &lt;p&gt;Let me show you what I mean, but don’t try this at home. I have an ADO.NET Data Service based on the Northwind database &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx" target="_blank"&gt;&lt;strong&gt;like the one I created here&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;and &lt;a href="http://msdn.microsoft.com/en-us/library/cc668796.aspx" target="_blank"&gt;in the quick start&lt;/a&gt;. I then added a Windows Forms client project to the same solution (File –&amp;gt; Add –&amp;gt; New Project, then select Windows Forms App). Now open Form1 in the client and from the toolbox under the Reporting tab, drop the Microsoft ReportViewer control onto the form and from the smart tag select “Design a New Report”. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="176" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb.png" width="429" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This will open the Report Wizard. The first thing I need to do is tell it what data source to use, so I’ll select Service and click Next. This will open the Add Service Reference dialog box where I can &lt;a href="http://msdn.microsoft.com/en-us/library/cc668183.aspx" target="_blank"&gt;add the reference to my data service&lt;/a&gt; and Visual Studio will generate the proxy objects for me. In this example my service is in the same solution as the client so I can just click the Discover button and Visual Studio will see it. I named it NorthwindService. Click OK then click Finish. &lt;/p&gt;  &lt;p&gt;At this point I’m brought back to the Report Wizard:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_8.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; margin: 0px 15px 0px 0px; border-left: 0px; border-bottom: 0px" height="392" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_3.png" width="433" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Hmmmm…. I’m a little lost at this point because -- didn’t I just select the data source? Why don’t I see it?&lt;/p&gt;  &lt;p&gt;Maybe I should have added the service reference first from the Solution Explorer instead of through the Report Wizard? You can do that and you’ll get to the same screen at this point.&lt;/p&gt;  &lt;p&gt;So okay, I’ll click the Add Data Source button that’s calling to me. Granted, I like clicking buttons that have the ellipsis (…) on them because I’m always curious to see what’s under them, but this seems redundant.&lt;/p&gt;  &lt;p&gt;This opens the same dialog as before but this time I’ll choose Object instead of Service. I’m choosing object this time because I’m going to try and bind to the client proxy types that were generated for me when I added the service reference. After selecting Object, click Next and expand the service namespace.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_12.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; margin: 0px 10px 0px 0px; border-left: 0px; border-bottom: 0px" height="334" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_5.png" width="434" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;For this report I want to just display a list of Customers in the system so I’ll select Customers and then click Next. &lt;/p&gt;  &lt;p&gt;Then… then…… are you ready?… you better sit down for this…. click Finish……. wait for it…. wait for it….. not responding…. uh ohhhh….. &lt;/p&gt;  &lt;p&gt;Visual Studio has encountered a problem and needs to close. Darn!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_14.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="134" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_6.png" width="247" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now that was fun. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How Do I Fix this?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Unfortunately the Report Wizard in Visual Studio 2008 doesn’t know how to work with many-to-many relationships and that’s exactly what we have defined in our EF Entity Data Model which is what is backing our ADO.NET Data Service. Customers have many CustomerDemographics and vice versa in Northwind. You can actually define a couple classes yourself manually and create a many-to-many association between them:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;Class1

    &lt;span style="color: blue"&gt;Private &lt;/span&gt;_class2 &lt;span style="color: blue"&gt;As &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Class2)
    &lt;span style="color: blue"&gt;Public ReadOnly Property &lt;/span&gt;Class2() &lt;span style="color: blue"&gt;As &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Class2)
        &lt;span style="color: blue"&gt;Get
            Return &lt;/span&gt;_class2
        &lt;span style="color: blue"&gt;End Get
    End Property

End Class

Public Class &lt;/span&gt;Class2

    &lt;span style="color: blue"&gt;Private &lt;/span&gt;_class1 &lt;span style="color: blue"&gt;As &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Class1)
    &lt;span style="color: blue"&gt;Public ReadOnly Property &lt;/span&gt;Class1() &lt;span style="color: blue"&gt;As &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Class1)
        &lt;span style="color: blue"&gt;Get
            Return &lt;/span&gt;_class1
        &lt;span style="color: blue"&gt;End Get
    End Property

End Class&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Try to use either class above as the data source of the report and it will crash too. Woah! So when the report designer tries to read these associations I’m guessing it gets into an infinite loop walking the association references back and forth and then it crashes. So it’s not an error with the generated proxy objects per se, the root cause is our object model. If I would have chosen Categories instead, it would have worked. &lt;/p&gt;

&lt;p&gt;So what do we do? We could create another layer of classes without the associations on both sides if we wanted and then use those types instead but then we’d have to write code that IMO is pretty useless, just to shape the data again how we want on the client. &lt;/p&gt;

&lt;p&gt;My recommendation is to create a separate data model for your reports that doesn’t have many-to-many associations at all. You’re going to end up with a lot of different looking entities anyways for your reports because they will most likely pull from multiple database Views and/or stored procedures. You’ll always be displaying one side of the many-to-many relationship on paper anyways. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a Reporting Data Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So let’s go back to the data service project and add a new Entity Data Model to the web project called NorthwindReport. This time I’ll just select the Customers, Orders and Order Details and all the Views defined in the database. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_16.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="434" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_7.png" width="449" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Next I’ll add the ADO.NET Data Service and call it NorthwindReport and configure it so that we’re only allowing read-only access to our data by setting the entity access rule like so:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.Data.Services
&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.Linq
&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.ServiceModel.Web

&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;NorthwindReport
    &lt;span style="color: blue"&gt;Inherits &lt;/span&gt;DataService(&lt;span style="color: blue"&gt;Of &lt;/span&gt;NorthwindReportEntities)

    &lt;span style="color: blue"&gt;Public Shared Sub &lt;/span&gt;InitializeService(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;config &lt;span style="color: blue"&gt;As &lt;/span&gt;IDataServiceConfiguration)
        config.SetEntitySetAccessRule(&lt;span style="color: #a31515"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;, EntitySetRights.&lt;strong&gt;AllRead&lt;/strong&gt;)
    &lt;span style="color: blue"&gt;End Sub
End Class&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Now back on the client we can add the service reference to this service instead. After we add the service reference we can run the Report Wizard again by selecting “Design a New Report” smart tag on the ReportViewer control like I showed in the beginning. Select Object as the data source (or Service if you didn’t add the service reference first, then you’ll have to click “Add Data Sources…” again and then select Object) and you should see the list of entities exposed in the NorthwindReport data model. Now when we select Customer, we don’t have a problem.&lt;/p&gt;

&lt;p&gt;Design the report how you like (&lt;a href="http://msdn.microsoft.com/en-us/library/bb558708.aspx" target="_blank"&gt;see the documentation for more details&lt;/a&gt;) by clicking through the wizard and then go back to the smart tag on the ReportViewer and you should see the report you just created in the dropdown. Next go to the code-behind for the form and in the Load handler we just set the BindingSource.DataSource property to the results of the ADO.NET Data Service LINQ query:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;NorthwindClient.NorthwindReportService

&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;Form1

    &lt;span style="color: blue"&gt;Private Sub &lt;/span&gt;Form1_Load() &lt;span style="color: blue"&gt;Handles MyBase&lt;/span&gt;.Load
        &lt;span style="color: green"&gt;'TODO: put in My.Settings
        &lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;uri &lt;span style="color: blue"&gt;As New &lt;/span&gt;Uri(&lt;span style="color: #a31515"&gt;&amp;quot;http://localhost:1933/NorthwindReport.svc/&amp;quot;&lt;/span&gt;)
        &lt;span style="color: green"&gt;'Create the service reference
        &lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;db &lt;span style="color: blue"&gt;As New &lt;/span&gt;NorthwindReportEntities(uri)

        &lt;span style="color: green"&gt;'Set the report's DataSource to the results of the query
        &lt;/span&gt;&lt;span style="color: blue"&gt;Me&lt;/span&gt;.BindingSource.DataSource = &lt;span style="color: blue"&gt;From &lt;/span&gt;c &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Customers _
                                      &lt;span style="color: blue"&gt;Where &lt;/span&gt;c.Country = &lt;span style="color: #a31515"&gt;&amp;quot;USA&amp;quot; &lt;/span&gt;_
                                      &lt;span style="color: blue"&gt;Order By &lt;/span&gt;c.CompanyName

        &lt;span style="color: blue"&gt;Me&lt;/span&gt;.ReportViewer1.RefreshReport()
    &lt;span style="color: blue"&gt;End Sub
End Class&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Now hit F5 to run this baby and you’ll see the report pull the data from the service and display in the form:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_18.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="352" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_8.png" width="557" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recap &amp;amp; Resources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ADO.NET Data Services are a great way to quickly and easily expose data on the web, especially if it’s just read-only data used for remote reporting clients. The key to using the ReportViewer with ADO.NET Data Services (or an Entity Data Model directly, or even your own object model) is to make sure there are &lt;strong&gt;no &lt;/strong&gt;many-to-many associations on the entities. Here are the resources you need to get started with ReportViewer and ADO.NET Data Services:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc668796.aspx" target="_blank"&gt;Data Service Quick Start (ADO.NET Data Services Framework)&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc668183.aspx" target="_blank"&gt;How to: Add, Update, or Remove an ADO.NET Service Reference&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms251704.aspx" target="_blank"&gt;Configuring ReportViewer for Local Processing&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb558708.aspx" target="_blank"&gt;Report Designer (Visual Studio)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9876342" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/ADO.NET+Data+Services/default.aspx">ADO.NET Data Services</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Reporting/default.aspx">Reporting</category></item><item><title>DevProConnections Article: Taking Advantage of LINQ and XML in Microsoft Office 2007</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/17/devproconnections-article-taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx</link><pubDate>Mon, 17 Aug 2009 20:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9879123</guid><dc:creator>Beth Massi</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9879123.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9879123</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9879123</wfw:comment><description>&lt;p&gt;This month I have an article on DevProConnections:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;a href="http://www.devproconnections.com/tabId/180/itemId/4575/Taking-Advantage-of-LINQ-and-XML-in-Microsoft-Offi.aspx" target="_blank"&gt;Taking Advantage of LINQ and XML in Microsoft Office 2007&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In this article, I talk about how a lot of applications that need to take advantage of Microsoft Office can do so without going through COM. Many programs that need to process documents often require manipulation of the file formats directly and doing that through the Office component object model won’t scale very well. It also requires that Microsoft Office be installed to run. A better route in a lot of these cases is to use the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&amp;amp;DisplayLang=en" target="_blank"&gt;Open XML SDK&lt;/a&gt;. With the release of Office 2007, Word documents, Excel spreadsheets and PowerPoint presentations are based on an open standard for packaging XML files called Open XML. Using Visual Basic’s powerful and simple implementation of LINQ to XML you can work with these new document formats much easier than ever before.&lt;/p&gt;  &lt;p&gt;I show a couple practical examples of reading data from Word documents and updating a database as well as reading data from a database to create Word documents – all without COM. No Office applications need to be installed in order to read and write to these formats directly.&amp;#160; &lt;/p&gt;  &lt;p&gt;This article is based on the two episodes I did on DnrTV:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/04/07/dnrtv-showing-off-the-open-xml-sdk-and-linq.aspx"&gt;dnrTV: Showing off the Open XML SDK and LINQ&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/04/20/dnrtv-more-fun-with-office-and-xml-literals.aspx"&gt;dnrTV: More Fun with Office and XML Literals&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;[UPDATE: Here's code samples (also includes a presentation pptx)] &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://code.msdn.microsoft.com/openxmlvb"&gt;Working with Open XML in Visual Basic&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;More resources:&lt;/p&gt;  &lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&amp;amp;DisplayLang=en"&gt;Open XML Format SDK 2.0&lt;/a&gt; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/office/bb265236.aspx"&gt;Open XML Resource Center&lt;/a&gt; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9&amp;amp;displaylang=en"&gt;Microsoft Visual Studio Tools for the Office System Power Tools v1.0.0.0&lt;/a&gt; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://www.codeplex.com/dbe"&gt;Word 2007 Content Control Toolkit &lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href="http://msdn.com/vsto"&gt;VSTO Developer Center&lt;/a&gt; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://msdn.com/vbasic"&gt;Visual Basic Developer Center&lt;/a&gt;     &lt;p&gt;Enjoy!&lt;/p&gt;    &lt;p&gt;&lt;/p&gt; &lt;/li&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9879123" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/XML/default.aspx">XML</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Office/default.aspx">Office</category></item><item><title>Auto Access to non-Indexed Collections : Or How I Learned to Stop Worrying and Love the VB Compiler</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/14/auto-access-to-non-indexed-collections-or-how-i-learned-to-stop-worrying-and-love-the-vb-compiler.aspx</link><pubDate>Sat, 15 Aug 2009 02:26:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9870664</guid><dc:creator>Beth Massi</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9870664.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9870664</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9870664</wfw:comment><description>&lt;p&gt;I just finished a couple more &lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#wpfentity" target="_blank"&gt;How Do I videos on using EF with WPF using VS2008 SP1&lt;/a&gt; (they’ll be published soon) and while I was translating my VB code to C# I stumbled upon an error in C# that does not happen in VB. This of course got me curious and so I thought I’d share what I found out.&lt;/p&gt;  &lt;p&gt;I have an EDM defined with a parent entity &lt;b&gt;Order&lt;/b&gt; and child &lt;b&gt;OrderDetails&lt;/b&gt; that I created with the designer – very basic – like I show in &lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776537.aspx" target="_blank"&gt;this video&lt;/a&gt;. In the example I was working on, I was putting the results of an order query into a generic list but also including the OrderDetails so I end up with an &lt;a href="http://msdn.microsoft.com/en-us/library/bb354106.aspx" target="_blank"&gt;EntityCollection&lt;/a&gt; called OrderDetails on every Order.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;OMSEntities &lt;/span&gt;db = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OMSEntities&lt;/span&gt;();

&lt;span style="color: blue"&gt;var &lt;/span&gt;results = &lt;span style="color: blue"&gt;from &lt;/span&gt;o &lt;span style="color: blue"&gt;in &lt;/span&gt;db.Orders.Include(&lt;span style="color: #a31515"&gt;&amp;quot;OrderDetails&amp;quot;&lt;/span&gt;)
              &lt;span style="color: blue"&gt;select &lt;/span&gt;o;

&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Order&lt;/span&gt;&amp;gt; orderList = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Order&lt;/span&gt;&amp;gt;(results);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;However if I want to get the first Order’s first OrderDetail, I get an error in C#: “&lt;strong&gt;&lt;em&gt;Cannot apply indexing with [] to an expression of type 'System.Data.Objects.DataClasses.EntityCollection&amp;lt;EFTestDAL.OrderDetail&amp;gt;&lt;/em&gt;&lt;/strong&gt;'” when I write this line:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//ERROR
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(orderList[0].OrderDetails[0].OrderDetailID);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;However, the VB code works perfectly.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;db &lt;span style="color: blue"&gt;As New &lt;/span&gt;OMSEntities

&lt;span style="color: blue"&gt;Dim &lt;/span&gt;results = &lt;span style="color: blue"&gt;From &lt;/span&gt;o &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Orders.Include(&lt;span style="color: #a31515"&gt;&amp;quot;OrderDetails&amp;quot;&lt;/span&gt;) _
              &lt;span style="color: blue"&gt;Select &lt;/span&gt;o

&lt;span style="color: blue"&gt;Dim &lt;/span&gt;orderList &lt;span style="color: blue"&gt;As New &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Order)(results)

&lt;span style="color: green"&gt;'No Error
&lt;/span&gt;Console.WriteLine(orderList(0).OrderDetails(0).OrderDetailID)&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;So what gives in C#? At first I thought it was something with the way the EntityCollection was being generated in each of the designer code-behind for the languages, maybe I found a bug? So I created a single solution and used C# as the data access layer project and then added a C# client and a VB client project and still the same issue. VB worked fine against the C# defined EntityCollection. Hmmmm…… &lt;/p&gt;

&lt;p&gt;Next Stop, &lt;a href="http://www.bing.com/" target="_blank"&gt;BING&lt;/a&gt;. I searched for the error message and no luck. Okay well it helps to actually read these error messages so let’s put on my glasses and break out my Microsoft Compiler Error Message Magic Translator* and yeah, as the title of this post suggests, the EntityCollection doesn’t actually implement an indexer. Okay so again, why does it work in VB? &lt;/p&gt;

&lt;p&gt;The VB Compiler loves to help. It’s like uber-helpful (sometimes to its own fault, I admit), but this time it’s really helping in a good way. The way to get this to work in C# is to call the &lt;a href="http://msdn.microsoft.com/en-us/library/bb299233.aspx" target="_blank"&gt;ElementAt&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/bb494386.aspx" target="_blank"&gt;ElementAtOrDefault&lt;/a&gt; extension methods. So in C# to get the OrderDetail by index you write:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//No ERROR
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(orderList[0].OrderDetails.ElementAt(0).OrderDetailID);&lt;/pre&gt;

&lt;p&gt;So what Visual Basic is doing for you is exactly that. Actually it’s calling ElementAtOrDefault for you if the collection does not implement an indexer of its own. So you can write the same syntax for all collections. This help topic on the &lt;a href="http://msdn.microsoft.com/en-us/library/bb384875.aspx" target="_blank"&gt;Extension Indexer Property&lt;/a&gt; gave us the clue we needed. So, if an IEnumerable or IQueryable doesn't define an indexer property, VB will translate the indexer syntax to the ElementAtOrDefault operator. Good to know!&lt;/p&gt;

&lt;p&gt;So I asked &lt;a href="http://blogs.msdn.com/diego/" target="_blank"&gt;Diego&lt;/a&gt; on the EF team why the EntityCollection doesn’t implement an indexer. I was told that the EF team decided long time ago that since there was conceptually no guarantee on the ordering of EntityCollections, they didn’t want to give the illusion that such ordering existed by exposing an indexer. The internal implementation of EntityCollection(Of T) uses HashSet(Of T), which is super-fast and doesn’t have an indexer.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;*No there is no such thing as a Microsoft Compiler Error Message Magic Translator that I know of so please don’t ask! But please feel free to create one on &lt;a href="http://www.codeplex.com" target="_blank"&gt;CodePlex&lt;/a&gt;. ;-)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9870664" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Using Windows Presentation Foundation in Office Clients</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/10/using-windows-presentation-foundation-in-office-clients.aspx</link><pubDate>Tue, 11 Aug 2009 03:31:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9863656</guid><dc:creator>Beth Massi</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9863656.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9863656</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9863656</wfw:comment><description>&lt;p&gt;&lt;img style="display: inline; margin: 0px 10px 10px 0px" src="http://www.sdn.nl/Portals/0/Upload/Images/2009/Website/VP101.png" align="left" /&gt; I was cleaning up my desk today and in the piles of mail and gobs of paper I found the &lt;a href="http://www.sdn.nl/SDN/Magazine/tabid/66/articleType/ArticleView/articleId/2870/SDN-Magazine-101-Women-In-Technology-is-uit.aspx" target="_blank"&gt;SDN Magazine “Women in Technology” issue 101&lt;/a&gt; that featured an article I wrote that was released in print back in May. Well, I just noticed today that near the end of June they made most of the articles available online, including mine. :-)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.sdn.nl/SDN/Artikelen/tabid/58/agentType/View/PropertyID/2982/Default.aspx"&gt;&lt;strong&gt;Using Windows Presentation Foundation and Line-of-Business Data in Microsoft Office Clients&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In this article I talk about how to expose Line-of-Business data via ADO.NET Data Services to an Excel client using WPF. Office solutions you build with Visual Studio are designed to work with Windows Forms controls but you can also use WPF controls in your solutions as well. Any UI element that can host Windows Forms controls in an Office solution (VSTO) can also host WPF controls using the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.integration.elementhost.aspx" target="_blank"&gt;Winforms ElementHost&lt;/a&gt; as a container. &lt;/p&gt;  &lt;p&gt;Using WPF controls in Office allows you to think out of the box and provide world-class data visualizations that are not possible with Windows Forms controls. And you can do it easily in an instantly familiar end-user application like those in the Office family. But what if you don’t have any fancy data visualizations? Even the simplest controls that display data are often better off as WPF controls in Office applications because they better match the UI styles used in the latest versions of Office. Using WPF can make your add-ins look built into the Office applications themselves, providing a better user experience.&lt;/p&gt;  &lt;p&gt;This article describes one piece of the Northwind Office Business Application (OBA) we created in the beginning of the year so if you’re interested in OBA development with Outlook, Word, Excel and Sharepoint I’d suggest reading these as well:&lt;/p&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/02/03/oba-part-1-exposing-line-of-business-data.aspx"&gt;OBA Part 1 - Exposing Line-of-Business Data&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/02/07/oba-part-2-building-and-outlook-client-against-lob-data.aspx"&gt;OBA Part 2 - Building and Outlook Client against LOB Data&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/02/12/oba-part-3-storing-and-reading-data-in-word-documents.aspx"&gt;OBA Part 3 - Storing and Reading Data in Word Documents&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/03/08/oba-part-4-building-an-excel-client-against-lob-data.aspx"&gt;OBA Part 4 - Building an Excel Client against LOB Data&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/04/21/oba-part-5-building-the-sharepoint-2007-workflow.aspx"&gt;OBA Part 5 - Building the SharePoint 2007 Workflow&lt;/a&gt;&lt;/li&gt;  &lt;p&gt;The full sample application, built with Visual Studio 2008, is here: &lt;a title="http://code.msdn.microsoft.com/OBANorthwind" href="http://code.msdn.microsoft.com/OBANorthwind"&gt;http://code.msdn.microsoft.com/OBANorthwind&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Of course, the rest of the magazine is pack full of awesome articles from very well known women in technology (scroll to the bottom of &lt;a href="http://www.sdn.nl/SDN/Magazine/tabid/66/articleType/ArticleView/articleId/2870/SDN-Magazine-101-Women-In-Technology-is-uit.aspx" target="_blank"&gt;this page&lt;/a&gt; for the whole list). I’m honored to be featured with them in this issue. Thanks again to &lt;a href="http://information-worker.org/aboutus.aspx" target="_blank"&gt;Marianne van Wanrooij&lt;/a&gt; and the folks at &lt;a href="http://www.sdn.nl" target="_blank"&gt;SDN&lt;/a&gt; for putting this together and I’ll see you &lt;a href="http://www.sdc.nl/" target="_blank"&gt;in October at the SDN Conference&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9863656" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/XML/default.aspx">XML</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/ADO.NET+Data+Services/default.aspx">ADO.NET Data Services</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/OBA/default.aspx">OBA</category></item></channel></rss>