逐步解說:變更伺服器上的活頁簿快取資料
本逐步解說示範如何在不啟動 Excel 的情況下使用 ServerDocument 類別,修改 Microsoft Office Excel 活頁簿中快取的資料集。
**適用於:**本主題中的資訊適用於 Excel 2013 和 Excel 2010 的文件層級專案。如需詳細資訊,請參閱依 Office 應用程式和專案類型提供的功能。
這個逐步解說將說明下列工作:
定義資料集,其中包含 AdventureWorksLT 資料庫中的資料。
在 Excel 活頁簿專案和主控台應用程式專案中建立資料集的執行個體。
建立繫結至活頁簿之資料集的 ListObject,並在活頁簿開啟時將資料填入 ListObject。
將活頁簿中的資料集加入至資料快取。
在未啟動 Excel 的情況下,藉由在主控台應用程式執行程式碼,修改快取資料集中資料的資料行。
雖然這個逐步解說假設您正在開發電腦上執行程式碼,但是它所示範的程式碼可以在沒有安裝 Excel 的伺服器上使用。
注意事項 |
---|
在下列指示的某些 Visual Studio 使用者介面項目中,您的電腦可能會顯示不同的名稱或位置:您所擁有的 Visual Studio 版本和使用的設定決定了這些項目。如需詳細資訊,請參閱Visual Studio 設定。 |
必要條件
您需要下列元件才能完成此逐步解說:
-
包含 Microsoft Office Developer 工具的 Visual Studio 2012 版本。如需詳細資訊,請參閱[設定電腦以開發 Office 方案](bb398242\(v=vs.110\).md)。
Excel 2010.
存取附加了 AdventureWorksLT 範例資料庫之執行中的 Microsoft SQL Server 或 Microsoft SQL Server Express 執行個體。您可以從 CodePlex 網站 (英文) 下載 AdventureWorksLT 資料庫。如需附加資料庫的詳細資訊,請參閱下列主題:
若要使用 SQL Server Management Studio 或 SQL Server Management Studio Express 來附加資料庫,請參閱 HOW TO:附加資料庫 (SQL Server Management Studio)。
若要使用命令列來附加資料庫,請參閱 HOW TO:將資料庫檔案附加至 SQL Server Express。
建立定義資料集的類別庫專案
若要在 Excel 活頁簿專案和主控台應用程式專案中使用相同的資料集,您必須在這兩個專案同時參考的另一個組件中定義資料集。在本逐步解說中,請於類別庫專案中定義資料集。
若要建立類別庫專案
啟動 Visual Studio。
在 [檔案] 功能表上,指向 [新增],然後按一下 [專案]。
在 [範本] 窗格中,展開 [Visual C#] 或 [Visual Basic],然後按一下 [Windows]。
在專案範本清單中,選取 [類別庫]。
在 [名稱] 方塊中輸入 AdventureWorksDataSet。
按一下 [瀏覽],巡覽至您的 %UserProfile%\My Documents (適用於 Windows XP (含) 以前版本) 或 %UserProfile%\Documents (適用於 Windows Vista) 資料夾,然後按一下 [選取資料夾]。
在 [新增專案] 對話方塊中,確認未選取 [為方案建立目錄] 核取方塊。
按一下 [確定]。
Visual Studio 會將 AdventureWorksDataSet 專案加入至 [方案總管],並開啟 Class1.cs 或 Class1.vb 程式碼檔案。
在 [方案總管] 中,以滑鼠右鍵按一下 [Class1.cs] 或 [Class1.vb],再按一下 [刪除]。在這個逐步解說中,您不需要這個檔案。
在類別庫專案中定義資料集
定義具型別資料集,其中包含 SQL Server 2005 之 AdventureWorksLT 資料庫中的資料。在此逐步解說稍後的內容中,您會從 Excel 活頁簿專案和主控台應用程式專案參考這個資料集。
此資料集是「具型別資料集」(Typed Dataset),表示 AdventureWorksLT 資料庫之 Product 資料表中的資料。如需具型別資料集的詳細資訊,請參閱 使用 Visual Studio 中的資料集。
若要在類別庫專案中定義具型別資料集
在 [方案總管] 中,按一下 [AdventureWorksDataSet] 專案。
如果 [資料來源] 視窗中不可見,請顯示它,請在功能表列上,選擇 [檢視]],則 [其他視窗], [資料來源]。
選取 [加入新資料來源] 啟動 [資料來源組態精靈]。
按一下 [資料庫],然後按 [下一步]。
如果您有現有的 AdventureWorksLT 資料庫連接,請選擇此連接,再按 [下一步]。
否則,請按一下 [新增連接],並使用 [加入連接] 對話方塊建立新連接。如需詳細資訊,請參閱HOW TO:連接至資料庫中的資料。
在 [將連接字串儲存到應用程式組態檔] 頁面上,按 [下一步]。
在 [選擇您的資料庫物件] 頁面中,展開 [資料表],並選取 [Product (SalesLT)]。
按一下 [完成]。
AdventureWorksLTDataSet.xsd 檔案隨即加入至 AdventureWorksDataSet 專案。這個檔案定義下列項目:
名稱為 AdventureWorksLTDataSet 的具型別資料集。這個資料集表示 AdventureWorksLT 資料庫中 Product 資料表的內容。
名為 ProductTableAdapter 的 TableAdapter。這個 TableAdapter 可以用來讀取和寫入 AdventureWorksLTDataSet 中的資料。如需詳細資訊,請參閱TableAdapter 概觀。
在這個逐步解說後面的步驟中,您會用到這兩個物件。
在 [方案總管] 中,以滑鼠右鍵按一下 [AdventureWorksDataSet],再按一下 [建置]。
接著驗證專案建置無誤。
建立 Excel 活頁簿專案
建立資料介面的 Excel 活頁簿專案。在此逐步解說稍後的內容中,您會建立顯示資料的 ListObject,也會將資料集的執行個體加入至活頁簿的資料快取。
若要建立 Excel 活頁簿專案
在 [方案總管] 中,以滑鼠右鍵按一下 [AdventureWorksDataSet] 方案,指向 [加入],再按一下 [新增專案]。
在範本窗格中,展開 [Visual C#] 或 [Visual Basic],接著展開 [Office]。
在展開的 [Office] 節點下,選取 [2010 年] 節點。
在專案範本清單中,選取 Excel 活頁簿專案。
在 [名稱] 方塊中輸入 AdventureWorksReport。請勿修改位置。
按一下 [確定]。
[Visual Studio Tools for Office 專案精靈] 便會開啟。
確認已選取 [建立新文件],然後按一下 [確定]。
Visual Studio 會在設計工具中開啟 AdventureWorksReport 活頁簿,並將 AdventureWorksReport 專案加入至 [方案總管]。
將資料集加入至 Excel 活頁簿專案中的資料來源
您必須先將資料集加入至 Excel 活頁簿專案中的資料來源,才能在 Excel 活頁簿中顯示資料集。
若要將資料集加入至 Excel 活頁簿專案中的資料來源
在 [方案總管] 中,按兩下 [AdventureWorksReport] 專案底下的 [Sheet1.cs] 或 [Sheet1.vb]。
活頁簿就會在設計工具中開啟。
在 [資料] 功能表上,請按一下 [加入新資料來源]。
[資料來源組態精靈] 隨即開啟。
按一下 [物件],然後按 [下一步]。
在 [選取您要繫結的目標物件] 頁面中,按一下 [加入參考]。
在 [專案] 索引標籤上,按一下 [AdventureWorksDataSet],然後按 [確定]。
在 [AdventureWorksDataSet] 組件的 [AdventureWorksDataSet] 命名空間底下,按一下 [AdventureWorksLTDataSet],然後按一下 [完成]。
[資料來源] 視窗隨即開啟,而且 [AdventureWorksLTDataSet] 也會加入至資料來源清單中。
建立繫結至資料集執行個體的 ListObject
若要將資料集顯示在活頁簿中,請建立繫結至資料集執行個體的 ListObject。如需將控制項繫結至資料的詳細資訊,請參閱將資料繫結至 Office 方案中的控制項。
若要建立繫結至資料集執行個體的 ListObject
在 [資料來源] 視窗中,展開 [AdventureWorksDataSet] 底下的 [AdventureWorksLTDataSet] 節點。
選取 [產品] 節點,按一下出現的下拉箭號,然後在下拉式清單中選取 [ListObject]。
如果下拉箭號沒有出現,請確認活頁簿已在設計工具中開啟。
將 [產品] 資料表拖曳至儲存格 A1。
工作表中會建立一個名為 productListObject 的 ListObject 控制項 (從儲存格 A1 開始)。同時,也會將名為 adventureWorksLTDataSet 的資料集物件和名為 productBindingSource 的 BindingSource 加入至專案。ListObject 會繫結至 BindingSource,而後者則繫結至資料集物件。
將資料集加入至資料快取
若要讓 Excel 活頁簿專案外部的程式碼能夠存取活頁簿中的資料集,您必須將資料集加入至資料快取。如需資料快取的詳細資訊,請參閱文件層級自訂中的快取資料和快取資料。
若要將資料集加入至資料快取
在設計工具中,按一下 [adventureWorksLTDataSet]。
在 [屬性] 視窗中,將 [Modifiers] 屬性設定為 [Public]。
將 [CacheInDocument] 屬性設定為 [True]。
初始化活頁簿中的資料集
您必須先將資料填入快取的資料集,才能透過主控台應用程式從快取資料集擷取資料。
若要初始化活頁簿中的資料集
以滑鼠右鍵按一下 [方案總管] 中的 [Sheet1.cs] 或 [Sheet1.vb] 檔案,然後按一下 [檢視程式碼]。
以下列程式碼取代 Sheet1_Startup 事件處理常式。如果快取的資料集目前是空白,此程式碼會使用 AdventureWorksDataSet 專案中定義之 ProductTableAdapter 類別的執行個體,將資料填入快取的資料集。
Private ProductTableAdapter As New _ AdventureWorksDataSet.AdventureWorksLTDataSetTableAdapters.ProductTableAdapter() Private Sub Sheet1_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup If Me.NeedsFill("AdventureWorksLTDataSet") Then Me.ProductTableAdapter.Fill(Me.AdventureWorksLTDataSet.Product) End If End Sub
private AdventureWorksDataSet.AdventureWorksLTDataSetTableAdapters.ProductTableAdapter productTableAdapter = new AdventureWorksDataSet.AdventureWorksLTDataSetTableAdapters.ProductTableAdapter(); private void Sheet1_Startup(object sender, System.EventArgs e) { if (this.NeedsFill("adventureWorksLTDataSet")) { this.productTableAdapter.Fill(this.adventureWorksLTDataSet.Product); } }
檢查點
建置並執行 Excel 活頁簿專案,以確保此專案能正確編譯及執行。這項作業也會填滿快取的資料集,並將資料儲存在活頁簿中。
若要建置及執行專案
在 [方案總管] 中,以滑鼠右鍵按一下 [AdventureWorksReport] 專案,選擇 [偵錯],然後按一下 [開始新執行個體]。
專案已建置,而且活頁簿會在 Excel 中開啟。驗證下列各項:
ListObject 中會填滿資料。
ListObject 中第一列的 ListPrice 欄值為 1431.5。稍後在本逐步解說中,您會使用主控台應用程式修改 ListPrice 欄值。
儲存活頁簿。請勿修改活頁簿的檔案名稱或位置。
關閉 Excel。
建立主控台應用程式專案
您可以建立主控台應用程式專案,用來修改活頁簿中快取資料集內的資料。
若要建立主控台應用程式專案
在 [方案總管] 中,以滑鼠右鍵按一下 [AdventureWorksDataSet] 方案,指向 [加入],再按一下 [新增專案]。
在 [專案類型] 窗格中,展開 [Visual C#] 或 [Visual Basic],然後按一下 [Windows]。
在 [範本] 窗格中選取 [主控台應用程式]。
在 [名稱] 方塊中,輸入 DataWriter。請勿修改位置。
按一下 [確定]。
Visual Studio 會將 DataWriter 專案加入至 [方案總管],並開啟 Program.cs 或 Module1.vb 程式碼檔。
使用主控台應用程式變更快取資料集的資料
在主控台應用程式中使用 ServerDocument 類別,將資料讀入本機 AdventureWorksLTDataSet 物件、修改此資料,然後再儲存回快取資料集。
若要變更快取資料集的資料
在 [方案總管] 中,以滑鼠右鍵按一下 [DataWriter] 專案,再按一下 [加入參考]。
在 [.NET] 索引標籤上,選取 Microsoft.VisualStudio.Tools.Applications。
按一下 [確定]。
在 [方案總管] 中,以滑鼠右鍵按一下 [DataWriter] 專案,再按一下 [加入參考]。
在 [專案] 索引標籤上,選取 [AdventureWorksDataSet],然後按一下 [確定]。
在程式碼編輯器中開啟 Program.cs 或 Module1.vb 檔案。
將下列 using (適用於 C#) 或 Imports (適用於 Visual Basic) 陳述式加入至程式碼檔案的最上方。
Imports Microsoft.VisualStudio.Tools.Applications
using Microsoft.VisualStudio.Tools.Applications;
將以下程式碼加入至 Main 方法中。這個程式碼會宣告下列物件:
AdventureWorksLTDataSet 型別的執行個體,這個執行個體是在 AdventureWorksDataSet 專案中定義。
AdventureWorksReport 專案之組建資料夾中 AdventureWorksReport 活頁簿的路徑。
要用來在活頁簿中存取資料快取的 ServerDocument 物件。
注意事項 下列程式碼假設您使用的是副檔名為 .xlsx 的活頁簿。如果專案中的活頁簿是使用不同的副檔名,請視需要修改路徑。
Dim productDataSet As New AdventureWorksDataSet.AdventureWorksLTDataSet() Dim workbookPath As String = System.Environment.GetFolderPath( _ Environment.SpecialFolder.MyDocuments) & _ "\AdventureWorksReport\bin\Debug\AdventureWorksReport.xlsx" Dim serverDocument1 As ServerDocument = Nothing
AdventureWorksDataSet.AdventureWorksLTDataSet productDataSet = new AdventureWorksDataSet.AdventureWorksLTDataSet(); string workbookPath = System.Environment.GetFolderPath( Environment.SpecialFolder.MyDocuments) + @"\AdventureWorksReport\bin\Debug\AdventureWorksReport.xlsx"; ServerDocument serverDocument1 = null;
將下列程式碼加入至 Main 方法中,加入的位置是您在前一個步驟中加入的程式碼後面。這個程式碼會執行下列工作:
它會使用 ServerDocument 類別的 CachedData 屬性來存取活頁簿中的快取資料集。
它會將快取資料集的資料讀入本機資料集。
變更資料集的 Product 資料表中每個產品的 ListPrice 值。
儲存活頁簿中快取資料集的變更。
Try serverDocument1 = New ServerDocument(workbookPath) Dim dataHostItem1 As CachedDataHostItem = _ serverDocument1.CachedData.HostItems("AdventureWorksReport.Sheet1") Dim dataItem1 As CachedDataItem = dataHostItem1.CachedData("AdventureWorksLTDataSet") If dataItem1 IsNot Nothing Then Console.WriteLine("Before reading data from the cache dataset, the local dataset has " & _ "{0} rows.", productDataSet.Product.Rows.Count.ToString()) ' Read the cached data from the worksheet dataset into the local dataset. Dim schemaReader As New System.IO.StringReader(dataItem1.Schema) Dim xmlReader As New System.IO.StringReader(dataItem1.Xml) productDataSet.ReadXmlSchema(schemaReader) productDataSet.ReadXml(xmlReader) Console.WriteLine("After reading data from the cache dataset, the local dataset has " & _ "{0} rows.", productDataSet.Product.Rows.Count.ToString()) ' Modify the prices of each product in the local dataset. Dim row As AdventureWorksDataSet.AdventureWorksLTDataSet.ProductRow For Each row In productDataSet.Product.Rows If row.ProductCategoryID < 20 Then row.ListPrice = row.ListPrice + row.ListPrice * 0.1 Else row.ListPrice = row.ListPrice - row.ListPrice * 0.1 End If Next row ' Write the modified local dataset to the worksheet dataset using the DiffGram format. Dim stringIn As New System.Text.StringBuilder() Dim stringOut As New System.IO.StringWriter(stringIn) productDataSet.WriteXml(stringOut, System.Data.XmlWriteMode.DiffGram) dataItem1.Xml = stringIn.ToString() serverDocument1.Save() Console.WriteLine("The product prices have been modified.") Else Console.WriteLine("The data object is not found in the data cache.") End If Catch ex As System.IO.FileNotFoundException Console.WriteLine("The specified workbook does not exist.") Catch ex As System.Xml.XmlException Console.WriteLine("The data object has invalid XML information.") Finally If Not (serverDocument1 Is Nothing) Then serverDocument1.Close() End If Console.WriteLine(vbLf & vbLf & "Press Enter to close the application.") Console.ReadLine() End Try
try { serverDocument1 = new ServerDocument(workbookPath); CachedDataHostItem dataHostItem1 = serverDocument1.CachedData.HostItems["AdventureWorksReport.Sheet1"]; CachedDataItem dataItem1 = dataHostItem1.CachedData["adventureWorksLTDataSet"]; if (dataItem1 != null) { Console.WriteLine("Before reading data from the cache dataset, the local dataset has " + "{0} rows.", productDataSet.Product.Rows.Count.ToString()); // Read the cached data from the worksheet dataset into the local dataset. System.IO.StringReader schemaReader = new System.IO.StringReader(dataItem1.Schema); System.IO.StringReader xmlReader = new System.IO.StringReader(dataItem1.Xml); productDataSet.ReadXmlSchema(schemaReader); productDataSet.ReadXml(xmlReader); Console.WriteLine("After reading data from the cache dataset, the local dataset has " + "{0} rows.", productDataSet.Product.Rows.Count.ToString()); // Modify the prices of each product in the local dataset. foreach (AdventureWorksDataSet.AdventureWorksLTDataSet.ProductRow row in productDataSet.Product.Rows) { if (row.ProductCategoryID < 20) { row.ListPrice = row.ListPrice + (row.ListPrice * (Decimal).10); } else { row.ListPrice = row.ListPrice - (row.ListPrice * (Decimal).10); } } // Write the modified local dataset to the worksheet dataset using the DiffGram format. System.Text.StringBuilder stringIn = new System.Text.StringBuilder(); System.IO.StringWriter stringOut = new System.IO.StringWriter(stringIn); productDataSet.WriteXml(stringOut, System.Data.XmlWriteMode.DiffGram); dataItem1.Xml = stringIn.ToString(); serverDocument1.Save(); Console.WriteLine("The product prices have been modified."); } else { Console.WriteLine("The data object is not found in the data cache."); } } catch (System.IO.FileNotFoundException) { Console.WriteLine("The specified workbook does not exist."); } catch (System.Xml.XmlException) { Console.WriteLine("The data object has invalid XML information."); } finally { if (serverDocument1 != null) { serverDocument1.Close(); } Console.WriteLine("\n\nPress Enter to close the application."); Console.ReadLine(); }
在 [方案總管] 中,以滑鼠右鍵按一下 [DataWriter] 專案,指向 [偵錯],然後按一下 [開始新執行個體]。
主控台應用程式會在將快取資料集讀入本機資料集、修改本機資料集中的產品單價,以及儲存新值到快取資料集時顯示訊息。按 ENTER 鍵關閉應用程式。
測試活頁簿
開啟活頁簿時,ListObject 現在會顯示您對快取資料集中資料的 ListPrice 資料行所進行的變更。
若要測試活頁簿
如果 Visual Studio 設計工具中的 AdventureWorksReport 活頁簿仍然開啟,請將它關閉。
開啟位在 AdventureWorksReport 專案建置資料夾中的 AdventureWorksReport 活頁簿。根據預設,建置資料夾位於下列其中一個位置:
%UserProfile%\My Documents\AdventureWorksReport\bin\Debug (適用於 Windows XP (含) 以前版本)
%UserProfile%\Documents\AdventureWorksReport\bin\Debug (適用於 Windows Vista)
確認 ListObject 第一個資料列的 [ListPrice] 資料行現在的值為 1574.65。
關閉活頁簿。