none
關於VB與VBA之間的問題 RRS feed

  • 問題

  •  

    之前 璉璉 前輩有提到,在非 VBA 環境下不要用到 Select / Selection / ActiveXXXX,請問是關係到需要VB引用的問題嗎?

    那麼用巨集錄製下來的部份,在VB中不去使用VBA的東西,是不是需要經驗來改寫呢?還是有可以對照的表格呢?

    例如上次的例子:

    Code Snippet

    Application.Cells.Select()                      '選擇全部儲存格
    Application.Selection.ClearContents()    '刪除全部選擇

    改寫成

    Dim xlApp As Object = CreateObject("Excel.Application")

    ...

    xlApp.Cells.ClearContents()

     

     

    2008年3月6日 下午 08:24

解答

  • 使用 CreateObject 叫作延後連結(Late Bind),加入參考叫做提前連結 (early bind) 。

    在微軟官方文件所稱,提前連結效能較延後連結高 1000 倍。

    但提前連結有鎖版本的問題,延後連結則無。

     

    所以本來就有兩種方法。

     

    你後面寫的也不對,是透過 COM 與 Office 溝通,所以在 VBNET 下呼叫 COM 仍然是使用 VBNET 語法,但要注意的是 COM 型別為 Variant 的多變型態,.Net 則使用新的資料型態,在部分無法自動轉換的時候,必須使用強型別轉換函數轉換,例如 CDate / CBool /... 等。

    2008年3月8日 上午 02:30
    版主

所有回覆

  • 看不懂這句。

    Code Snippet

    請問是關係到需要VB引用的問題嗎

     

     

    從通論來解釋:

    VBA 在運行時,必在某個物件內,所以繼承了這個物件的所有命名環境,例如 Application.StatusBar 可以直接用 StatusBar ,但是在其他狀況下則無。此外程式可能在多重狀況下執行,使用非絕對的物件,可能會產生意料之外的後果。

     

    例如:

    假設兩個含有巨集的 Excel 同時運行,若兩個 Excel 巨集均使用 Select 時,最後一個呼叫 Select 的物件將被選擇,則先前的呼叫到的 Select 所對應的 Selection 就會變成後面呼叫 Select 的這個物件,所以就變成根本是不同的 workbook ,同理,ActiveSheet 也是如此。因此實際上並非僅有在非 VBA 環境,而是正式的程式碼撰寫慣例要避免這樣的情形。

     

    而在外部用編譯器就有更多的不可預期因素,就最好用正確的物件結構來對應。

     

    至於對照的表格要看該物件的結構圖,以 Cells 來說,Application.Cells 等同於 ActiveCells ,若是 ActiveWorkBook 切換到其它的工作簿時,Applicaiton.Cells 就會對應到其他工作簿,所以是不穩定的程式碼。

    Application.Workbook.Sheet.Cells 才是正確的物件結構,所以在運用上要以此為架構來設計:

    Code Snippet

    Set xlBook = xlApp.Workbooks.Open(strFile)

    Set xlSheet = xlBook.Sheets("Sheet1")

    xlSheet.Cells.ClearContents()

     

     

    這樣才會形成穩定的程式碼,當然也可以直接用物件全路徑:

    Code Snippet

    xlApp.WorkBooks(filename).Sheets(sheetname).Cells.ClearContents()

     

     

    這個基本觀念實際上並沒有說 VBA 就可以不管,只是為了方便起見,才會說在 VBA 以外的環境都不要用,硬要套在 VBA 以外的環境還是可以用 xlApp.Selection ,但是這是個不穩定的程式碼,比如說你不小心開了兩個執行檔來跑,就可能會出問題。

    2008年3月7日 上午 02:51
    版主
  • 感謝前輩對另外一個問題的解答

    不好意思,其中一個問題沒有描述清楚,「請問是關係到需要VB引用的問題嗎」,當初會想問這句話的想法是:

    我不確定在使用select等vba的東西時,是不是需要加入參考。所以會有個想法,若以CreatObject來建立Excel.Application這個物件,是不是在使用select等語法的時候就不用再加入參考Microsoft.Office.Tools.Excel???

    未加入參考

    Dim myApp as Object

    ...
    myApp = CreateObject("Excel.Application") 
    myApp.Cells.Select()                  
    myApp.Selection.ClearContents() 


    需加入參考
    Microsoft.Office.Tools.Excel

    Dim myapp As New Application
    ...
    myApp.Cells.Select()                  
    myApp.Selection.ClearContents() 

    還有另外一個問題,就是vb需要透過vba與office作溝通,來達到
    Automation,但是vba似乎偏向於vb6版本的使用,在vb2005之後的版本中,若同樣要與office作溝通,來達到Automation,是否仍需使用vba??亦或是有別的方法呢??


     

             


    2008年3月7日 下午 06:54
  • 使用 CreateObject 叫作延後連結(Late Bind),加入參考叫做提前連結 (early bind) 。

    在微軟官方文件所稱,提前連結效能較延後連結高 1000 倍。

    但提前連結有鎖版本的問題,延後連結則無。

     

    所以本來就有兩種方法。

     

    你後面寫的也不對,是透過 COM 與 Office 溝通,所以在 VBNET 下呼叫 COM 仍然是使用 VBNET 語法,但要注意的是 COM 型別為 Variant 的多變型態,.Net 則使用新的資料型態,在部分無法自動轉換的時候,必須使用強型別轉換函數轉換,例如 CDate / CBool /... 等。

    2008年3月8日 上午 02:30
    版主
  • HI,

     

    Dim myApp as Object

     

    這種寫法在VB程式叫做Late Binding, 可以不需要加入參考.

     

    Dim myapp As New Application

    這種寫法在VB程式叫做Early Binding, 其執行效能較佳, 程式執行出錯機會較低, 但是需要參考Microsoft.Office.Tools.Excel

     

    VB2005要和Office溝通, 可以透過Visual Studio Tools for Office技術來做, 是一種VBA的替代方案, 請參考:

     

    http://msdn2.microsoft.com/en-us/office/aa905543.aspx

     

    tihs

    2008年3月8日 上午 02:33
  •  

    感謝兩位前輩的指導
    2008年3月9日 上午 02:22