1. 程式人生 > >VSTO:使用C#開發Excel、Word【16】

VSTO:使用C#開發Excel、Word【16】

some protected leo 使用 pro .net studio 包括 con

使用工作表對象
Worksheet對象表示Excel工作簿中的工作表。Worksheet有一個Name屬性,返回工作表的名稱(例如“Sheet1”)。

工作表管理
Worksheet對象具有一個Index屬性,它為工作表窗口左下角顯示的選項卡式工作表選項卡中的工作表提供基於1的選項卡位置。您可以使用Move方法將工作表移動到不同的選項卡位置。 Move方法有兩個可選參數:一個Before參數,您可以傳遞要移動工作表之前的工作表,以及一個After參數,您可以傳遞要移動的工作表之後的工作表。如果省略了兩個可選參數,Excel將創建一個新的工作簿,並將工作表移動到新的工作簿。

也可以使用復制方法制作工作表的副本。像Move方法一樣,它需要兩個可選參數:一個Before和After參數,用於指定復制的工作表應該相對於其他工作表的位置。您可以指定Before或After,但不能同時指定兩個參數。如果省略了兩個可選參數,Excel將創建一個新的工作簿,並將工作表復制到新的工作簿。

要激活特定的工作表,請使用Activate方法。此方法通過將與工作表相關聯的第一個窗口設置為活動窗口來激活工作表。它還選擇與工作表對應的選項卡,並在活動窗口中顯示該工作表。

相當於右鍵單擊工作表選項卡,並從彈出菜單中選擇“刪除”由Delete方法提供。使用此方法時,Excel會顯示一個警告對話框。您可以通過使用Application對象的DisplayAlerts屬性來防止出現此警告對話框,該屬性將在本章前面的“控制Excel顯示的對話框和警報”一節中討論。

您可以隱藏工作表,以便通過使用Visible屬性完全不顯示其選項卡。 Visible屬性的類型為XlSheetVisibility,可以設置為xlSheetVisible,xlSheetHidden和xlSheetVeryHidden。最後一個值隱藏工作表,以便只能通過將Visible屬性設置為xlSheetVisible來再次顯示。將Visible屬性設置為xlSheetHidden隱藏工作表,但用戶仍然可以通過轉到“格式”菜單並選擇“Sheet”,然後單擊“隱藏”來取消隱藏工作表。

有時,使用Visible屬性隱藏工作表,以便該工作表可用於存儲應用程序在用戶不會看到的“臨時”工作表中使用的其他數據。 VSTO的緩存數據功能提供了更好的方法,如第18章所述。它具有額外的好處,您可以在Excel電子表格中操作隱藏的數據,而無需啟動Excel。這使您可以在服務器上預填充具有自定義數據的Excel工作表。

請註意,工作簿必須至少包含一個可見的工作表。所以當使用Delete方法和Visible屬性時,你必須牢記這個限制。如果您的代碼嘗試隱藏或刪除工作簿中的最後一個可見表單,則會拋出異常。

清單5-23說明了幾個這些屬性和方法的用法。

清單5-23 適用於工作表集合的VSTO定制

