Microsoft Office 為組織提供了一個最終用戶非常熟悉的環境來快速創建業務應用程序。構建 Office 業務應用程序為組織提供了利用以下內容的大量機會:編輯客戶關系管理 (CRM) 系統、將從業務線應用程序提取的數據前置、托管商業智能報告,以及很多其他可能性。
盡管 Office 開發為組織提供了很多有價值的機會,但是之前它也為這些應用程序的開發和部署提出了一些挑戰。早期的托管語言版本也推動了使用 Office 創建應用程序的方式。
調用大量的 Office API 方法通常很難,因為其中包含很多參數,而且大多數參數都無用。Visual Basic 的可選參數功能簡化了這一操作,但是使用 C# 語言的開發人員將不得不編寫大量無用的初始化表達式或空語句,以填寫所需的方法簽名參數。如果您使用的是 Visual Basic,您將無法使用類似於 C# 3.0 的 lambda 的功能來在調用代理時提供內聯方法。
在本實驗中,您將看到 Visual Studio 2010、 C# 4.0 和 Visual Basic 10 中的新功能如何消除上述段落中提到的問題。此外,您還將看到其他一些強大功能,這些功能加速了其他 Office 要素的開發。
目標
在本次動手實驗中,您將學習如何:
• 學習新語言功能如何加速業務實體的創建
• 探索一些新的語言功能,這些功能使業務實體與 Excel 的交互變得更容易
• 利用支持在 Office 程序之間進行快速交互的新語言功能
• 了解新的構建過程如何簡化向最終用戶部署 Office 應用程序的過程
系統要求
您必須擁有以下內容才能完成本實驗:
• Microsoft Visual Studio 2010 Beta 2
• .Net Framework 4
• Microsoft Excel 2007
• Microsoft Word 2007
安裝
使用 Configuration Wizard 驗證本實驗的所有先決條件。要確保正確配置所有內容,請按照以下步驟進行。
注意:要執行安裝步驟,您需要使用管理員權限在命令行窗口中運行腳本。
1.如果之前沒有執行,運行 Training Kit 的 Configuration Wizard。為此,運行位於 %TrainingKitInstallationFolder%\Labs\Dev10Office\Setup 文件夾下的 CheckDependencies.cmd 腳本。安裝先決條件中沒有安裝的軟件(如有必要請重新掃描),並完成向導。
注意:為了方便,本實驗管理的許多代碼都可用於 Visual Studio 代碼片段。CheckDependencies.cmd 文件啟動 Visual Studio 安裝程序文件安裝該代碼片段。
練習
本次動手實驗由以下練習組成:
1.創建一個帳戶類集合並在 Microsoft Excel 中顯示帳戶信息
2.將 Microsoft Excel 工作表嵌入 Microsoft Word 文檔中
3.調整 VS 項目文件,以支持在不使用 PIA 的情況下部署程序
完成本實驗的估計時間:60 分鐘。
下一步
練習 1:創建一個業務實體集合並將其值插入 Excel 工作表中
練習 1:創建一個業務實體集合並將其值插入 Excel 工作表中
業務實體是一種常用模式,它通過應用程序或系統承載數據。業務實體可能反映一個銀行帳戶(顯示帳戶結余和帳戶持有人),或者可能反映放置了很多東西的購物車,其中每項都是它自己的業務實體。
在本練習中,您將學習如何創建業務實體集合,並將這些實體的值寫入 Excel 工作表中。在本練習中,您還將學習 C# 4.0 和 Visual Basic 10 中新的語言功能,這些新功能大大加快了業務實體的創建速度。
注意:要驗證每個步驟是否正確執行,建議在每次任務結束時生成解決方案。
任務 1 –創建一個新控制台應用程序並引用 Microsoft Office 互操作程序集
在本任務中,您將創建一個新控制台應用程序並將其添加到進行 Office 開發所需的程序集。
1.從 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打開 Microsoft Visual Studio 2010。
2.在 Microsoft Visual Studio 初始頁面, 單擊 New Project 圖標。
注意:本實驗將使用 C# 和 Visual Basic 兩種語言進行展示。您可以使用任何您熟悉的語言。在實驗過程中,將指出 Visual Studo 2010 和每種語言的新功能。
3.在 C# 或 Visual Basic 項目模板列表中,選擇 Windows | Console Application.
4.在Name字段中,輸入“OfficeApplication”
5.在右上角,確保選擇了 .NET Framework 4.0 版本。
6.接受默認的位置和解決方案名稱。單擊 OK 按鈕。該解決方案將使用一個控制台應用程序項目進行創建。
7.右鍵單擊 OfficeApplication 項目節點並選擇 Add Reference…。
8.在Add Reference 對話框的 .NET選項卡下,選擇 Microsoft.Office.Interop.Excel。按住 CTRL 鍵並單擊 Microsoft.Office.Interop.Word。單擊 OK 按鈕。
注意:由於本實驗針對的是 Office 2007,所以要確保在添加引用時選擇了版本 12.0.0.0。
完成時,控制台應用程序的引用列表應如下所示:
圖 1
Office 開發引用
任務 2 –創建業務實體集合
在本任務中,您將創建一個將預先填充數據的業務實體集合。預先填充用於模擬從單獨的源加載帶有數據的實體。在此我們將重點介紹數據訪問。
首先從創建單獨實體開始。
1.在 Solution Explorer 中,右鍵單擊 OfficeApplication 項目的節點,並從菜單中選擇 Add… | Class 。
2.將出現 Add New Item 對話框,其中包含已選中的 Class 模板。將名稱更改為 Account.cs (C#) 或 Account.vb (Visual Basic),單擊 Add 按鈕。
a.如果使用 C# 語言進行本實驗,將 Account 類的定義更改為 public,如下所示:
C#
public class Account
{
}
3.為 Account 添加公共屬性 ID (integer)、Balance (double) 和 AccountHolder (string),如下所示:
(代碼片段– Office 編程實驗 - 練習 1 Account 屬性 CSharp)
C#
public class Account
{
public int ID { get; set; }
public double Balance { get; set; }
public string AccountHolder { get; set; }
}
(代碼片段– Office 編程實驗 - 練習 1 Account 屬性 VB)
Visual Basic
Public Class Account
Property ID As Integer
Property Balance As Double
Property AccountHolder As String
End Class
注意:Visual Basic 有一項新功能,那就是無需聲明一個存儲值的單獨字段就可以聲明屬性。這種自動實現屬性的工作方式就好象開發人員聲明了一個私有字段來存儲數據並實現了簡單的“getter”和“setter”方法。它們的調用方式與傳統屬性的調用方式相同。如果屬性訪問需要更可靠的邏輯,那麼仍然可以創建在私有字段中存儲數據的傳統屬性。VS 2008 相應的 Visual Basic 代碼如下所示:
Visual Basic
' This is the old style using backing variables instead of
' auto-implemented properties
Public Class Account
Private _id As Integer
Private _balance As Double
Private _accountHolder As String
Property ID() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Property Balance() As Double
Get
Return _balance
End Get
Set(ByVal value As Double)
_balance = value
End Set
End Property
Property AccountHolder() As String
Get
Return _accountHolder
End Get
Set(ByVal value As String)
_accountHolder = value
End Set
End Property
End Class
4.Account 類表示您的單個實體類型。通常,應用程序會創建這些實體集合中的某些實體,並使用一些數據填充這些實體。為了保持本實驗簡潔明了,將通過在創建列表時將值推入各個對象來填充列表。在 Module1.vb (VB) 或 Program.cs (C#) 文件中,創建一個名為 CreateAccountList 的新方法,如以下代碼所示:
(代碼片段– Office 編程實驗 - 練習 1 CreateAccountList VB)
Visual Basic
Private Function CreateAccountList() As List(Of Account)
Dim checkAccounts As New List(Of Account) From {
New Account With {
.ID = 1,
.Balance = 285.93,
.AccountHolder = "John Doe"
},
New Account With {
.ID = 2,
.Balance = 2349.23,
.AccountHolder = "Richard Roe"
},
New Account With {
.ID = 3,
.Balance = -39.46,
.AccountHolder = "I Dunoe"
}
}
Return checkAccounts
End Function
注意:上述代碼強調了 Visual Basic 的另一項新功能:集合初始化程序。這使開發人員能夠節省大量時間,因為他們可以直接在聲明列表時初始化列表的內容。無需實例化列表,然後逐個“更新”更新各項將其添加到列表中。
(代碼片段– Office 編程實驗 - 練習 1 CreateAccountList CSharp)
C#
private static List<Account> CreateAccountList()
{
var checkAccounts = new List<Account> {
new Account{
ID = 1,
Balance = 285.93,
AccountHolder = "John Doe"
},
new Account{
ID = 2,
Balance = 2349.23,
AccountHolder = "Richard Roe"
},
new Account{
ID = 3,
Balance = -39.46,
AccountHolder = "I Dunoe"
}
};
return checkAccounts;
}
5.從 Module1.vb (VB) 或 Program.cs (C#) 文件中的 Main 方法調用 CreateAccountList 方法,如下所示:
Visual Basic
Sub Main()
Dim checkAccounts = CreateAccountList()
End Sub
C#
static void Main(string[] args)
{
var checkAccounts = CreateAccountList();
}
任務 3 –創建 Excel 工作簿並使用來自業務實體的數據填充它
在本任務中,您將創建一個新 Excel 工作簿。然後您可以遍歷業務對象集合並將數據插入 Excel 工作簿中。最後您將格式化工作表。
1.第一步是使用 Imports (VB) 或 using (C#) 語句導入 Office 命名空間。在 Module1.vb (VB) 或 Program.cs (C#) 文件的頂部輸入以下代碼:
(代碼片段– Office 編程實驗 - 練習 1 Namespaces VB)
Visual Basic
Imports Microsoft.Office.Interop
Imports System.Runtime.CompilerServices
(代碼片段– Office 編程實驗 - 練習 1 Namespaces CSharp)
C#
using Microsoft.Office.Interop;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
2.將數據插入 Excel 的代碼作為 Extension 方法實現。
該(和所有)擴展方法的第一個參數表示該方法(在帳戶列表中)所操作的類型。第二個參數 (DisplayFunc) 是一個類型為 delegate 的 Action。Action 代理可以接受任意多個參數,但總是返回 void。
該代碼塊創建了一個具有工作簿的新 Excel 應用程序,將一些標題文本插入工作簿中,調用一個幫助程序方法來顯示 Account 對象的值,然後將每列設置為 AutoFit 模式,以更好地顯示每列的值。
在 Module1.vb (VB) 或 Program.cs (C#) 中的 Main 方法後輸入以下代碼:
(代碼片段– Office 編程實驗 - 練習 1 DisplayInExcel VB)
Visual Basic
<Extension()>
Sub DisplayInExcel(ByVal accounts As IEnumerable(Of Account), ByVal DisplayFunc As Action(Of Account, Excel.Range))
With New Excel.Application
.Workbooks.Add()
.Visible = True
.Range("A1").Value = "ID"
.Range("B1").Value = "Balance"
.Range("C1").Value = "Account Holder"
.Range("A2").Select()
For Each ac In accounts
DisplayFunc(ac, .ActiveCell)
.ActiveCell.Offset(1, 0).Select()
Next
.Columns(1).AutoFit()
.Columns(2).AutoFit()
.Columns(3).AutoFit()
End With
End Sub
注意:在 C# 中,有必要將 Program.cs 中的 Program 類聲明更改為 static。
(代碼片段– Office 編程實驗 - 練習 1 DisplayInExcel CSharp)
C#
static void DisplayInExcel(this IEnumerable<Account> accounts,
Action<Account, Excel.Range> DisplayFunc)
{
var x1 = new Excel.Application();
//see the Note below
x1.Workbooks.Add();
x1.Visible = true;
x1.get_Range("A1").Value2 = "ID";
x1.get_Range("B1").Value2 = "Balance";
x1.get_Range("C1").Value2 = "Account Holder";
x1.get_Range("A2").Select();
foreach (var ac in accounts)
{
DisplayFunc(ac, x1.ActiveCell);
x1.ActiveCell.get_Offset(1, 0).Select();
}
((Excel.Range)x1.Columns[1]).AutoFit();
((Excel.Range)x1.Columns[2]).AutoFit();
((Excel.Range)x1.Columns[3]).AutoFit();
}
注意:語句 x1.Workbooks.Add(); 反映了 .NET Framework 4.0 和 C# 4.0 中的一個重要變化:可選參數。Microsoft.Office.Interop.Excel.Workbook COM 互操作程序集的早期版本需要傳入一個參數。此外,C# 的早期版本不支持可選參數,而 Visual Basic 開發人員多年來都偏愛使用可選參數。之前,該語句顯示為 x1.Workbooks.Add(Missing.Value);.NET Framework 4.0 中新的互操作程序集與 C# 4.0 對可選參數的全新支持結合使用,可以使您的語法更簡潔、更清晰。
3.下一步是從程序的 Main 方法調用擴展方法。將以下代碼添加到 Main 方法的底部:
(代碼片段– Office 編程實驗 - 練習 1 DisplayInExcel 調用 VB)
Visual Basic
checkAccounts.DisplayInExcel(Sub(account, cell)
cell.Value2 = account.ID
cell.Offset(0, 1).Value2 = account.Balance
cell.Offset(0, 2).Value2 = account.AccountHolder
If account.Balance < 0 Then
cell.Interior.Color = RGB(255, 0, 0)
cell.Offset(0, 1).Interior.Color = RGB(255, 0, 0)
cell.Offset(0, 2).Interior.Color = RGB(255, 0, 0)
End If
End Sub)
注意:這裡您看到了 Visual Basic 的另一個新功能:語句 lambda。語句 lambda 是一個匿名代碼塊,它與變量類似,可以將其用作方法的參數,正如本例所示。lambda 的語法是“聲明”一系列參數,在本例中是 account 和 cell,然後提供該 lambda 的邏輯。使用語句 lambdas 函數或 sub 時,不需要名稱但要推理參數類型。
(代碼片段– Office 編程實驗 - 練習 1 DisplayInExcel 調用 CSharp)
C#
checkAccounts.DisplayInExcel((account, cell) =>
{
cell.Value2 = account.ID;
cell.get_Offset(0, 1).Value2 = account.Balance;
cell.get_Offset(0, 2).Value2 = account.AccountHolder;
if (account.Balance < 0)
{
cell.Interior.Color = 255;
cell.get_Offset(0, 1).Interior.Color = 255;
cell.get_Offset(0, 2).Interior.Color = 255;
}
});
DisplayInExcel 擴展方法接受一個參數,Action 代理接受兩個參數。Action 代理的參數可以是 Account 對象的實例,也可以是 Excel 工作表單元格的實例。擴展方法實際上是一個功能單位,它將被 DisplayInExcel 函數主體中的 for each 循環中的每個 Account 調用。
DisplayInExcel 函數包含創建和執行 Excel 工作簿的設置的邏輯。您所提供的代理包含從 Account 對象獲取單個值並將其放在 Excel 工作表中的邏輯。
下一步
練習 1:驗證
練習 1:驗證
在本驗證中,您將運行控制台應用程序,並可以看到,打開了 Excel 工作表並且您的帳戶數據被填充到工作表中。
1.在 Visual Studio 中,按 F5 鍵以調試模式運行應用程序。
2.可以看到,應用程序啟動了一個 Microsoft Excel 實例並將您的數據插入到第一個工作表中:
圖 2
Excel 工作表中的帳戶數據
注意:注意,列已設置為根據內容調整列寬。此外還要注意, 根據傳入到 DisplayInExcel 函數的代理的 for each 循環的邏輯,有負債的帳戶背景顏色為紅色。
3.關閉 Excel。不要保存任何更改。
下一步
練習 2:將 Excel 工作表嵌入 Microsoft Word 中
練習 2:將 Excel 工作表嵌入 Microsoft Word 中
在本練習中,將把您的 Excel 工作表嵌入到 Microsoft Word 文檔中。本練習還將向 C# 開發人員介紹可選參數。
注意:要驗證每個步驟是否正確執行,建議在每次任務結束時生成解決方案。
任務 1 –將 Excel 工作表嵌入到新 Microsoft Word 文檔中
1.從 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打開 Microsoft Visual Studio 2010。
2.打開 OfficeApplication.sln 解決方案文件。默認情況下,該文件位於以下文件夾:%TrainingKitInstallFolder%\Labs\Dev10Office \Source\Ex02-EmbeddingWorksheet\Begin\,並選擇您喜歡的語言。您也可以繼續使用上一個練習完成時獲得的解決方案。
3.復制 Excel 工作表,以將其粘貼到 Word 文檔中。Copy() 方法可以完成此操作。將以下代碼添加到 DisplayInExcel 方法(在 Visual Basic 方法中,該命令需要位於 With 塊中)的末尾:
Visual Basic
.Range("A1:C4").Copy()
C#
x1.get_Range("A1:C4").Copy();
4.將工作表粘貼到剪貼板後,您需要創建一個 Word 文檔並將工作表粘貼到該文檔中。在 Module1.vb (VB) 或 Program.cs (C#) 文件中,創建一個名為 EmbedInWordDocument 的新方法,如以下代碼所示:
(代碼片段– Office 編程實驗 - 練習 2 EmbedInWordDocument VB)
Visual Basic
private bool LoadDictionaries()
Dim word As New Word.Application
word.Visible = True
word.Documents.Add()
word.Selection.PasteSpecial(Link:=True, DisplayAsIcon:=False)
End Sub
(代碼片段– Office 編程實驗 - 練習 2 EmbedInWordDocument CSharp)
C#
private static void EmbedInWordDocument()
{
var word = new Word.Application();
word.Visible = true;
word.Documents.Add();
word.Selection.PasteSpecial(Link:true, DisplayAsIcon:false);
}
注意:C# 開發人員將在調用 PasteSpecial 的過程中發現 C# 4.0 的一項新功能:可選參數的使用。PasteSpecial 實際上有 7 個參數。在大多數情況下,您不需要提供這些參數的值,因為默認值已足夠。在 C# 的早期版本中,這些值仍然需要提供,即使提供的值為 System.Reflection.Missing.Value 類型(這將導致調用 PasteSpecial,如下所示):
C#
object iconIndex = System.Reflection.Missing.Value;
object link = true;
object placement = System.Reflection.Missing.Value;
object displayAsIcon = false;
object dataType = System.Reflection.Missing.Value;
object iconFileName = System.Reflection.Missing.Value;
object iconLabel = System.Reflection.Missing.Value;
word.Selection.PasteSpecial(ref iconIndex,
ref link,
ref placement,
ref displayAsIcon,
ref dataType,
ref iconFileName,
ref iconLabel);
注意:C# 開發人員還會注意到,即使 PasteSpecial 的參數仍然被引用,也沒有必要使用 ref 關鍵字說明這一點。
5.從 Module1.vb (VB) 或 Program.cs (C#) 文件的 Main 方法調用 EmbedInWordDocument 方法,如下所示:
Visual Basic
Sub Main()
Dim checkAccounts = CreateAccountList()
checkAccounts.DisplayInExcel(Sub(account, cell)
cell.Value2 = account.ID
cell.Offset(0, 1).Value2 = account.Balance
cell.Offset(0, 2).Value2 = account.AccountHolder
If account.Balance < 0 Then
cell.Interior.Color = RGB(255, 0, 0)
cell.Offset(0, 1).Interior.Color = RGB(255, 0, 0)
cell.Offset(0, 2).Interior.Color = RGB(255, 0, 0)
End If
End Sub)
EmbedInWordDocument()
End Sub
C#
static void Main(string[] args)
{
var checkAccounts = CreateAccountList();
checkAccounts.DisplayInExcel((account, cell) =>
{
cell.Value2 = account.ID;
cell.get_Offset(0, 1).Value2 = account.Balance;
cell.get_Offset(0, 2).Value2 = account.AccountHolder;
if (account.Balance < 0)
{
cell.Interior.Color = 255;
cell.get_Offset(0, 1).Interior.Color = 255;
cell.get_Offset(0, 2).Interior.Color = 255;
}
});
EmbedInWordDocument();
}
下一步
練習 2:驗證
練習 2:驗證
在本驗證中,您將運行控制台應用程序並可以看到,除了應用程序在上一個驗證中執行的活動外,您的 Excel 工作表也嵌入到了 Microsoft Word 應用程序中。
1.在 Visual Studio 中,按 F5 鍵以調試模式運行應用程序。
2.可以看到,和之前一樣,應用程序啟動了 Microsoft Excel 的一個實例並將您的數據插入到第一個工作表中。
3.創建了 Excel 工作表後,應用程序將會在 Microsoft Word 的一個實例中啟動並將您的數據插入到文檔中:
圖 3
Word 文檔中的帳戶數據
4.關閉 Excel 和 Word。不要保存任何更改。
下一步
練習 3:從應用程序移除 PIA 依賴關系
練習 3:從應用程序移除 PIA 依賴關系
Office 編程功能依賴於 Office PIA 類型來與 Office 套件中的各種應用程序進行交互。過去,由於多種原因,這極大地影響了自定義 Office 應用程序的部署。第一,不同版本的 Ofice 使用不同版本的 PIA,所以管理程序集變得很復雜。第二,IT 人員必須確定部署策略,確保所需的 PIA 資源在其支持庫中可用。另外,部署應用程序的 PIA 會導致安裝程序較大,安裝了不需要的無用功能。
注意:主互操作程序集(PIA)是所有 .NET framework 應用程序與 COM 組件進行交互的關鍵部分。常規互操作程序集用於描述 COM 類型,支持在編譯時將托管代碼與 COM 類型綁定。互操作程序集還有助於 CLR 了解在運行時如何封送這些 COM 類型。主互操作程序集與常規互操作程序集的不同之處在於,它是所有類型描述的“正式”所有者,並由供應商簽署以確保其有效性。
Visual Studio 2010 中的開發通過從應用程序清除 PIA 依賴關系減輕了這些負擔。清除了依賴關系後,編譯器將直接從 PIA 導入應用程序所需的任何類型;您只需部署應用程序,並了解您所需的所有 PIA 是否都包含在您的應用程序集中。
任務 1 –檢查 PIA 依賴關系是否已被默認清除
在 Visual Studio 2010 中,默認已清除了 PIA 依賴關系,要驗證這一點:
1.從 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打開 Microsoft Visual Studio 2010。
2.打開 OfficeApplication.sln 解決方案文件。默認情況下,該文件位於以下文件夾:%TrainingKitInstallFolder%\Labs\Dev10Office \Source\RemovingPIA\Begin\,並選擇您喜歡的語言。您也可以繼續使用上一個練習完成時獲得的解決方案。
3.展開項目的 References。
4.右鍵單擊項目引用中的 Microsoft.Office.Interop.Excel,並選擇 Properties。
5.注意,Embed Interop Types 的值設置為 True。
6.右鍵單擊項目引用中的 Microsoft.Office.Interop.Word,並選擇 Properties。
7.注意,Embed Interop Types 的值設置為 True。
在本實驗中,您看到了使用 Office 創建自定義應用程序的簡單性。您使用了新的語言功能,如 Visual Basic 新的自動屬性和集合初始化程序,這些新功能使您能夠快速構建類和方法。
對於其他語言功能,您還看到了 C# 4.0 的可選參數,並了解了該功能如何讓使用 Office 的 PIA 變得更簡潔且不易出錯。此外,您還學習了 Visual Basic 的多行 lambda,以及語句 lambda 如何使您簡潔地將代理變為合適的語句。
最後,您還學習了如何將互操作類型嵌入 Office 業務應用程序中,以顯著減輕部署 Office 應用程序的負擔。這是對以前的 Office 開發環境的極大改進,在以前的開發環境中,您不得不辛苦地處理多個不同版本的依賴關系。
Visual Studio 2010 的最新版本在工具、平台和語言方面的所有這些更新都會提高您創建強大、靈活的 Office 業務應用程序的能力。