EXCEL VBA從頭來過-基本語法(中篇)

張凱喬
7 min readDec 20, 2017

這一篇
原本要一次講變數與控制邏輯
但是後來發現變數滿雜、滿多需要補充
只好從上下兩篇變成上中下三篇了

有變數跟控制邏輯
就可以寫變數讀EXCEL內容
利用控制邏輯作判斷、執行迴圈等
可以做的事情就會變很多

(一)、變數

變數種類有:
Integer 整數
Long 長整數
Single 浮點數
Double 浮點數(雙精度)
String 字串
Boolean 布林值(True & False)
Date 日期

其他比較複雜的還有 Variant 數值 與 Object 物件 等等

Integer整數的範圍是-32,768~32,767
Long長整數的範圍是-2147483648~2147483647
(Long是二十億,還不夠就用Variant)

宣告的方式是「Dim 變數 As 類型」

'a1是一個整數
Dim a1 as Integer
a1=100
'b1是一個字串
Dim b1 as string
b1="blabla"

而Variant可以是數字、字串、日期等等
意思是代表所有的數字與文字
而且可以容納的數字也很大,比Long還大
缺點就是沒有限制記憶體大小,跑起來可能比較慢
宣告Variant的方式就是不用宣告 XD
以下示範三種方法

'這樣宣告一個Variant變數a,且a的值是100 (意思是可以不用打宣告)
a= 100
'這樣也是宣告一個Variant變數b
Dim b
'這樣也是宣告一個Variant變數c
Dim c as Variant

雖然Variant很方便,一般來說是建議少用
因為有點難控制,你也不知道你有沒有把整數存成浮點數

補充如何一次宣告多個變數

'其實就只是共用一個Dim,後面還是要重打
Dim a As integer, b As integer
'如果像下面這樣打,c變數就會變成Variant
Dim c, d As integer

Object是一個奇妙的東西
與其說是物件,倒不如說是參照

然而Obeject還有分很多種形式

'直接訂a1是一個物件(通用物件的概念)
'所以a1可以是工作表、活頁簿或欄位區域
Dim a1 as Obeject
a1 =Workbooks(1)
a1 =Range("A1,B2")
'也可以使用固定物件型態,也就是直接定義
'定義b1是一個工作表
b1 =Workbooks(1)
'定義c1是一個欄位區域
c1 =Range("A1,B2")

定義完之後
他是甚麼物件 就可以執行該物件的功能
譬如

'定義一個Range,再給予值
Dim d1 as Range
d1 = Range("A1,B2")
d1.value=100
'此時A1~B2四格的值都會變100

(二)、陣列

大家對陣列這個詞應該不陌生
但每個程式語言對陣列概念的解讀不太一樣

在VBA中陣列可以設定下界(起始點)與上界(結束點)
此外,陣列的起始點可以是負數、也可以不填

'建立一個i(5)到i(10)共六格的整數陣列
Dim i(5 to 10) As Integer
'建立一個從m(-2)到i(2)共五格的整數陣列
Dim m(-2 to 10) As Integer
'建立一個從n(0)到n(3)共四格的整數陣列(不給下界就是從0開始的意思)
Dim n(3) As Integer
'建立一個沒有限制大小的p整數陣列
Dim p() As Integer
'建立一個沒有限制大小、沒有限制內容物(使用Variant)的陣列
Dim r()

如果沒有限制陣列大小,我們又稱作動態陣列
則使用時需要多加留意
舉例而言 你需要給值,陣列元素才會出現,否則會錯誤
下面的例子會舉出動態陣列與靜態陣列的差異

'建立一個a()動態整數陣列
Dim a() as integer
'建立一個b(0)~b(5)靜態整數陣列
Dim b(5) as integer
'在陣列都還沒有給值之前,利用Msgbox讀出a(1)與b(1)
'先做a(1),會出現錯誤(因為沒有給值,該陣列元素不存在)
Msgbox(a(1))
'b(1)則會正常顯示一個空白(雖然沒有給值,但定義陣列時已經有做出元素了)
Msgbox(b(1))

再來介紹幾個常用方法
刪除及讀取陣列長度

'建一個i(3)~i(6)共四個元素的整數陣列
Dim i(3 to 6) As Integer
'清除內容
Erase i
'使a等於i陣列的上界 => a=6
a=Ubound(i)
'使b等於i陣列的下界 => b=3
b=Lbound(i)
'使c等於i陣列的長度 => c=4
c=Ubound(i)-Lbound(i)+1

當然 陣列可以是多維的
譬如 Dim m(2,2)之類的

最後 可能大家寫陣列常會碰到的問題
就是究竟可不可以用變數定義陣列長度
譬如我想要 a=10 然後 Dim i(a)
在VBA是不行直接這樣宣告的

要換一個方法 先Dim一個空陣列,再ReDim塞入變數
這個比較進階,參考官方文件

(三)、運算子

運算子算是比較簡單的東西
通常都是先記錄起來,打錯時可以查

算術運算:
^ 次方
* 乘法
/ 除法
\ 整數除法
Mod 餘數
+ 加法
- 減法

比較運算:
= 等於
<> 不等於
< 小於
> 大於
<= 小於或等於
>= 大於或等於

邏輯運算:
And
Or
Not
Xor

最後還有一個字串運算&
簡單來說就是合併字串時使用

(四)、補充:變數使用區域/保存期限

你如果在模組層宣告一個變數
則在這個模組裡,都能使用
且直到活頁簿關閉 才會重設

在程式層宣告變數
則只有在該程式(sub)裡才能使用
且程式結束之後,變數不會儲存

以上圖為例

由於在test()裡重新宣告一次num
所以這個num會讀取這個sub裡的num
而不會讀取到模組層的

再來,由於每執行結束,程式層變數都會重設
所以不管你執行幾次test(),答案永遠是100
(因為每次都是做0+100)

但test1()沒有重新宣告,會讀取到模組層的num
如上述所說,模組層的變數只有活頁簿結束才會重設
所以你每執行一次test1(),模組層的num就會加1000

你可以試著每執行一次test1()之後便執行一次test2()
你會發現顯示數字會從1000變2000、3000以此類推

阿除了模組層、程式層
還有一個工程級,就是用Public宣告
這樣就可以跨模組使用
有興趣可以看看

這篇先這樣
下一篇講控制邏輯

--

--