private
void ThisWorkbook_Startup(object sender, EventArgs e) { Excel.Worksheet sheetA = this.Worksheets.Add( missing, missing, missing, missing) as Excel.Worksheet; sheetA.Name = "SheetA"; Excel.Worksheet sheetB = this.Worksheets.Add( missing, missing, missing, missing) as Excel.Worksheet; sheetB.Name = "SheetB"; Excel.Worksheet sheetC = this.Worksheets.Add( missing, missing, missing, missing) as Excel.Worksheet; sheetC.Name = "SheetC"; // Tab indexes string msg = "{0} is at tab index {1}"; MessageBox.Show(String.Format(msg, sheetA.Name, sheetA.Index)); MessageBox.Show(String.Format(msg, sheetB.Name, sheetB.Index)); MessageBox.Show(String.Format(msg, sheetC.Name, sheetC.Index)); sheetC.Move(sheetA, missing); MessageBox.Show("Moved SheetC in front of SheetA"); // Tab indexes MessageBox.Show(String.Format(msg, sheetA.Name, sheetA.Index)); MessageBox.Show(String.Format(msg, sheetB.Name, sheetB.Index)); MessageBox.Show(String.Format(msg, sheetC.Name, sheetC.Index)); sheetB.Copy(sheetA, missing); Excel.Worksheet sheetD = this.Worksheets.get_Item( sheetA.Index - 1) as Excel.Worksheet; ((Excel._Worksheet)sheetA).Activate(); MessageBox.Show(String.Format( "Copied SheetB to create {0} at tab index {1}", sheetD.Name, sheetD.Index)); sheetD.Delete(); sheetA.Visible = Excel.XlSheetVisibility.xlSheetHidden; MessageBox.Show("Deleted SheetD and hid SheetA."); }

使用名稱
如前所述,您可以使用Workbook.Names在工作簿級別定義命名範圍。您還可以通過使用與Worksheet對象關聯的Names屬性來定義範圍到特定工作表的命名範圍。 Names屬性返回一個僅包含作用域到作業表的名稱的Names集合。有關Names集合的更多信息,請參閱本章前面的“使用名稱集合和名稱對象”一節。

使用工作表自定義屬性
您可以添加具有名稱和值的自定義屬性到工作表。自定義屬性是將其他隱藏信息與不想放入單元格的工作表相關聯的便捷方式。不同於與工作簿關聯的文檔屬性,Excel用戶界面中的任何位置都不顯示自定義屬性。工作表級別的自定義屬性不具有文檔屬性對其值的256個字符的限制。您可以在工作表自定義屬性中存儲更大的數據塊。

CustomProperties屬性返回與工作表關聯的自定義屬性的集合。您可以使用CustomProperties集合的Add方法添加自定義屬性,並為要創建的自定義屬性的名稱傳遞一個字符串,並為要與自定義屬性關聯的值傳遞一個對象。要獲取特定的自定義屬性,請使用CustomProperties.Item方法並傳遞要獲取的屬性的索引。不幸的是,Item方法只需要一個基於1的索引,而不是您添加的自定義屬性的名稱。因此,您必須遍歷該集合並檢查每個返回的CustomProperty對象的Name屬性,以確定是否已找到所需的自定義屬性。清單5-24顯示了創建自定義屬性,然後再次訪問的示例。

清單5-24 訪問自定義DocumentProperty對象的VSTO自定義

private void ThisWorkbook_Startup(object sender, EventArgs e)
{
  Excel.Worksheet sheet = this.Worksheets.Add(missing,
    missing, missing, missing) as Excel.Worksheet;

  // Add a custom property

  Excel.CustomProperties props = sheet.CustomProperties;

  props.Add("myProperty", "Some random value");
  props.Add("otherProperty", 1);

  // Now, enumerate the collection to find myProperty again.
  foreach (Excel.CustomProperty prop in props)
  {
    if (prop.Name == "myProperty")
    {
      MessageBox.Show(String.Format(
        "{0} property is set to {1}.",
        prop.Name, prop.Value));
      break;
    }
  }
}

如果您使用VSTO將代碼與工作簿相關聯,通常最好使用緩存數據而不是自定義屬性。 緩存的數據功能可以將數據集和任何XML可序列化類型放入文檔中的數據島。 該數據島也可以在服務器上訪問而不啟動Excel。 有關VSTO的緩存數據功能的更多信息,請參見第18章。

保護工作表
Protect方法保護工作表,使用戶不能修改工作表。 當使用Protect方法保護工作表時,工作簿中的所有單元都將被自動鎖定。 保護方法對應於圖5-3所示的“保護工作表”對話框。 您可以通過選擇工具>保護>保護頁面訪問該對話框。


圖5-3 保護工作表對話框。

技術分享

傳遞給Protect方法的一些可選參數精確地控制可以修改的內容,如表5-14所示。 許多這些選項對應於圖5-3所示的檢查列表。

表5-14 保護方法的可選參數

技術分享

技術分享

當工作表受保護時,您有兩種排除某些範圍的單元格被鎖定的方法。 第一種方法是使用從Worksheet.Protection.AllowEdit-Ranges返回的AllowEditRanges集合來添加排除對象。 AllowEditRanges集合對應於允許用戶編輯範圍對話框,如圖5-4所示。 您可以通過選擇工具>保護>允許用戶編輯範圍來訪問此對話框。


圖5-4 允許用戶編輯範圍對話框

技術分享

必須先使用AllowEditRanges集合進行排除,然後再使用Protect方法來保護工作表。 在保護工作表之後,在重新取消保護工作表之前,不能對AllowEditRanges集合進行任何更改。 以此方式進行排除,可以給出標題,並顯示在“允許用戶編輯範圍”對話框中。 以這種方式從保護中排除的範圍將從其Range.AllowEdit屬性返回TRue。 清單5-25顯示了一個VSTO自定義,它使用AllowEditRanges創建兩個保護的排除,然後使用Protect方法保護工作表。

清單5-25 使用AllowEditRanges將禁止添加到保護的VSTO自定義

private void ThisWorkbook_Startup(object sender, EventArgs e)
{
  Excel.Worksheet sheet = this.Worksheets.Add(missing,
    missing, missing, missing) as Excel.Worksheet;

  Excel.AllowEditRanges allowEdits = sheet.Protection.
    AllowEditRanges;

  allowEdits.Add("Editable Cell",
    sheet.get_Range("A1", missing), missing);

  sheet.Protect(missing, missing, missing, missing,
    missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing,
    missing, missing);

  Excel.Range protectedRange = sheet.get_Range("A2", missing);


  MessageBox.Show(String.Format(
    "A2‘s Locked is set to {0}", protectedRange.Locked));

  MessageBox.Show(String.Format(
    "A2‘s AllowEdit is set to {0}", protectedRange.AllowEdit));

  try
  {
    protectedRange.Value2 = "Should fail";
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message);
  }

  try
  {
    allowEdits.Add("This should fail",
      sheet.get_Range("A2", missing), missing);
  }
  catch (Exception ex)
  {
    // You can‘t add to the AllowEditRanges collection
    // when the worksheet is protected
    MessageBox.Show(ex.Message);
  }

  Excel.Range allowEditRange = sheet.get_Range("A1", missing);

  MessageBox.Show(String.Format(
    "A1‘s Locked is set to {0}", allowEditRange.Locked));

  MessageBox.Show(String.Format(
    "A1‘s AllowEdit is set to {0}", allowEditRange.AllowEdit));

  allowEditRange.Value2 = "Should succeed";
}

