我在理解以下概念時遇到困難。前段時間我發布了一個問題- 通讀答案,但有些事情仍然不清楚。我在下面陳述我的困惑:
我的第一個問題是指以下代碼片段
Option Strict On
Imports Microsoft.Office.Interop
Dim oxl As Excel.Application
oxl = CreateObject("Excel.Application")
在上面的代碼段中,該陳述句oxl = CreateObject("Excel.Application")拋出一個錯誤,指出Option Strict On disallows implicit conversions from Object to Application. 我的問題是我從許多來源中了解到,始終保持 Option Strict ON 總是更好,但在這種情況下,當我們需要創建一個新的 excel 應用程式時,Option Strict ON 會阻止我們這樣做。那么對于這種沖突應該遵循的最佳實踐是什么?
接下來我嘗試oxl = CreateObject("Excel.Application")用oxl = New Excel.Application. 據觀察,即使 Option Strict ON,我們也可以使用 NEW 關鍵字創建一個新的 excel 應用程式物件。還使用 GetType 進行了檢查,在這兩種情況下,即使用 CreateObject 和 NEW,創建的物件的型別是:System._ComObject。所以我的問題是,如果創建的物件的型別保持不變,為什么 Option Strict 不允許CreateObject但是允許使用創建 excel 應用程式物件NEW?
為了進一步研究它,我將上面的代碼擴展到以下內容:
Option Strict On
Imports System
Imports Microsoft.Office.Interop
Module Program
Dim oxl As Excel.Application
Dim owb As Excel.Workbook
Dim osheet As Excel.Worksheet
Sub Main()
oxl = New Excel.Application
'oxl = CreateObject("Excel.Application")
Console.WriteLine(oxl.GetType)
oxl.Visible = True
owb = oxl.Workbooks.Add()
osheet = owb.Worksheets("Sheet1") ‘Error: Option Strict ON disallows implicit conversions from ‘Object’ to ‘Worksheet’
osheet.Range("A1").Value = 53
Console.WriteLine("Hello World!")
Console.ReadLine()
End Sub
End Module
當我們運行代碼時,我們看到錯誤Option Strict ON disallows implicit conversions from ‘Object’ to ‘Worksheet’出現在以下行:osheet = owb.Worksheets("Sheet1")
問題:
為什么會出現錯誤?我的意思是如果,owb = oxl.Workbooks.Add()可以作業(它回傳一個由 參考的作業簿owb)那么為什么osheet = owb.Worksheets("Sheet1")不作業,因為右側回傳osheet應該能夠指向的作業簿的“Sheet1”(假設它是型別Excel.Worksheet)?
uj5u.com熱心網友回復:
有時它只是沒有比物件更具體的資訊。如果您不使用默認屬性并Item改為使用owb.Worksheets.Item("Sheet1"),您可以將滑鼠懸停在該Worksheets部分上以查看表示 的部分.Sheets,但將滑鼠懸停在該部分上會Item顯示其中沒有專案的詳細資訊 - 它表示它回傳一個物件。
你知道它應該是什么,所以如果你有
Imports XL = Microsoft.Office.Interop.Excel
那么你可以做
osheet = DirectCast(owb.Worksheets("Sheet1"), XL.Worksheet)
并且型別都會解決。
uj5u.com熱心網友回復:
這就是關于 COM 物件的 VB 陳述句實際上所做的。
面向 Visual Basic 程式員的資訊
Visual Basic 提供對自動化的完全支持。下表列出了 Visual Basic 陳述句如何轉換為 OLE API。
Visual Basic 陳述句 OLE API
CreateObject (“ProgID”)CLSIDFromProgID CoCreateInstance QueryInterface to get IDispatch interface.
GetObject (“filename”, “ProgID”)CLSIDFromProgID CoCreateInstance QueryInterface for IPersistFile interface. Load on IPersistFile interface. QueryInterface to get IDispatch interface.
GetObject (“filename”)CreateBindCtx creates the bind context for the subsequent functions. MkParseDisplayName returns a moniker handle for BindMoniker. BindMoniker returns a pointer to the IDispatch interface. Release on moniker handle. Release on context.
GetObject (“ProgID”)CLSIDFromProgID GetActiveObject on class ID. QueryInterface to get IDispatch interface.
Dim x As New interfaceFind CLSID for interface. CoCreateInstance QueryInterface
一個標準的 COM VTable,前三個條目是 IUnknown
AddRef, Release (decreases the ref count), and QueryInterface to find what interfaces this object support.
接下來的四個條目是 IDispatch
GetIDsOfNames, Invoke , GetTypeInfoCount, GetTypeInfo.
之后的條目是您的方法和屬性,并且都是間接函式呼叫。
要獲取記憶體中的代碼,請使用 COM API 呼叫,例如CoCreateInstance
你需要決定是早系結還是晚系結。早期系結需要安裝程式,以便可以讀取其型別庫,以便將其型別編譯到程式中。后期系結不關心編譯時間。有一個對話Hello物件,你有沒有一個函式叫x。物件回復 是的,它是函式 7,請你做函式 7 物件。早期系結函式 7 是硬編碼的。您只能后期系結到通用物件。–
所以 COM 物件是 4 x 32 位的。一個是參考計數,一個是虛擬功能表(VTable)的地址,2個是未使用的。在呼叫函式 7 的早期系結中,編譯器執行 Address_Of_Vtable (4 x 7) (地址為 4 個位元組)。請參閱IDispatch。NB Microsoft.Office.Interop 在后期系結中根本不使用。–
只有泛型物件可以用于后期系結,不能用于早期系結。早期系結需要你告訴它具體的物件。你正在混合和匹配。編譯器很困惑,就像你一樣。–
Option Strict將隱式資料型別轉換限制為僅擴展轉換,不允許后期系結,并且不允許導致 Object 型別的隱式型別。learn.microsoft.com/en-us/dotnet/visual-basic/… –
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/520130.html
標籤:擅长VB.net办公自动化excel-自动化通信自动化
上一篇:WCFcustomUserNamePasswordValidatorType錯誤-無法加載檔案或程式集“CustomUserNameValidator”或其依賴項之一
下一篇:如何顯示具有相同ID的多行
