我堅持在VB的路上走到黑…………
清單1.1 從應用程序對象導航到Excel中的工作表
Dim myWorkbooks As Excel.Workbooks = app.Workbooks Dim myWorkbook As Excel.Workbook = myWorkbooks.Item(1) Dim myWorksheets As Excel.Sheets = myWorkbook.Worksheets Dim myWorksheet As Excel.Worksheet myWorksheet = CType(myWorksheets.Item(1), Excel.Worksheet)
如果代碼不需要在變量中緩存每個對象模型對象,但只需要獲取一個Worksheet對象,則編寫此代碼的更有效的方法如下所示:
Dim myWorksheet As Excel.Worksheet myWorksheet = CType(app.Workbooks.Item(1).Worksheets.Item(1), Excel.Worksheet)
活代碼:第一步:創建visual basic 2017的窗體應用程序(運行環境:win 10+visual studio 2017+office 2010)
第二步:添加引用:COM的 "Microsoft Office 14.0 Object Library 2.5"(指的是Office 2010)和“程序集”的"擴展"中的"Microsoft.office.Interop.Excel 14.0.0.0"
第三步:代碼
Imports Excel = Microsoft.Office.Interop.Excel Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim app As Excel.Application = New Excel.Application Dim myWorkbook As Excel.Workbook Dim myWorksheet As Excel.Worksheet app.Visible = True myWorkbook = app.Workbooks.Add() myWorksheet = CType(myWorkbook.Sheets.Add(), Excel.Worksheet) myWorksheet.Cells(1, 1) = "這是A1" End Sub End Class
第四步:運行結果
清單1.2 使用整數或String作為Count屬性和Item屬性索引遍歷工作表集合
Dim myWorkbooks As Excel.Workbooks = app.Workbooks Dim workbookCount As Integer = myWorkbooks.Count For i As Integer = 1 To workbookCount ' Get the workbook by its integer index Dim myWorkbook As Excel.Workbook = myWorkbooks.Item(i) ' Get the workbook by its string index Dim workbookName As String = myWorkbook.Name Dim myWorkbook2 As Excel.Workbook = myWorkbooks.Item(workbookName) MsgBox(String.Format("Workbook {0}", myWorkbook2.Name)) Next
活代碼:
活代碼:第一步:創建visual basic 2017的窗體應用程序(運行環境:win 10+visual studio 2017+office 2010)
第二步:添加引用:COM的 "Microsoft Office 14.0 Object Library 2.5"(指的是Office 2010)和“程序集”的"擴展"中的"Microsoft.office.Interop.Excel 14.0.0.0"
第三步:代碼
Imports Excel = Microsoft.Office.Interop.Excel Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim app As Excel.Application = New Excel.Application Dim myWorkbook As Excel.Workbook Dim myWorksheet As Excel.Worksheet app.Visible = True myWorkbook = app.Workbooks.Add() myWorksheet = CType(myWorkbook.Sheets.Add(), Excel.Worksheet) myWorksheet.Cells(1, 1) = "這是A1" Dim worksheetCount As Integer = myWorkbook.Worksheets.Count For i As Integer = 1 To worksheetCount Dim str As String str = myWorkbook.Worksheets.Item(i).Name '以整數作為索引 MessageBox.Show(str, "獲取工作表名稱") Next For i As Integer = 1 To worksheetCount Dim str As String str = myWorkbook.Worksheets.Item("sheet" & i).Name MessageBox.Show(str, "獲取工作表名稱") '以字符串作為索引 Next End Sub End Class
第四步:運行結果
拓展假如要編輯工作表sheet2中D3單元格,並填入“我是丑丑”,該如何實現呢
Imports Excel = Microsoft.Office.Interop.Excel Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim app As Excel.Application = New Excel.Application Dim myWorkbook As Excel.Workbook Dim myWorksheet As Excel.Worksheet app.Visible = True myWorkbook = app.Workbooks.Add() 'myWorksheet = CType(myWorkbook.Sheets.Add(, , 3,), Excel.Worksheet) '第3個參數表示添加多少工作表,這里添加3個, Dim C4_sheet As Excel.Worksheet = myWorkbook.Worksheets.Item("sheet2") '工作表的索引從0開始, C4_sheet.Cells(3, 4) = "我是丑丑" 'Cells(行,列),也就是D3單元格 End Sub End Class
運行結果:
清單1.3 使用For Each結構遍歷工作簿集合
Dim myWorkbooks As Excel.Workbooks = app.Workbooks For Each workbook As Excel.Workbook In myWorkbooks MsgBox(String.Format("Workbook {0}", workbook.Name)) Next
活代碼:略
清單1.4 當刪除對象時使用輔助集合
Dim myWorkbook As Excel.Workbook = app.ActiveWorkbook Dim myCollection As New Collections.Generic.List(Of Excel.Name) For Each name As Excel.Name In myWorkbook.Names myCollection.Add(name) Next For Each name As Excel.Name In myCollection name.Delete() Next
活代碼:第一步:創建visual basic 2017的窗體應用程序(運行環境:win 10+visual studio 2017+office 2010)
第二步:添加引用:COM的 "Microsoft Office 14.0 Object Library 2.5"(指的是Office 2010)和“程序集”的"擴展"中的"Microsoft.office.Interop.Excel 14.0.0.0"
第三步:代碼
Imports Excel = Microsoft.Office.Interop.Excel Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim app As Excel.Application = New Excel.Application Dim myWorkbook As Excel.Workbook = app.ActiveWorkbook app.Visible = True myWorkbook = app.Workbooks.Add("E:\工作簿1") Dim myCollection As New Collections.Generic.List(Of Excel.Range) For Each Name As Excel.Range In myWorkbook.Worksheets("Sheet1").Range("A1:D5") '由於是刪除,所以下面的行會自動向上縮進 myCollection.Add(Name) Next For Each name As Excel.Range In myCollection name.Delete() '由於是刪除,所以下面的行會自動向上縮進 Next End Sub End Class
運行結果:
原圖:
表1.2 從Word的應用程序對象中選擇的屬性,方法和事件
名稱 |
作用 |
---|---|
屬性 |
|
ActiveDocument |
返回一個用戶正在編輯的word文檔對象 |
ActivePrinter |
獲取並設置默認打印機 |
Caption |
為word應用程序設置標題,默認被設置為 "Microsoft Word" |
Documents |
返回一個打開的word文檔集 |
方法 |
|
Activate |
將word顯示在最前,並且作為活動窗口 |
NewWindow |
創建一個新的Word窗口來顯示活動窗口,並返回一個新的窗口模型對象 。 |
Quit |
關閉word程序 |
事件 |
|
DocumentBeforeClose |
這是一個在文檔關閉之前發生的事件。如果代碼句柄將參數 Cancel 設置為true, 文檔將不會關閉 |
DocumentOpen |
打開文檔時引發的事件。 要打開的文檔的Document對象作為參數傳遞給事件。 |
WindowActivate |
當用戶激活Word窗口時,通常通過單擊非活動窗口,從而使其處於活動狀態,引發事件。 正在激活的文檔的Document對象作為參數傳遞給事件以及激活的窗口的Window對象(因為兩個窗口可能顯示相同的文檔)。 |
清單1.5 返回值類型的屬性:Word應用程序對象上的布爾CapsLock屬性
If app.CapsLock Then MsgBox("CapsLock is on") Else MsgBox("CapsLock is off") End If
清單1.6 返回枚舉的屬性:Word應用程序對象上的WindowState屬性
Select Case app.WindowState Case Word.WdWindowState.wdWindowStateMaximize MsgBox("Maximized") Case Word.WdWindowState.wdWindowStateMinimize MsgBox("Minimized") Case Word.WdWindowState.wdWindowStateNormal MsgBox("Normal") End Select
清單1.7 返回另一個對象模型對象的屬性:Word應用程序對象上的ActiveDocument屬性
Dim myDocument As Word.Document = app.ActiveDocument MsgBox(myDocument.Name)
列表1.8 可能拋出異常的屬性:Word應用程序對象上的ActiveDocument屬性
Dim myDocument As Word.Document Try myDocument = app.ActiveDocument MsgBox(myDocument.Name) Catch ex As Exception MsgBox(String.Format("No active document: {0}", ex.Message) End Try
清單1.9 可以返回的屬性:Excel應用程序對象上的ActiveWorkbook屬
Dim myWorkbook As Excel.Workbook = app.ActiveWorkbook If myWorkbook Is Nothing Then MsgBox("No active workbook") Else MsgBox(myWorkbook.Name) End If
清單1.10 枚舉參數並返回對象模型對象的參數化屬性:Word應用程序對象上的FileDialog屬性
Dim dialog As Office.FileDialog dialog = app.FileDialog(Office.MsoFileDialogType. _ msoFileDialogFilePicker) dialog.Show()
清單1.11 具有可選參數的參數化屬性:Excel應用程序對象上的范圍屬性
' 刪除第二個可選參數 Dim myRange As Excel.Range = app.Range("A1") ' 指定第二個可選參數 Dim myRange2 As Excel.Range = app.Range("A1", "B2")
默認參數化屬性
Dim myWorksheet As Excel.Worksheet myWorksheet = CType(app.Workbooks.Item(1).Worksheets.Item(1), Excel.Worksheet) '重寫上面的代碼 Dim myWorksheet As Excel.Worksheet myWorksheet = CType(app.Workbooks(1).Worksheets(1), Excel.Worksheet)
清單1.12 無參數無返回類型的方法:Word應用對象的激活方法
MsgBox("Activating the Word window.") app.Activate()
清單1.13 具有參數和無返回類型的方法:Word應用程序對象上的ChangeFileOpenDirectory方法
app.ChangeFileOpenDirectory("c:\temp") MsgBox("Will open out of temp for this session.")
清單1.14 無參數和返回類型的方法:Word應用程序對象的DefaultWebOptions方法
Dim options As Word.DefaultWebOptions = app.DefaultWebOptions() MsgBox(String.Format("Pixels per inch is {0}.", options.PixelsPerInch))
清單1.15 具有參數和返回類型的方法:Word應用程序對象上的CentimetersToPoints方法
Dim centimeters As Single = 15.0 Dim points As Single = app.CentimetersToPoints(centimeters) MsgBox(String.Format("{0} centimeters is {1} points.", centimeters, points)) '將計量單位從厘米轉換為磅。1磅=0.035厘米
'將Excel表的左邊距設置為5厘米 Worksheets("Sheet1").PageSetup.LeftMargin = Application.CentimetersToPoints(5)
清單1.16 具有可選參數和返回類型的方法:Excel應用程序對象上的CheckSpelling方法
Dim phrase1 As String = "Thes is spelled correctly." Dim phrase2 As String = "This is spelled correctly AFAIK." Dim isCorrect1 As Boolean = app.CheckSpelling(phrase1) Dim isCorrect2 As Boolean = app.CheckSpelling(phrase2, , True)
'用法 expression.CheckSpelling(Word, CustomDictionary, IgnoreUppercase) 'Word String 類型(僅與 Application對象一起使用),必需。要檢查的單詞。 'CustomDictionary Variant 類型,可選。用於表示自定義詞典文件名的字符串,如果在主詞典中找不到單詞,則會到此詞典中查找。如果忽略此參數,則將使用當前指定詞典。 'IgnoreUppercase Variant 類型,可選。如果為 True,則 Microsoft Excel 忽略那些所有字母都是大寫的單詞。如果為 False 則 Microsoft Excel 檢查那些所有字母都是大寫的單詞。如果省略該參數,則使用當前設置。
表1.3 Excel應用對象引發的事件
事件的名稱 |
什么時候它被激活 |
---|---|
當一個工作簿被創建是 |
|
SheetActivate |
當某個工作表被激活時 |
SheetBeforeDoubleClick |
當某個工作表被雙擊時 |
SheetBeforeRightClick |
當某個工作表被右擊時 |
SheetCalculate |
在某個工作表被重新計算后 |
SheetChange |
當某個工作表單元格被用戶改變時 |
SheetDeactivate |
當某個工作表被停用時 |
SheetFollowHyperlink |
當某個工作表中超鏈接被單擊時 |
SheetPivotTableUpdate |
在數據透視表被更新后 |
SheetSelectionChange |
當工作表上的選擇更改時 |
WindowActivate |
當工作表窗口被激活時 |
WindowDeactivate |
當工作表窗口被停用時 |
WindowResize |
當工作表窗口調整大小時 |
WorkbookActivate |
當工作簿被激活時 |
WorkbookAddinInstall |
當工作簿作為加載項安裝時 |
WorkbookAddinUninstall |
當工作簿作為加載項卸載時 |
WorkbookAfterXmlExport |
在工作簿數據作為XML文件導出后 |
WorkbookAfterXmlImport |
在工作簿中導入XML文件后 |
WorkbookBeforeClose |
工作簿關閉前 |
WorkbookBeforePrint |
在打印工作簿前 |
WorkbookBeforeSave |
在工作簿保存前 |
WorkbookBeforeXmlExport |
工作簿數據作為XML文件導出前 |
WorkbookBeforeXmlImport |
工作簿導入XML文件前 |
WorkbookDeactivate |
當工作簿停用時 |
WorkbookNewSheet |
當在工作簿中創建工作表時 |
WorkbookOpen |
當工作簿打開時 |
WorkbookPivotTableCloseConnection |
當透視報表連接關閉時 |
WorkbookPivotTableOpenConnection |
當透視報表連接打開時 |
WorkbookSync |
當作為文檔工作區的一部分的工作簿與服務器上的副本同步時 |
申明事件處理
Public WithEvents app As Excel.Application 'WithEvents表明Excel.Aplication的實例對象是一個可以引發事件的對象
Event WindowActivate(ByVal Wb As Excel.Workbook, ByVal Wn As Excel.Window)
Private Sub app_WindowActivate(ByVal Wb As Excel.Workbook, ByVal Wn As Excel.Window) Handles app.WindowActivate MsgBox("The window " & Wn.Caption & " was just activated.") End Sub
清單1.17 處理Excel應用程序對象的WindowActivate事件的VSTO自定義
Public Class Sheet1 Public WithEvents app As Excel.Application Private Sub app_WindowActivate(ByVal Wb As Excel.Workbook, ByVal Wn As Excel.Window) Handles app.WindowActivate MsgBox("The window " & Wn.Caption & " was just activated.") End Sub Private Sub Sheet1_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup app = Me.Application End Sub End Class
高級主題:動態處理事件
AddHandler app.WindowActivate, AddressOf Me.MyWindowActivateHandler 'AddHandler和RemoveHandler語句將傳遞要處理的事件以及將處理事件的事件處理程序方法。 當指定事件處理程序方法時,使用AddressOf關鍵字。 以下代碼使用AddHandler動態添加事件處理程序MyWindowActivateHandler來處理應用程序對象的WindowActivate事件:
RemoveHandler app.WindowActivate, AddressOf Me.MyWindowActivateHandler '刪除事件處理方法
Private Sub app_WindowActivate(ByVal Wb As Excel.Workbook, ByVal Wn As Excel.Window) MsgBox("The window " & Wn.Caption & " was just activated.") End Sub '與動態事件處理程序一樣,事件處理程序簽名必須與事件的預期簽名相匹配。 但是,當您動態處理事件時,Handles關鍵字不會用於事件處理程序簽名。 因此,WindowActivate事件的動態事件處理程序看起來像聲明性事件處理程序,但省略了Handles子句:
清單1.18 動態添加和刪除Excel應用程序對象的WindowActivate事件的事件處理程序的VSTO自定義
Public Class Sheet1 Public app As Excel.Application Private Sub MyWindowActivateHandler(ByVal Wb As Excel.Workbook, ByVal Wn As Excel.Window) MsgBox("The window " & Wn.Caption & " was just activated.") RemoveHandler app.WindowActivate, AddressOf Me.MyWindowActivateHandler End Sub Private Sub Sheet1_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup app = Me.Application AddHandler app.WindowActivate, AddressOf Me.MyWindowActivateHandler End Sub End Class
'本示例使工作簿窗口激活時最大化。 Private Sub Workbook_WindowActivate(ByVal Wn As Excel.Window) Wn.WindowState = xlMaximized End Sub
清單1.19 一個無法處理CommandBarButton單擊事件的類
Imports Excel = Microsoft.Office.Interop.Excel Imports Office = Microsoft.Office.Core Class SampleListener Private app As Excel.Application Public Sub New(ByVal application As Excel.Application) app = application End Sub ' 這里的作用是關聯Click事件,但會失敗,因為btn沒有放在一個更永久的變量中。 Public Sub ConnectEvents() Dim bar As Office.CommandBar = app.CommandBars("Standard") Dim btn As Office.CommandBarButton = bar.Controls.Add(1) If btn IsNot Nothing Then btn.Caption = "My Button" btn.Tag = "SampleListener.btn" AddHandler btn.Click, AddressOf Me.btn_Click End If End Sub ' Click事件永遠不會到達此處理程序. Public Sub btn_Click(ByVal ctrl As Office.CommandBarButton, ByRef cancelDefault As Boolean) MessageBox.Show("Button was clicked") End Sub End Class
清單1.20 一個無法處理Outlook檢查器對象的NewInspectorEvent的類
Imports Outlook = Microsoft.Office.Interop.Outlook Class SampleListener Private app As Outlook.Application Public Sub New(ByVal application As Outlook.Application) app = application End Sub ' This will appear to connect to the NewInspector event, but ' will fail because Inspectors is not put in a more permanent ' variable. Public Sub ConnectEvents() AddHandler app.Inspectors.NewInspector, _ AddressOf Me.MyNewInspectorHandler End Sub ' The NewInspector event will never reach this handler. Public Sub MyNewInspectorHandler(ByVal inspector As Outlook .Inspector) MessageBox.Show("New inspector.") End Sub End Class
清單1.21 一個類成功處理CommandBarButton單擊事件,因為它將CommandBarButton對象存儲在一個類成員變量中
Imports Excel = Microsoft.Office.Interop.Excel Imports Office = Microsoft.Office.Core Class SampleListener Private app As Excel.Application Private myBtn As Office.CommandBarButton Public Sub New(ByVal application As Excel.Application) app = application End Sub Public Sub ConnectEvents() Dim bar As Office.CommandBar = app.CommandBars("Standard") myBtn = bar.Controls.Add(1) If myBtn IsNot Nothing Then myBtn.Caption = "My Button" myBtn.Tag = "SampleListener.btn" AddHandler myBtn.Click, AddressOf Me.myBtn_Click End If End Sub Public Sub myBtn_Click(ByVal ctrl As Office.CommandBarButton, ByRef cancelDefault As Boolean) MessageBox.Show("Button was clicked") End Sub End Class
清單1.22 一個類成功處理Outlook檢查器對象的NewInspector事件,因為它將檢查器對象存儲在一個類成員變量中
Imports Outlook = Microsoft.Office.Interop.Outlook Class SampleListener Private app As Outlook.Application Private myInspectors As Outlook.Inspectors Public Sub New(ByVal application As Outlook.Application) app = application End Sub Public Sub ConnectEvents() myInspectors = app.Inspectors AddHandler myInspectors.NewInspector, _ AddressOf Me.MyNewInspectorHandler End Sub Public Sub MyNewInspectorHandler( _ ByVal inspector As Outlook.Inspector) MessageBox.Show("New inspector.") End Sub End Class