當工作表被保護時,排除某些範圍的單元格被鎖定的第二種方法是使用Range.Locked屬性。 以這種方式排除的單元格不會顯示在“允許用戶編輯範圍”對話框中。 清單5-26顯示了使用Range.Locked屬性添加排除對保護。

清單5-26 使用Range.Locked添加排除對象的VSTO自定義

private void ThisWorkbook_Startup(object sender, EventArgs e)
{
  Excel.Worksheet sheet = this.Worksheets.Add(missing,
    missing, missing, missing) as Excel.Worksheet;

  Excel.Range range1 = sheet.get_Range("A2", missing);
  range1.Locked = false;

  sheet.Protect(missing, missing, missing, missing,
    missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing,
    missing, missing);

  MessageBox.Show(String.Format(
    "A2‘s Locked is set to {0}", range1.Locked));

  MessageBox.Show(String.Format(
    "A2‘s AllowEdit is set to {0}", range1.AllowEdit));

  range1.Value2 = "Should succeed";
}

工作表受保護後,可以通過多個屬性來檢查文檔的保護設置,並進一步修改保護選項,如表5-15所示。

表5-15 允許您檢查並進一步修改文檔保護的屬性

技術分享

使用OLEObjects
除了包含單元格,工作表還可以包含來自其他程序(如嵌入式Word文檔)和ActiveX控件的嵌入對象。要使用這些對象,可以在Worksheet對象上使用OLEObjects方法。 OLEObjects方法接受一個可選的Index對象參數,您可以傳遞OLEObject的名稱或集合中OLEObject的基於1的索引。 OLEObjects方法也可以作為一種訪問OLEObjects集合的方式,這可能令人困惑。如果你傳遞一個字符串,它表示為一個名字或一個基於1的索引作為一個int,它返回指定的OLEObject。如果您傳遞它Type.Missing,它返回OLEObjects集合。

任何時候,將OLEObject添加到工作表中,Excel還包括從“工作表”對象中的“樣式”屬性返回的“形狀”集合中的該對象。要獲取OLEObject唯一的屬性,可以使用Shape.OLEFormat屬性。

