Visual Studio 2005 Tools for Office Hands-on Labs for Word 2003
Microsoft Corporation
June 2005
Updated February 2006
Applies to:
Microsoft Visual Studio 2005 Tools for the Microsoft Office System
Microsoft Visual Basic 2005
Microsoft Office Word 2003
Summary: Use these Hands-on Labs to gain experience building a customer survey application using Microsoft Visual Studio 2005 Tools for the Microsoft Office System and Microsoft Office Word 2003. (45 printed pages)
Download OfficeVSTO2005WordLabs.msi.
Contents
Setting Up the Labs
Lab 1-Creating Actions Panes in Word
Lab 2-Using Controls in Word Documents
Lab 3-Working with Data in Word Documents
Lab 4-Caching Data in Word Documents
Conclusion
Additional Resources
Setting Up the Labs
To work through the lab exercises, you must install:
Microsoft Windows 2000 or later
Microsoft Visual Studio 2005 Tools for the Microsoft Office System
Microsoft Office Professional Edition 2003 with Service Pack 1
Note Microsoft Office Word and the primary interop assemblies (PIAs) are required for these labs. When prompted during installation, choose the option to run the PIAs from your computer.
Note You must set macro security in Word to medium in order to complete these labs.
Microsoft SQL Server 2005 Express Edition (included with Visual Studio 2005 Tools for Office)
Note When applicable, instructions in the lab manual refer to files by a full path; it is assumed that the download files are extracted to
\My Documents\Visual Studio 2005\Projects
. The files needed to complete the labs are in a subfolder namedVSTO 2005 Word Labs\Starter Files
. A completed version of the labs can be found in theVSTO 2005 Word Labs\Completed Labs
subfolder.
When working with controls on the Word document in this lab, if you find that you cannot change the value of a control, you may be in Design mode. To exit Design mode, on the Control Toolbox toolbar, click Exit Design Mode.
Also, if you receive a message stating "Windows Forms controls have been disabled because the document has been scaled. When zoom is returned to 100%, controls will reactivate," enter Design mode by clicking Design Mode on the Control Toolbox toolbar, resize the control that gave the error, and then exit Design mode again.
Lab 1—Creating Actions Panes in Word
The objective of this lab is to introduce you to creating Word projects with Visual Studio 2005 Tools for Office and to demonstrate working with an actions pane in Word. In this lab, you create an actions pane for your Word solution and manage layout of controls contained in the actions pane.
Estimated time to complete:
- Exercise 1: Create Actions Panes—10 minutes
Exercise 1: Creating Actions Panes
To create a Word Document project
On the File menu, click New, and then click Project.
In the list of Project Types, expand Visual Basic (or Visual C#) and click Office.
In the Templates list, select Word Document.
In the Name box, type CustomerSurvey, and in the Location box type a location, such as C:\VSTO2005\Labs. The New Project dialog box looks like Figure 1.
Figure 1. Create a Word Document project (click picture to see larger image)
Click OK. The Visual Studio Tools for Office Project Wizard appears.
In the wizard, select Copy an existing document.
Click Browse.
Navigate to the following directory and then click Open:
\My Documents\Visual Studio 2005\Projects\VSTO 2005 Word Labs\Starter Files\Customer Satisfaction Survey.doc
In the wizard, click OK. You may receive the warning shown in Figure 2.
Figure 2. Access to the Visual Basic for Applications project system is disabled by default (click picture to see larger image)
If you do receive the security message, click OK to allow access to the Visual Basic for Applications project system. You need to do this only once.
On the File menu, click Save All.
To add a user control to the Word actions pane
In Solution Explorer, right-click the CustomerSurvey project; on the shortcut menu, point to Add and then click Existing Item. The Add Existing Item dialog box appears.
Navigate to one of the following directories, and then click Add:
\My Documents\Visual Studio 2005\Projects\VSTO 2005 Word Labs\Starter Files\ SubmitPaneVB\SubmitPane.vb
or
\My Documents\Visual Studio 2005\Projects\VSTO 2005 Word Labs\Starter Files\SubmitPaneC#\SubmitPane.vb
In Solution Explorer, right-click SubmitPane.vb (or SubmitPane.cs); on the shortcut menu, click View Designer.
The user control SubmitPane appears as shown in Figure 3. It is a simple user control with only a GroupBox, a Label, and a Button.
Figure 3. SubmitPane is ready to be added to the actions pane
In Solution Explorer, right-click SubmitPane.vb (or SubmitPane.cs); on the shortcut menu, click View Code.
Add code to the SubmitPane class to raise an event named OnSubmit when the Button is clicked and expose public write-only properties for setting the text of the Label and Button controls. Start by adding an Event statement to the SubmitPane class.
' Visual Basic Public Class SubmitPane Public Event OnSubmit() End Class // C# public partial class SubmitPane : UserControl { public SubmitPane() { InitializeComponent(); } public delegate void OnSubmitEventDelegate(); public event OnSubmitEventDelegate OnSubmit; }
Add code to define the Message and ButtonText properties.
' Visual Basic Public WriteOnly Property Message() As String Set(ByVal value As String) Me.lblStatus.Text = value End Set End Property Public WriteOnly Property ButtonText() As String Set(ByVal value As String) Me.btnSubmit.Text = value End Set End Property // C# public string Message { set { this.lblStatus.Text = value; } } public string ButtonText { set { this.btnSubmit.Text = value; } }
On the View menu, click Designer.
Double-click the button to display the button's Click event handler in the Code Editor.
Add code to raise the OnSubmit event.
' Visual Basic Private Sub btnSubmit_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnSubmit.Click RaiseEvent OnSubmit() End Sub // C# private void btnSubmit_Click(object sender, EventArgs e) { OnSubmitEventDelegate temp = OnSubmit; if (temp != null) { temp(); } }
In Solution Explorer, right-click ThisDocument.vb (or ThisDocument.cs); on the shortcut menu, click View Code. The code module for the document appears; notice that the document code-behind is encapsulated in a class named ThisDocument.
Add a private member variable to the ThisDocument class for an instance of the SubmitPane user control.
' Visual Basic Private WithEvents ucSubmitPane As SubmitPane // C# private SubmitPane ucSubmitPane;
Add a new private method named CreateActionsPane to the ThisDocument class that adds the SubmitPane control to the Word actions pane.
' Visual Basic Private Sub CreateActionsPane() Me.SmartDocument.SolutionID = "" 'Add a user control to the actions pane. ucSubmitPane = New SubmitPane Me.ActionsPane.Controls.Add(ucSubmitPane) End Sub // C# private void CreateActionsPane() { this.SmartDocument.SolutionID = ""; //Add the user control to the actions pane ucSubmitPane = new SubmitPane(); ucSubmitPane.OnSubmit+= new SubmitPane.OnSubmitEventDelegate(ucSubmitPane_OnSubmit); ActionsPane.Controls.Add(ucSubmitPane); }
Add a call to CreateActionsPane in the Startup event of the ThisDocument class.
' Visual Basic Private Sub ThisDocument_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup Me.CreateActionsPane() End Sub // C# private void ThisDocument_Startup(object sender, System.EventArgs e) { CreateActionsPane(); }
Add code to handle the OnSubmit event that is raised by the SubmitPane control when the button is clicked.
Add the following code to the procedure stub.
' Visual Basic Private Sub ucSubmitPane_OnSubmit() Handles ucSubmitPane.OnSubmit MessageBox.Show("TO DO. Submit") End Sub // C# private void ucSubmitPane_OnSubmit() { MessageBox.Show("TO DO: Submit"); }
Checkpoint
On the File menu, click Save All.
On the Debug menu, click Start Debugging to build and run the project. The document Customer Satisfaction Survey.doc opens in Word.
The actions pane now contains a SubmitPane user control, as shown in Figure 4.
Figure 4. The actions pane with the SubmitPane user control (click picture to see larger image)
Click Submit. You receive the message "TO DO: Submit".
Close the document without saving changes and exit Word.
Lab 2—Using Controls in Word Documents
The objective of this lab is to demonstrate the types of controls that you can use in a Word document and how you can handle document events and control events.
Estimated time to complete:
- Exercise 1: Using Bookmark Controls and Handling Events—15 minutes
- Exercise 2: Using Windows Forms Controls—15 minutes
This lab uses the CustomerSurvey project you created in Lab 1.
Exercise 1: Using Bookmark Controls and Handling Events
To handle an event for a bookmark control in your document
In Solution Explorer, right-click ThisDocument.vb (or ThisDocument.cs); on the shortcut menu, click View Designer.
If the Properties window is not visible, on the View menu, click Properties Window.
Click the arrow next to the list at the top of the Properties window (the Control list) to see the list of controls on the document; notice that several bookmark controls already exist. The designer automatically created bookmark controls for bookmarks that existed in the original Customer Satisfaction Survey.doc when you created the project.
In the Control list of the Properties window, select bkMenu to select the bookmark bkMenu. This selects the Menu bookmark in the upper-right corner of the document.
Double-click inside the bkMenu bookmark. The Code window for ThisDocument.vb (or ThisDocument.cs) opens. The bkMenu_SelectionChange event is automatically created for you.
Add the following code to bkMenu_SelectionChange to change the Word status bar text when the bookmark is selected.
' Visual Basic Private Sub bkMenu_SelectionChange(ByVal sender As System.Object, _ ByVal e As Microsoft.Office.Tools.Word.SelectionEventArgs) _ Handles bkMenu.SelectionChange Application.StatusBar = "Right-click for more options" End Sub // C# private void bkMenu_SelectionChange(object sender, Microsoft.Office.Tools.Word.SelectionEventArgs e) { Application.StatusBar = "Right-click for more options"; }
To create a command bar during document initialization
Add private member variables for CommandBar and CommandBarButton references to the ThisDocument class.
' Visual Basic 'CommandBar pop-up and CommandBar controls Private cbPopup As Office.CommandBar Private cbctlPrevious As Office.CommandBarButton Private cbctlNext As Office.CommandBarButton Private cbctlShowByCustID As Office.CommandBarButton Private cbctlShowAll As Office.CommandBarButton Private cbctlShowCompleted As Office.CommandBarButton // C# //CommandBar pop-up and CommandBar controls private Office.CommandBar cbPopup; private Office.CommandBarButton cbctlPrevious; private Office.CommandBarButton cbctlNext; private Office.CommandBarButton cbctlShowByCustID; private Office.CommandBarButton cbctlShowAll; private Office.CommandBarButton cbctlShowCompleted;
Add a private method to the ThisDocument class named cbctlClick that is called when any one of the command bar buttons on the custom pop-up is clicked.
' Visual Basic Private Sub cbctlClick(ByVal Ctrl As Office.CommandBarButton, _ ByRef CancelDefault As Boolean) MessageBox.Show("To do: " & Ctrl.Tag) End Sub // C# private void cbctlClick(Office.CommandBarButton Ctrl, ref bool CancelDefault) { MessageBox.Show("To do: " + Ctrl.Tag); }
Add a private method to the ThisDocument class named AddPopupButton that is called to create command bar buttons, and set up the event delegates for the buttons.
' Visual Basic Private Sub AddPopupButton(ByVal Caption As String, _ ByVal Tag As String, ByRef Btn As Office.CommandBarButton) 'Add the button with the given Caption and Tag properties. Btn = cbPopup.Controls.Add(Office.MsoControlType.msoControlButton) Btn.Caption = Caption Btn.Tag = Tag 'Set up the event handler for the button when it is clicked. AddHandler Btn.Click, AddressOf Me.cbctlClick End Sub // C# private void AddPopupButton(string Caption, string Tag, ref Office.CommandBarButton Btn) { //Add the button with the given Caption and Tag properties. Btn = (Office.CommandBarButton)(cbPopup.Controls.Add( Office.MsoControlType.msoControlButton, missing, missing, missing, missing)); Btn.Caption = Caption; Btn.Tag = Tag; //Set up the event handler for the button when it is clicked. Btn.Click += new Office._CommandBarButtonEvents_ClickEventHandler( cbctlClick); }
Add a private method to the ThisDocument class named AddPopupMenu that creates a pop-up command bar named Survey Filter Popup.
' Visual Basic Private Sub AddPopupMenu() Try //Set the customization context to this document so that //command bar changes are reflected in this document and not //stored in Normal.dot (which is the default). Me.Application.CustomizationContext = _ Me.Application.ActiveDocument 'Add the command bar to the document. cbPopup = Me.CommandBars.Add("Survey Filter Popup", _ Office.MsoBarPosition.msoBarPopup, , True) 'Add command bar buttons to the popup. Me.AddPopupButton("Previous Order", "MOVE_PREVIOUS", _ cbctlPrevious) Me.AddPopupButton("Next Order", "MOVE_NEXT", cbctlNext) Me.AddPopupButton("", "SHOW_BY_CUSTID", cbctlShowByCustID) cbctlShowByCustID.BeginGroup = True Me.AddPopupButton("Show Only Completed Surveys Ready to Submit", _ "SHOW_COMPLETED", cbctlShowCompleted) Me.AddPopupButton("Show All Orders", "SHOW_ALL", cbctlShowAll) Catch ex As Exception MessageBox.Show(ex.Message, "Error adding Survey Filter Popup") End Try End Sub // C# private void AddPopupMenu() { try { //Set the customization context to this document so that command //bar changes are reflected in this document and not stored //in Normal.dot (which is the default). Application.CustomizationContext = this.InnerObject; //Add the command bar to the document. cbPopup = this.CommandBars.Add("Survey Filter Popup", Office.MsoBarPosition.msoBarPopup, missing, true); //Add command bar buttons to the pop-up. this.AddPopupButton("Previous Order", "MOVE_PREVIOUS", ref cbctlPrevious); this.AddPopupButton("Next Order", "MOVE_NEXT", ref cbctlNext); this.AddPopupButton("", "SHOW_BY_CUSTID", ref cbctlShowByCustID); cbctlShowByCustID.BeginGroup = true; this.AddPopupButton( "Show Only Completed Surveys Ready to Submit", "SHOW_COMPLETED", ref cbctlShowCompleted); this.AddPopupButton("Show All Orders", "SHOW_ALL", ref cbctlShowAll); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error adding Survey Filter Popup"); } }
Append the following line of code to ThisDocument_Startup to call the AddPopupMenu method.
' Visual Basic AddPopupMenu() // C# AddPopupMenu();
To show a command bar pop-up when you right-click a bookmark
On the View menu, click Designer.
Select the bkMenu bookmark on the document.
In the Properties window, click Events.
In the Properties window, double-click the BeforeRightClick event to show the event handler in the Code Editor.
Add code to bkMenu_BeforeRightClick that shows the Survey Filter Popup command bar when you right-click the bkMenu bookmark.
' Visual Basic Private Sub bkMenu_BeforeRightClick(ByVal sender As Object, _ ByVal e As Microsoft.Office.Tools.Word.ClickEventArgs) _ Handles bkMenu.BeforeRightClick 'Update command bar button properties based on the text of the 'current Customer ID. cbctlShowByCustID.Caption = "Show Only Orders for [TO DO]" 'Show the pop-up and then cancel the default action. cbPopup.ShowPopup() e.Cancel = True End Sub // C# private void bkMenu_BeforeRightClick(object sender, Microsoft.Office.Tools.Word.ClickEventArgs e) { //Update command bar button properties based on the text of the //current Customer ID. cbctlShowByCustID.Caption = "Show Only Orders for [TO DO]"; //Show the pop-up and then cancel the default action. cbPopup.ShowPopup(missing, missing); e.Cancel = true; }
Checkpoint
On the File menu, click Save All.
On the Debug menu, click Start Dubugging to build and run the project. The document Customer Satisfaction Survey.doc opens in Word.
Click the document to place the insertion mark inside the bookmark bkMenu. Notice that the status bar text changes to Right-click for more options, as shown in Figure 5.
Figure 5. Click the bookmark to see the status message; right-click to see the pop-up menu (click picture to see larger image)
Right-click the bookmark bkMenu to display the Survey Filter Popup command bar.
Click any one of the controls on the pop-up menu to display a message.
Close the document without saving changes and exit Word.
Exercise 2: Using Windows Forms Controls
To add Windows Forms controls to your document
Throughout this portion of the exercise, refer to Figure 6 for an illustration of how to position the controls on the document.
Figure 6. The document looks like this when the controls have all been placed (click picture to see larger image)
In Solution Explorer, right-click ThisDocument. vb (or ThisDocument.cs); on the shortcut menu, click View Designer.
If the Toolbox window is not visible, on the View menu, click Toolbox.
Select a NumericUpDown control and drag it to the last cell of the first row in the survey table.
Select a CheckBox control and drag it to the last cell of the second row in the survey table.
Select a CheckBox control and drag it to the last cell of the third row in the survey table.
Select a NumericUpDown control and drag it to the last cell of the fourth row in the survey table.
Select a CheckBox control and drag it to the last cell of the fifth row in the survey table.
Set the properties for the Windows Forms controls on the document according to Table 1.
Table 1. Property values for controls in Customer Satisfaction Survey.doc
Control Property Value NumericUpDown1 (Name) nupdnSalesRep Maximum 5 Minimum 1 Value 5 Width 140 CheckBox1 (Name) chkCourteous Text No Width 140 CheckBox2 (Name) chkEfficiency Text No Width 140 NumericUpDown2 (Name) nupdnOverall Maximum 5 Minimum 1 Value 5 Width 140 CheckBox3 (Name) chkSurveyed Text Completed Width 140
To initialize the Windows Forms controls on your document
In Solution Explorer, right-click ThisDocument.vb (or ThisDocument.cs); on the shortcut menu, click View Code.
Add a private read-only property named NormalFont to the ThisDocument class that returns a Font similar to the Normal font in the document. You use NormalFont to set the Font properties of the Windows Forms controls so that the controls use a font similar to the Normal style font in the document.
' Visual Basic Private ReadOnly Property NormalFont() As System.Drawing.Font Get Dim ftNormal As Word.Font = Me.Styles("Normal").Font Dim ft As System.Drawing.Font ft = New Font(ftNormal.Name, ftNormal.Size, FontStyle.Regular) Return ft End Get End Property // C# private System.Drawing.Font NormalFont { get { object styleName = "Normal"; Word.Font ftNormal = this.Styles.get_Item(ref styleName).Font; System.Drawing.Font ft; ft = new Font(ftNormal.Name, ftNormal.Size, FontStyle.Regular); return ft; } }
Append the following code to ThisDocument_Startup to initialize the fonts of the controls.
' Visual Basic 'Format the fonts of the controls to match the Normal style. Dim ft As System.Drawing.Font = Me.NormalFont Me.nupdnSalesRep.Font = ft Me.chkCourteous.Font = ft Me.chkEfficiency.Font = ft Me.nupdnOverall.Font = ft Me.chkSurveyed.Font = ft // C# //Format the fonts of the controls to match the Normal style. System.Drawing.Font ft = this.NormalFont; nupdnSalesRep.Font = ft; chkCourteous.Font = ft; chkEfficiency.Font = ft; nupdnOverall.Font = ft; chkSurveyed.Font = ft;
On the View menu, click Designer.
Double-click chkCourteous to display the CheckedChanged event handler in the Code Editor.
Add code to the chkCourteous_CheckedChanged event handler that changes the text of the control to Yes or No based on the current value.
' Visual Basic Private Sub chkCourteous_CheckedChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles chkCourteous.CheckedChanged If chkCourteous.Checked Then chkCourteous.Text = "Yes" Else chkCourteous.Text = "No" End If End Sub // C# private void chkCourteous_CheckedChanged(object sender, EventArgs e) { if(chkCourteous.Checked) chkCourteous.Text = "Yes"; else chkCourteous.Text = "No"; }
Use the same technique to create a similar event handler for the CheckChanged event of the chkEfficiency check box control.
' Visual Basic Private Sub chkEfficiency_CheckedChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles chkEfficiency.CheckedChanged If chkEfficiency.Checked Then chkEfficiency.Text = "Yes" Else chkEfficiency.Text = "No" End If End Sub // C# private void chkEfficiency_CheckedChanged(object sender, EventArgs e) { if (chkEfficiency.Checked) chkEfficiency.Text = "Yes"; else chkEfficiency.Text = "No"; }
Checkpoint
On the File menu, click Save All.
On the Debug menu, click Start Dubugging to build and run the project. The document Customer Satisfaction Survey.doc opens in Word.
The Windows Forms controls appear on the document, as illustrated in Figure 7.
Figure 7. The Word document now includes Windows Forms controls (click picture to see larger image)
Click one of the check boxes and notice that the text changes to match the state of the check box.
Change the value in one of the NumericUpDown controls.
Close the document without saving changes and exit Word.
Lab 3—Working with Data in Word Documents
The objective of this lab is to illustrate how you can work with data in a Word document. In this lab, you connect to a SQL Server data source, bind bookmarks and Windows Forms controls to database objects, and navigate records in the data source.
Estimated time to complete:
- Exercise 1: Setting Up Connections and Adding Data Sources—10 minutes
- Exercise 2: Connecting, Binding, and Navigating to Data—30 minutes
- Exercise 3: Filtering Data—10 minutes
- Exercise 4: Inserting and Updating Data—10 minutes
This lab uses the CustomerSurvey project you created in Lab 2.
Exercise 1: Setting Up Connections and Adding Data Sources
To create the SurveysVSTO2005 SQL Express database
On the taskbar, click Start, and then click Run. Type cmd and click OK. A command window opens.
Go to the folder where the lab files reside:
\My Documents\Visual Studio 2005\Projects\VSTO 2005 Word Labs\Starter Files.
Execute the batch procedure.
osql.exe –n -E -S .\SQLExpress -i SurveysVSTO2005.sql
You receive the message "1 row affected" for each new entry in the database.
Close the command window.
To add a data source to your project
In Visual Studio, on the Data menu, click Show Data Sources. The Data Sources window appears.
In the Data Sources window, click Add New Data Source. The Data Source Configuration Wizard appears.
Select Database for the data source type and click Next.
Click New Connection. If you created a data connection previously, you see the Add Connection dialog box (shown in Figure 9) and you can skip to the next step. If you did not create a data connection previously, the Choose Data Source dialog box appears:
Type .\SQLExpress in the Server name list; the Connect to a database section becomes available.
In the Log on to the server section, select the Use Windows Authentication option.
In the Select or enter a database name list, choose SurveysVSTO2005.
Click Test Connection. If you do not receive the confirmation message shown in Figure 10, return to the Add Connection dialog box and verify that the selections you made are appropriate for your server.
Figure 10. After you make appropriate selections, the test connection succeeds
Click OK to close the message box, and then click OK to close the Add Connection dialog box. The Data Source Configuration Wizard now includes the connection you just created, as shown in Figure 11.
Figure 11. The name of your server precedes the name of the database (click picture to see larger image)
Click Next. You see the next step of the wizard, as shown in Figure 12.
Figure 12. Save the connection (click picture to see larger image)
Leave the Yes, save the connection as check box selected, name the connection NorthwindConnectionString and click Next. You see the Choose your database objects page of the wizard, as shown in Figure 13.
Figure 13. Use this page to select which objects you need for your application (click picture to see larger image)
Expand Tables in the list of database objects.
Select the Customers and Surveys tables.
Name the DataSet NorthwindDataSet, and then click Finish.
To configure the data source
In the Data Sources window, select NorthwindDataSet and then click Edit DataSet with Designer at the top of the Data Sources window.
Right-click the Surveys table in the designer window and, on the shortcut menu, click Configure. The TableAdapter Configuration Wizard appears.
Append a WHERE clause to the SQL statement so that newly filled DataSets contain only records where the Surveyed field is 0.
SELECT OrderID, CustomerID, RateSalesRep, RateCourteous, RateEfficiency, RateOverall, Surveyed FROM dbo.Surveys WHERE Surveyed=0
The completed dialog box looks like Figure 14.
Figure 14. Add a WHERE clause to the SQL statement (click picture to see larger image)
Click Finish.
To add a relation to the data source
On the Data menu, point to Add and then click Relation. The Relation dialog box appears.
Set the following fields for the new relation:
Table 2. Relation dialog box fields
Field Value Name FK_Survey_Customers Parent Table Surveys Child Table Customers Key Column CustomerID Foreign Key Column CustomerID When complete, the Relation dialog box looks like Figure 15.
Figure 15. The Relation dialog box (click picture to see larger image)
Click OK to add the new relation.
The NorthwindDataSet designer window appears, as illustrated in Figure 16.
Figure 16. Design view of the new relation
On the File menu, click Save All to save your changes.
Exercise 2: Connecting, Binding, and Navigating to Data
To bind a bookmark to a field in the Surveys table (the parent table)
In Solution Explorer, right-click ThisDocument.vb (or ThisDocument.cs); on the shortcut menu, click View Designer.
In the Data Sources window, expand Surveys.
Select OrderID under Surveys and drag it onto the bkOrderID bookmark in the document.
Note The bkOrderID bookmark is now bound to the SurveysBindingSource object. The designer automatically adds the SurveysBindingSource object to the component tray when you drag the OrderID field to the bookmark.
To bind the Windows Forms controls on the document to fields in SurveysBindingSource
Select the nupdnSalesRep control in the document.
In the Properties window, expand the DataBindings property and select the (Advanced) property.
Click the ellipsis (...) next to the (Advanced) property. You see the Formatting and Advanced Binding dialog box, as shown in Figure 17.
Figure 17. Formatting and Advanced Binding dialog box (click picture to see larger image)
In the Property list, select Value.
Drop down the Binding list.
Expand SurveysBindingSource and select RateSalesRep.
Click OK.
Repeat Steps 1 through 7 for each of the other controls in the document. Use Table 3 to determine which property and field to bind for each control.
Table 3. Binding instructions for each control
Control Property to Bind Field to Bind nupdnSalesRep Value SurveysBindingSource—RateSalesRep chkCourteous Checked SurveysBindingSource—RateCourteous chkEfficiency Checked SurveysBindingSource—RateEfficiency nupdnOverall Value SurveysBindingSource—RateOverall chkSurveyed Checked SurveysBindingSource—Surveyed
To bind controls to fields in the Customers table (the child table) using the foreign key
In the Data Sources window, notice that there is a Customers node in the Surveys table. This Customers node represents the relationship between the Surveys table and the Customers table.
Expand the Customers node in the Surveys table.
Select CustomerID under Customers and drag it onto the bkCustomerID bookmark in the document.
Note The bkCustomerID bookmark is now bound to the CustomersBindingSource object. The designer automatically adds the CustomersBindingSource object to the component tray when you drag the CustomerID field from the Data Sources window.
Select CompanyName under Customers and drag it onto the bkCompanyName bookmark in the document.
Select ContactName under Customers and drag it onto the bkContactName bookmark in the document.
Select Phone under Customers and drag it onto the bkPhone bookmark in the document.
In Solution Explorer, right-click ThisDocument.vb (or ThisDocument.cs); on the shortcut menu, click View Code.
Add a new private method named GetSurveys to the ThisDocument class.
' Visual Basic Private Sub GetSurveys() Me.CustomersTableAdapter.Fill(Me.NorthwindDataSet.Customers) Me.SurveysTableAdapter.Fill(Me.NorthwindDataSet.Surveys) End Sub // C# private void GetSurveys() { this.customersTableAdapter.Fill(this.northwindDataSet.Customers); this.surveysTableAdapter.Fill(this.northwindDataSet.Surveys); }
Delete the lines of code that the designer added to ThisDocument_Startup to automatically fill the table adapters.
' Visual Basic 'TODO: Delete this line of code to remove the default AutoFill for 'NorthwindDataSet.Customers. If Me.NeedsFill("NorthwindDataSet") Then Me.CustomersTableAdapter.Fill(Me.NorthwindDataSet.Customers) End If 'TODO: Delete this line of code to remove the default AutoFill for 'NorthwindDataSet.Surveys. If Me.NeedsFill("NorthwindDataSet") Then Me.SurveysTableAdapter.Fill(Me.NorthwindDataSet.Surveys) End If // C# // TODO: Delete this line of code to remove the default AutoFill for // northwindDataSet.Customers. if (this.NeedsFill("northwindDataSet")) { this.customersTableAdapter.Fill(this.northwindDataSet.Customers); } // TODO: Delete this line of code to remove the default AutoFill for // northwindDataSet.Surveys. if (this.NeedsFill("northwindDataSet")) { this.surveysTableAdapter.Fill(this.northwindDataSet.Surveys); }
Add a call to GetSurveys to ThisDocument_Startup.
' Visual Basic Private Sub ThisDocument_Startup(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Startup Me.CreateActionsPane() Me.AddPopupMenu() 'Format the controls' fonts to match the Normal style. Dim ft As System.Drawing.Font = Me.NormalFont Me.nupdnSalesRep.Font = ft Me.chkCourteous.Font = ft Me.chkEfficiency.Font = ft Me.nupdnOverall.Font = ft Me.chkSurveyed.Font = ft Me.GetSurveys() End Sub // C# private void ThisDocument_Startup(object sender, System.EventArgs e) { CreateActionsPane(); AddPopupMenu(); //Format the controls' fonts to match the Normal style. System.Drawing.Font ft = this.NormalFont; nupdnSalesRep.Font = ft; chkCourteous.Font = ft; chkEfficiency.Font = ft; nupdnOverall.Font = ft; chkSurveyed.Font = ft; this.GetSurveys(); }
Checkpoint
On the File menu, click Save All.
On the Debug menu, click Start Dubugging to build and run the project. The document Customer Satisfaction Survey.doc opens in Word.
Notice that the values in the first record of the data source (Order 10248 for VINET) appear in the bookmark controls and Windows Forms controls, as illustrated in Figure 18.
Figure 18. The document now includes data-bound controls (click picture to see larger image)
Close the document without saving changes and exit Word.
To navigate to records in the view
Replace the code in cbctlClick with the following code, which executes MovePrevious or MoveNext on the binding source based on the command bar button that triggered the event.
' Visual Basic Private Sub cbctlClick(ByVal Ctrl As Office.CommandBarButton, _ ByRef CancelDefault As Boolean) Me.Application.ScreenUpdating = False Try 'Perform action based on the tag of the button 'that was clicked. Select Case Ctrl.Tag Case "MOVE_PREVIOUS" Me.SurveysBindingSource.MovePrevious() Case "MOVE_NEXT" Me.SurveysBindingSource.MoveNext() End Select Catch ex As Exception MessageBox.Show(ex.Message) Finally Me.Application.ScreenUpdating = True End Try End Sub // C# private void cbctlClick(Office.CommandBarButton Ctrl, ref bool CancelDefault) { Application.ScreenUpdating = false; try { //Perform action based on the tag of the button //that was clicked. switch (Ctrl.Tag) { case "MOVE_PREVIOUS": surveysBindingSource.MovePrevious(); break; case "MOVE_NEXT": surveysBindingSource.MoveNext(); break; } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { Application.ScreenUpdating = true; } }
Modify bkMenu_BeforeRightClick to enable or disable the navigation command bar buttons based on the current position in the view.
' Visual Basic Private Sub bkMenu_BeforeRightClick(ByVal sender As Object, _ ByVal e As Microsoft.Office.Tools.Word.ClickEventArgs) _ Handles bkMenu.BeforeRightClick 'Update command bar button properties based on the text of the 'current Customer ID and the current position in the data source. cbctlShowByCustID.Caption = _ "Show Only Orders for " & Me.bkCustomerID.Text If Me.bkCustomerID.Text = "" Then cbctlShowByCustID.Enabled = False Else cbctlShowByCustID.Enabled = True End If Dim nPos As Integer = Me.SurveysBindingSource.Position cbctlPrevious.Enabled = (nPos > 0) cbctlNext.Enabled = ( _ nPos + 1 < Me.SurveysBindingSource.Count) 'Show the pop-up and then cancel the default action. cbPopup.ShowPopup() e.Cancel = True End Sub // C# private void bkMenu_BeforeRightClick(object sender, Microsoft.Office.Tools.Word.ClickEventArgs e) { // Update command bar button properties based on the text of the // current Customer ID and the current position in the data source. cbctlShowByCustID.Caption = "Show Only Orders for " + this.bkCustomerID.Text; if (this.bkCustomerID.Text == "") cbctlShowByCustID.Enabled = false; else cbctlShowByCustID.Enabled = true; int nPos = this.surveysBindingSource.Position; cbctlPrevious.Enabled = (nPos > 0); cbctlNext.Enabled = ( nPos + 1 < surveysBindingSource.Count); //Show the pop-up and then cancel the default action. cbPopup.ShowPopup(missing,missing); e.Cancel = true; }
To display the current position and record count in the view
Add a private method to the ThisDocument class named UpdatePane that updates the label in the SubmitPane control in the actions pane to display the current position and record count in the document.
' Visual Basic Private Sub UpdatePane() 'Update the SubmitPane control to display the current position in 'the data source and the count of records in the data source. If Not (Me.ucSubmitPane Is Nothing) Then Dim sCaption As String Dim nCurrentRecord As Integer = Me.SurveysBindingSource.Position + 1 Dim nRecords As Integer = Me.SurveysBindingSource.Count sCaption = nCurrentRecord & " of " & nRecords Me.ucSubmitPane.Message = sCaption End If End Sub // C# private void UpdatePane() { //Update the SubmitPane control to display the current position in //the data source and the count of records in the data source. if (ucSubmitPane!=null) { string sCaption; int nCurrentRecord = surveysBindingSource.Position + 1; int nRecords = surveysBindingSource.Count; sCaption = nCurrentRecord + " of " + nRecords; ucSubmitPane.Message = sCaption; } }
On the View menu, click Designer.
Select SurveysBindingSource.
In the Properties window, click Events. Double-click the ListChanged event to display the event handler in the Code Editor.
Add code to SurveysBindingSource_ListChanged that updates the window caption when the list changes.
' Visual Basic Private Sub SurveysBindingSource_ListChanged(ByVal sender As Object, _ ByVal e As System.ComponentModel.ListChangedEventArgs) _ Handles SurveysBindingSource.ListChanged Me.UpdatePane() End Sub // C# private void surveysBindingSource_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) { this.UpdatePane(); }
Use a similar technique for adding code to the PositionChanged event that updates the window caption when the position within the existing list changes.
' Visual Basic Private Sub SurveysBindingSource_PositionChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles SurveysBindingSource.PositionChanged Me.UpdatePane() End Sub // C# private void surveysBindingSource_PositionChanged(object sender, EventArgs e) { this.UpdatePane(); }
Checkpoint
- On the File menu, click Save All.
- On the Debug menu, click Start Dubugging to build and run the project. The document Customer Satisfaction Survey.doc opens in Word. Notice that the actions pane displays the current position in the data source (1 of 100) and that the first order in the view is for Order 10248.
- Fill out the controls in the survey.
- Right-click the bookmark bkMenu, and click Next Order on the pop-up menu to move to the next record in the data source. Notice that the actions pane changes to reflect the current position in the data source (2 of 100) and that Order 10249 now appears in the view.
- Right-click the bookmark bkMenu, and click Previous Order on the pop-up menu to move back to the first record in the data source.
- Notice that your survey selections (stored in the in-memory dataset, not in the actual data source) are restored in the view for Order 10248.
- Close the document without saving changes and exit Word.
Exercise 3: Filtering Data
To filter data in your data source
In Solution Explorer, right-click ThisDocument.vb (or ThisDocument.cs); on the shortcut menu, click View Code.
Add three additional cases to the Select Case (or switch) statement in cbctlClick that filter the data source to show all data, show data only for a given customer, or show data only for completed surveys.
' Visual Basic Private Sub cbctlClick(ByVal Ctrl As Office.CommandBarButton, _ ByRef CancelDefault As Boolean) Me.Application.ScreenUpdating = False Try 'Perform action based on the tag of the button 'that was clicked. Select Case Ctrl.Tag Case "MOVE_PREVIOUS" Me.SurveysBindingSource.MovePrevious() Case "MOVE_NEXT" Me.SurveysBindingSource.MoveNext() Case "SHOW_ALL" Me.SurveysBindingSource.EndEdit() Me.SurveysBindingSource.RemoveFilter() Case "SHOW_BY_CUSTID" Me.SurveysBindingSource.EndEdit() Me.SurveysBindingSource.Filter = _ String.Format(" CustomerID = '{0}' ", _ Me.bkCustomerID.Text) Case "SHOW_COMPLETED" Me.SurveysBindingSource.EndEdit() Me.SurveysBindingSource.Filter = "Surveyed=1" End Select Catch ex As Exception MessageBox.Show(ex.Message) Finally Me.Application.ScreenUpdating = True End Try End Sub // C# private void cbctlClick(Office.CommandBarButton Ctrl, ref bool CancelDefault) { Application.ScreenUpdating = false; try { //Perform action based on the tag of the button //that was clicked. switch (Ctrl.Tag) { case "MOVE_PREVIOUS": surveysBindingSource.MovePrevious(); break; case "MOVE_NEXT": surveysBindingSource.MoveNext(); break; case "SHOW_ALL": surveysBindingSource.EndEdit(); surveysBindingSource.RemoveFilter(); break; case "SHOW_BY_CUSTID": surveysBindingSource.EndEdit(); surveysBindingSource.Filter = String.Format(" CustomerID = '{0}' ", this.bkCustomerID.Text); break; case "SHOW_COMPLETED": surveysBindingSource.EndEdit(); surveysBindingSource.Filter = "Surveyed=1"; break; } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { Application.ScreenUpdating = true; } }
Checkpoint
- On the File menu, click Save All.
- On the Debug menu, click Start Dubugging to build and run the project. The document Customer Satisfaction Survey.doc opens in Word.
- Notice the actions pane; currently, the view contains 100 records in the table and you are viewing Record 1.
- Right-click the bkMenu bookmark; on the shortcut menu, click Show Only Orders for VINET.
- Notice the actions pane message, which indicates that the view now represents only the three records in the Surveys table that are associated with the Customer ID VINET.
- Right-click the bkMenu bookmark, and then click Previous Order or Next Order to navigate the records for VINET.
- Right-click the bkMenu bookmark, and then click Show All Orders to show all records.
- Complete questionnaires for one or more records. After you complete a survey for a record, check Completed.
- Right-click the bkMenu bookmark, and then click Show Only Completed Surveys Ready to Submit to display only those surveys that you marked as completed.
- Close the document without saving changes and exit Word.
Exercise 4: Inserting and Updating Data
To update data
In Solution Explorer, right-click ThisDocument.vb (or ThisDocument.cs); on the shortcut menu, click View Code.
Replace the code in the OnSubmit event that is raised by the SubmitPane control when the button is clicked to update the survey data in the database.
' Visual Basic Private Sub ucSubmitPane_OnSubmit() Handles ucSubmitPane.OnSubmit 'End the current edit. Me.SurveysBindingSource.EndEdit() 'Select those rows that have the Surveyed field set to 1. Dim rows() As CustomerSurvey.NorthwindDataSet.SurveysRow rows = Me.northwindDataSet.Surveys.Select("Surveyed=1") 'If there is at least one row selected, then proceed to update 'the database; otherwise, display a message. If rows.Length > 0 Then Try Dim nCount As Integer 'Perform the update and display a message about the 'rows affected. nCount = Me.surveysTableAdapter.Update(rows) MessageBox.Show("Number of surveys submitted: " & nCount) GetSurveys() Catch ex As Exception MessageBox.Show(ex.Message, "Error updating records") End Try Else MessageBox.Show("None of the records have been marked as " & _ "complete. No updates to the database have been made.") End If End Sub // C# private void ucSubmitPane_OnSubmit() { // End the current edit. surveysBindingSource.EndEdit(); //Select those rows that have the Surveyed field set to 1. CustomerSurvey.NorthwindDataSet.SurveysRow[] rows; rows = (CustomerSurvey.NorthwindDataSet.SurveysRow[])( northwindDataSet.Surveys.Select("Surveyed=1")); //If there is at least one row selected, then proceed to update //the database; otherwise, display a message. if (rows.Length > 0) { try { int nCount; //Perform the update and display a message about the //rows affected. nCount = surveysTableAdapter.Update(rows); MessageBox.Show("Number of surveys submitted: " + nCount); GetSurveys(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error updating records"); } } else { MessageBox.Show("None of the records have been marked as " + "complete. No updates to the database have been made."); } }
Checkpoint
- On the File menu, click Save All.
- On the Debug menu, click Start Debugging to build and run the project. The document Customer Satisfaction Survey.doc opens in Word.
- Complete the survey for Order 10248 (VINET) by setting values in the controls and checking the Completed check box.
- Click Submit in the actions pane. You receive a message that one survey was submitted. The next record appears.
- Complete the survey for Order 10249 (TOMSP) by setting values in the controls and checking the Completed check box, but, in the actions pane, do not click Submit to submit the survey yet.
- Right-click the bookmark bkMenu; on the shortcut menu, click Next Order to show the next record.
- Complete the survey for Order 10250 (HANAR) by setting values in the controls and checking the Completed check box.
- Click Submit. You receive a message that two surveys were submitted.
- Close the document without saving changes and exit Word.
Lab 4—Caching Data in Word Documents
This lab illustrates how you can cache data in a Word document for offline use. After you cache some data in a document, you read from and write to the document's data cache.
Estimated time to complete:
- Exercise 1: Caching Data in Word Documents—20 minutes
This lab uses the CustomerSurvey project you created in Lab 3.
Exercise 1: Caching Data in Word Documents
To add a cached dataset to the document
In Solution Explorer, right-click ThisDocument.vb (or ThisDocument.cs); on the shortcut menu, click View Code.
Add a public variable to the ThisDocument class to store the DataSet in the document cache.
' Visual Basic <Cached()> Public dsCached As CustomerSurvey.NorthwindDataSet // C# [Cached()] public CustomerSurvey.NorthwindDataSet dsCached;
Add a private member variable to the ThisDocument class that you use to indicate whether you are using a cached dataset.
' Visual Basic Private bCached As Boolean // C# private bool bCached;
On the View menu, click Designer.
In the Properties window, select ThisDocument, if it is not already selected.
In the Properties window, click Events to show the events available to ThisDocument.
Double-click the BeforeSave event to show the event handler in the Code Editor.
Add code to ThisDocument_BeforeSave that caches the data when the document is saved.
' Visual Basic Private Sub ThisDocument_BeforeSave(ByVal sender As Object, _ ByVal e As Microsoft.Office.Tools.Word.SaveEventArgs) _ Handles Me.BeforeSave Me.SurveysBindingSource.EndEdit() dsCached = Me.NorthwindDataSet End Sub // C# private void ThisDocument_BeforeSave(object sender, Microsoft.Office.Tools.Word.SaveEventArgs e) { surveysBindingSource.EndEdit(); dsCached = northwindDataSet; }
Replace the code in the GetSurveys method so that it uses data from the cache when data is present in the document.
' Visual Basic Private Sub GetSurveys() bCached = Not (dsCached Is Nothing) Try Me.Application.ScreenUpdating = False If Not bCached Then 'If there is no data cached in this document, then fill 'the dataset from the live data source. Me.CustomersTableAdapter.Fill(Me.NorthwindDataSet.Customers) Me.SurveysTableAdapter.Fill(Me.NorthwindDataSet.Surveys) Else 'Load the dataset from the cache. Me.NorthwindDataSet = dsCached End If 'Set up the data connectors. Me.SurveysBindingSource.DataMember = "Surveys" Me.SurveysBindingSource.DataSource = Me.NorthwindDataSet Me.CustomersBindingSource.DataMember = "FK_Survey_Customers" Me.CustomersBindingSource.DataSource = Me.SurveysBindingSource Me.Application.ScreenUpdating = True Catch ex As Exception Me.Application.ScreenUpdating = True MessageBox.Show(ex.Message, "Error retrieving data") End Try End Sub // C# private void GetSurveys() { bCached = (dsCached!=null); try { Application.ScreenUpdating = false; if (!bCached) { //If there is no data cached in this document, then fill //the dataset from the live data source. customersTableAdapter.Fill( northwindDataSet.Customers); surveysTableAdapter.Fill(northwindDataSet.Surveys); } else { //Load the dataset from the cache. northwindDataSet = dsCached; } //Set up the binding sources. surveysBindingSource.DataMember = "Surveys"; surveysBindingSource.DataSource = northwindDataSet; customersBindingSource.DataMember = "Surveys_Customers"; customersBindingSource.DataSource = surveysBindingSource; Application.ScreenUpdating = true; } catch (Exception ex) { Application.ScreenUpdating = true; MessageBox.Show(ex.Message, "Error retrieving data"); } }
Modify the UpdatePane method so that, when the view represents cached data, the SubmitPane control includes a message containing the text "[Cached]" and the button displays the text "Connect and Submit".
' Visual Basic Private Sub UpdatePane() 'Update the SubmitPane control to display the current position in 'the data source and the count of records in the data source. If Not (Me.ucSubmitPane Is Nothing) Then Dim sCaption As String Dim nCurrentRecord As Integer = Me.SurveysBindingSource.Position + 1 Dim nRecords As Integer = Me.SurveysBindingSource.Count sCaption = nCurrentRecord & " of " & nRecords If bCached Then sCaption &= vbCrLf & "[Cached]" Me.ucSubmitPane.Message = sCaption If bCached Then Me.ucSubmitPane.ButtonText = "Connect and Submit" Else Me.ucSubmitPane.ButtonText = "Submit" End If End If End Sub // C# private void UpdatePane() { //Update the SubmitPane control to display the current position in //the data source and the count of records in the data source. if (ucSubmitPane!=null) { string sCaption; int nCurrentRecord = surveysBindingSource.Position + 1; int nRecords = surveysBindingSource.Count; sCaption = nCurrentRecord + " of " + nRecords; if(bCached) sCaption += "\n[Cached]"; ucSubmitPane.Message = sCaption; if (bCached) ucSubmitPane.ButtonText = "Connect and Submit"; else ucSubmitPane.ButtonText = "Submit"; } }
Modify the OnSubmit event of the SubmitPane control to handle updates originating from the cached dataset.
' Visual Basic Private Sub ucSubmitPane_OnSubmit() Handles ucSubmitPane.OnSubmit 'End the current edit. Me.SurveysBindingSource.EndEdit() 'Select those rows that have the Surveyed field set to 1. Dim rows() As CustomerSurvey.NorthwindDataSet.SurveysRow rows = Me.northwindDataSet.Surveys.Select("Surveyed=1") 'If there is at least one row selected, then proceed to update 'the database; otherwise, display a message. If rows.Length > 0 Then Try Dim nCount As Integer 'Perform the update and display a message about the 'rows affected. nCount = Me.surveysTableAdapter.Update(rows) MessageBox.Show("Number of surveys submitted: " & nCount) If bCached Then dsCached.Clear() dsCached = Nothing End If GetSurveys() Catch ex As Exception MessageBox.Show(ex.Message, "Error updating records") End Try Else MessageBox.Show("None of the records have been marked as " & _ "complete. No updates to the database have been made.") End If End Sub // C# private void ucSubmitPane_OnSubmit() { // End the current edit. surveysBindingSource.EndEdit(); //Select those rows that have the Surveyed field set to 1. CustomerSurvey.NorthwindDataSet.SurveysRow[] rows; rows = (CustomerSurvey.NorthwindDataSet.SurveysRow[])( northwindDataSet.Surveys.Select("Surveyed=1")); //If there is at least one row selected, then proceed to update //the database; otherwise, display a message. if (rows.Length > 0) { try { int nCount; //Perform the update and display a message about the //rows affected. nCount = surveysTableAdapter.Update(rows); if(bCached) { dsCached.Clear(); dsCached = null; } MessageBox.Show("Number of surveys submitted: " + nCount); GetSurveys(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error updating records"); } } else { MessageBox.Show("None of the records have been marked as " + "complete. No updates to the database have been made."); } }
Checkpoint
On the File menu, click Save All.
On the Debug menu, click Start Debugging to build and run the project. The document Customer Satisfaction Survey.doc opens in Word.
Currently the data source represents 97 survey records, and the current record is Order 10251 for VICTE.
Complete the surveys for Orders 10251 and 10252, but do not submit them.
On the File menu, click Save As. The Save As dialog box appears.
Save the file with the name Cached.doc.
Close Cached.doc.
Open Cached.doc.
Notice that the actions pane indicates that you are viewing cached data, as illustrated in Figure 19. Also, notice that the survey selections you made for Order 10251 and Order 10252 are stored.
Figure 19. The actions pane shows that you are working with cached data (click picture to see larger image)
Move to Order 10253 and complete the survey.
Click Connect and Submit in the actions pane. You receive a message that three surveys are submitted. After the surveys are submitted, the actions pane indicates that you are no longer working with cached data. The view now contains 94 uncompleted surveys.
Close the document and exit Word.
Conclusion
In these labs, you learned how to create a customer survey application using Microsoft Visual Studio 2005 Tools for the Microsoft Office System and Microsoft Office Word 2003. You learned how to use Windows Forms controls, host controls, the actions pane, and data binding.
Additional Resources
For more information, see the following resources:
- Microsoft Visual Studio Developer Center
- Microsoft Office Developer Center: Visual Studio Tools for Office Developer Portal
- Online Documentation: Visual Studio Tools for Office
- Visual Studio 2005 Tools for Office Hands-on Labs for Excel 2003
- Visual Studio 2005 Tools for Office Hands-on Labs for Outlook 2003
- Blog: Microsoft Visual Studio 2005 Tools for the Microsoft Office System
- Forum: Visual Studio Tools for Office
- Microsoft Office Developer Center
- Microsoft Office Developer Center: Word