tft每日頭條

 > 圖文

 > vba set函數的使用方法

vba set函數的使用方法

圖文 更新时间:2024-08-06 15:09:13

vba set函數的使用方法(VBVBA内置函數之LenLenB函數)1

在這個紅框中,題目中的這兩函數值得一看

前言

正如《VB/VBA字符串》中所說,字符串在人機交互中,舉足輕重,是站人這一邊的,其作用甚至比變量和函數更突出。要想将VB中的字符串搞清楚,本身就涉及到變量、指針,指針的指針、數組等内容。所以要想提高字符串的處理效率,得有一個抽絲剝繭的過程,不是三言兩語就能交代清楚的。

在探索VB/VBA字符串效率的過程中,除了在前文《VB/VBA/VB中哪些字符串函數 $能提高性能?》介紹的$修飾符外,還有兩個大家司空見慣的函數值得一說,這便是Len和LenB函數。

vba set函數的使用方法(VBVBA内置函數之LenLenB函數)2

字符串,至少有這麼些個内容

一、判斷字符串的長度

判斷字符串長度,這可能是這兩哥們最常去的地方。當然,字符串長度,因為編碼的問題(這個有點重,後面再講),出現了字符長度和字節長度。那Len就是獲取字符串的字符長度LenB就是獲取字節長度

1、LenB與Len之間關系

很多人覺得是這樣的:2*Len=LenB。沒錯,在這兩個函數的實現上,的确也是這麼個關系。但是,直接将其視為不變的邏輯,進行套用,就會掉坑裡。這就像Str="",并非判斷字符串為空的最佳方式一樣(詳見《VB/VBA判斷字符串為空,這樣更高效!》),如果不了解背後的邏輯,就很難理解。

默認情況下,也就是在VB/VBA的IDE中,隻能直接輸入Unicode的字符串(一個字符占2字節),所以前述關系是正确的。但,這不代表着,任何時候都正确。如果轉換了編碼,如将Unicode轉換為ANSI,則Len函數返回的結果就是錯誤的(如下所示)。

如何理解更合适呢?Len函數對于字符串而言,獲取Unicode編碼的字符串字符大小,或許更為妥當。

2、Len和LenB的性能

控制和處理字符串的過程中,大小總是關鍵,畢竟絕大部分人處理字符串的過程中,都有根據大小進行遍曆的經曆。比如,數下一串英文中有多少個大寫字符,估計除了Mid函數逐字符遍曆,或賦值給字節數組後再逐元素遍曆外,能用其他方法的人就很少了(有懂的,在BtOfficer看來,可能達到了VB/VBA應用的中級水平)。

這兩函數,雖然極少會被高頻調用,但探究其實現過程,了解下VB/VBA的編譯/解釋器的優化,總歸還是有用的,哪怕看個放心呢。正好,BtOfficer在擴展VB/VBA的運行時(歡迎關注),可以将這兩函數底層的東西,簡單地說一說。

這兩函數都經過了4層封裝,才達到真正的實現代碼。最核心的代碼是什麼呢?就兩句:

1、『mov eax, dword ptr [eax-4]』,這句兩個都有,就是從BSTR結構中取出第1個成員的值,這個在前面的鍊接《VB/VBA的字符串》中,有詳細介紹,可前去查看。

2、『shr eax, 1』,這句隻有Len有,就是将BSTR的大小,右移1位,相當于除2。所以Len=Lenb/2,就是這麼來的。

BtOfficer舍棄了這兩函數4層封裝中的其他代碼,就留了上面的核心代碼,構建了StrSize函數(與LenB對應),來看下測試效果:

從測試過程可以看出,盡管Lenb函數有4層調用,但在解釋器(測試是在IDE環境)的優化下,仍然比指令更少(3條指令,與Lenb的核心指令一樣)的StrSize函數表現的更好。這是為什麼呢?因為,此處的擴展函數StrSize的指令數,僅是函數内的指令,而沒有考慮參數傳遞過程中的指令。如此一來,反而是優化後的Lenb代碼量更少,因而更快。