可以編寫將ActiveX控件添加到工作表中的C#代碼,並通過將OLEObject.Object或Shape.OLEFormat.Object轉換為適當的類型與它們進行交談。您必須在C#項目中添加與要使用的ActiveX控件相關聯的COM庫的引用。這樣做會導致Visual Studio生成一個互操作程序集並將其添加到您的項目中。或者,如果為COM庫註冊了主互操作程序集,Visual Studio將自動添加對預生成的主互操作程序集的引用。然後,您可以將OLEObject.Object或Shape.OLEFormat.Object轉換為Visual Studio為與ActiveX控件相對應的COM庫對象添加的正確類型。

VSTO使您能夠將Windows Forms控件添加到工作表中,功能更強大,以.NET為中心的處理控件的方式。因此,我們不會在本書中更多地使用ActiveX控件。有關VSTO對Windows Forms控件的支持的更多信息,請參見第14章“在VSTO中使用Windows窗體”。

使用形狀
Shapes屬性返回Shape對象的Shapes集合集合。 Shape對象表示可以插入到Excel電子表格中的各種對象,包括圖形,AutoShape,藝術字,嵌入對象或ActiveX控件或圖片。

“形狀”集合具有“Count”屬性,用於確定“工作表”中有多少個形狀。它還有一個Item方法,它采用基於1的索引來獲取集合中的特定形狀。您還可以使用foreach枚舉Shapes集合。

“形狀”集合上的幾種方法可以添加可以表示為“形狀”的各種對象。這些方法包括AddCallout,AddConnector,AddCurve,AddDiagram,AddLabel,AddLine,AddOLEObject,AddPicture,AddPolyline,AddShape,AddTextbox和AddTextEffect。

Shape對象具有將Shape置於工作表上的屬性和方法。它還具有允許格式化和修改Shape對象的屬性和方法。 Shape對象上的屬性返回的一些對象如圖3-20所示。

使用ChartObjects
在本書中,當引用工作簿中的工作表的圖表時,我們使用了短語圖表。圖5-5顯示了在插入新圖表時顯示的圖表向導的最後一頁。 Excel使您能夠將圖表插入新的圖表,我們稱之為圖表單,並允許您將圖表作為對象添加到工作表中。對象模型調用在表單中添加為對象的圖表。


圖5-5 圖表向導的圖表位置步驟

技術分享

事情更復雜的是,圖表表的對象模型中的對象是一個圖表,但ChartObject也有一個返回圖表的屬性。 ChartObject具有自己的一組屬性,用於控制工作表中圖表的位置。但是,由ChartObject.Chart屬性返回的Chart對象可以找到實際操作圖表內容的屬性和方法。

要使用ChartObjects,可以在Worksheet對象上使用ChartObjects方法。 ChartObjects方法接受類型對象的可選索引參數,您可以傳遞集合中ChartObject的名稱或ChartObject的基於1的索引。 ChartObjects方法也可以作為獲取ChartObjects集合的一種方式,這可能會令人困惑。如果您傳遞一個表示為名稱或基於1的索引的字符串,則返回指定的ChartObject。如果您傳遞它Type.Missing,它返回ChartObjects集合。

要將ChartObject添加到工作表中,可以使用ChartObjects.Add方法,它將“左”,“頂”,“寬”和“高”作為點的雙精度值。每當您將ChartObject添加到工作表中時,Excel也會在“工作表”對象中的“Shapes”屬性返回的“Shapes”集合中包含該對象。

使用列表
Excel 2003引入了從一系列單元格創建列表的功能。只需選擇一系列單元格,右鍵單擊選擇,然後選擇創建列表。列表具有列標題和下拉選項,使用戶可以輕松地對列表中的數據進行排序和應用過濾器。它有一個總計行,可以自動求和並對一列數據執行其他操作。它在列表底部有一個標有星號的插入行,允許用戶向列表中添加其他行。圖5-6顯示了Excel中的列表示例。


圖5-6 Excel中的列表

技術分享

您可以使用ListObjects屬性訪問工作表中的列表。 ListObjects屬性返回ListObjects集合。 ListObjects集合有一個Count屬性來確定Worksheet中有多少列表。 它還有一個Item方法,它將一個基於索引的索引或列表對象的名稱作為一個字符串來從集合中獲取一個ListObject對象。 您還可以使用foreach枚舉ListObjects集合。

表5-16顯示了ListObject對象的一些最常用的屬性。 您將在第17章“VSTO數據編程”中討論VSTO對數據的支持的更多信息。

表5-16 ListObject的關鍵屬性

技術分享

VSTO:使用C#開發Excel、Word【16】