因為編譯器和解釋器,均有相應的版權,進行修改擴展,沒有合法性。所以,BtOfficer在擴展時不能使用全局優化上的便利,僅能在擴展部分進行局部優化。因此通過第三方合法擴展,要想超越Delphi,估計還是很難,頂多八八九九吧。不過從中也可以看出,VB/VBA編譯器和解釋器的優化性能,還是值得信耐的,隻要使用得當,VB/VBA的代碼性能不會差到哪兒去。

這裡呢,Len/Lenb的性能是沒什麼問題的,哪怕是高頻調用,大家也盡可放心使用。

二、判斷結構體大小

在VB/VBA的通常應用中,結構體是比較少用的概念,但在複雜的API或高級應用中,結構體總是如影随形。獲取結構體的尺寸,便是使用結構體的基礎操作。Len和LenB函數,除了在字符串的一畝三分地裡是常客,在其他方面也是不可或缺的重量級函數。

對于結構體(也即自定義類型),Len函數獲得各成員的尺寸之和,而Lenb獲得其占用内存大小。來看個示例:

從示例可以看出,結構體個成員大小之和與其占用内存并不一緻,因為這裡面涉及到對齊問題。正如《VB中Byte、Bool和Int與Lng的開銷及性能相同嗎?》所說,計算機裡隻有整齊才會更快,所以對齊的要求處處都有,VB/VBA要想提高性能,也得遵守這樣的規律。

結構體涉及到的東西也比較多,後續會專題講解,歡迎繼續關注。

三、判斷變量尺寸

什麼是變量尺寸呢?比如Byte類型占用1字節,Boolean和Integer占用2字節,Long占用4字節等,這就是變量尺寸。如果不使用指針,那麼考慮變量尺寸的場景就會很少。

當Len/Lenb的參數不是字符串常量或變量,而是其他變量名時,這兩函數就可以丈量指定變量占用的内存大小,此時二者是相同的。特别指出的是,變量指向Null時,返回值也是NULL.

vba set函數的使用方法(VBVBA内置函數之LenLenB函數)3

還可以丈量變量尺寸,有點意思

但正如《VB的任性,從Variant開始》所說,VB/VBA要考慮計算機專業素質較差的文科背景人士使用,因此不得不提供高容錯特性,并盡可能隐藏專業特性。這其中,Variant功不可沒。無論是VB/VBA自身内置函數的參數、返回值,還是很多系統級API,都在廣泛使用這一類型。

正是這一類型在VB/VBA中的廣泛使用,造就了VB/VBA的低門檻(工具意義上的靈活性,而非編程控制上的靈活性),同時也導緻了讓人诟病的低效性(Delphi當年緊抓不放的把柄)。所以,VB/VBA要想提高性能,更高效處理Variant才是出路(棄而不用并不經濟,這與通常建議避免使用Variant,可是大相徑庭的哦)。

Variant的後續内容,會逐步結合指針(注意,VB/VBA的指針,并不是調用CopyMemory函數)進行介紹,歡迎繼續關注。這裡結合本篇主題,講下Len/Lenb的作用。我們知道,Variant是個容器,可以帶來靈活性,但除了知道其包含的具體類型,還得知道這些類型數據的尺寸。這幾乎是VB/VBA高階應用中,最為基礎的操作。

從該例可以看出,對于Variant,似乎和前面的說法不同。的确如此,當變量類型為Variant類型時,Len/Lenb會将其轉換為String類型,視為String類型的值,加以判斷。此時,和字符串參數是一樣的。這樣的特性,在VB/VBA中還有大量存在。

歡迎關注BtOfficer(收藏、點贊、關注 轉發),更多精彩仍在繼續哦(專欄文章将更系統,更全面),有嚴肅而枯燥的技術,也有輕松的唠嗑,更有現成工具等你來拿,期待你的加入!

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关圖文资讯推荐

热门圖文资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved