第一章 VBA語言基礎
第一節 標識符
一.定義
標識符是一種標識變量、常量、過程、函數、類等語言構成單位的符號,利用它可以完成對變量、常
量、過程、函數、類等的引用。 二.命名規則
1) 字母打頭,由字母、數字和下劃線組成,如 A987b_23Abc
2) 字符長度小於 40,(Excel2002以上中文版等,可以用漢字且長度可達 254個字符)
3) 不能與 VB保留關鍵字重名,如 public, private, dim, goto, next, with, integer, single等
第二節 運算符
定義:運算符是代表 VB某種運算功能的符號。 1)賦值運算符 =
2)數學運算符 &、 + (字符連接符 )、 +(加)、-(減)、 Mod(取餘)、 /(整除)、*(乘)、/(除)、-(負號)、^(指數)
3)邏輯運算符 Not(非)、 And(與)、 Or(或)、 Xor(異或)、 Eqv(相等)、 Imp(隱含)
4)關係運算符 = (相同)、 <>(不等)、>(大於)、<(小於)、 >=(不小於)、 <=(不大於)、 Like、 Is
5)位運算符 Not(邏輯非)、 And(邏輯與)、 Or(邏輯或)、 Xor(邏輯異或)、 Eqv(邏輯等)、 Imp(隱含)
第三節 數據類型
VBA共有12種數據類型,具體見下表,此外用戶還可以根據以下類型用 Type自定義數據類型。
數據類型 類型標識符 字節
字符串型 String $ 字符長度 (0-65400)
字節型 Byte 無 1
布爾型 Boolean 無 2
整數型 Integer % 2
長整數型 Long & 4
單精度型 Single ! 4
雙精度型 Double # 8
日期型 Date 無 8 公元 100/1/1-9999/12/31
貨幣型 Currency @ 8
小數點型 Decimal 無 14
變體型 Variant 無 以上任意類型,可變
對象型 Object 無 4
第四節 變量與常量
1) VBA允許使用未定義的變量,默認是變體變量。
2)在模塊通用說明部份,加入 Option Explicit 語句可以強迫用戶進行變量定義。
3)變量定義語句及變量作用域 Dim 變量 as 類型 '定義爲局部變量,如 Dim xyz as integer
Private 變量 as 類型 '定義爲私有變量,如 Private xyz as byte
Public 變量 as 類型 '定義爲公有變量,如 Public xyz as single
Global 變量 as 類型 '定義爲全局變量,如 Globlal xyz as date
Static變量 as 類型 '定義爲靜態變量,如 Static xyz as double 一般變量作用域的原則是,那部份定義就在那部份起作用,模塊中定義則在該模塊那作用。 4)常量爲變量的一種特例,用 Const定義,且定義時賦值,程序中不能改變值,作用域也如同變量作用域。 如下定義: Const Pi=3.1415926 as single
第五節 數組
數組是包含相同數據類型的一組變量的集合,對數組中的單個變量引用通過數組索引下標進行。在內 存中表現爲一個連續的內存塊,必須用Global或Dim語句來定義。定義規則如下: Dim 數組名 ([lower to ]upper [, [lower to ]upper, ….]) as type ;Lower缺省值爲0。二維數組是按行列排列,如 XYZ(行,列)。
除了以上固定數組外, VBA還有一種功能強大的動態數組,定義時無大小維數堀明;在程序中再利用
Redim語句來重新改變數組大小,原來數組內容可以通過加 preserve關鍵字來保留。如下例:
Dim array1() as double : Redim array1(5) : array1(3)=250 : Redim preserve array1(5,10)
第六節 註釋和賦值語句
1)註釋語句是用來說明程序中某些語句的功能和作用; VBA中有兩種方法標識爲註釋語句。 9 單引號 ’ ;如:’定義全局變量;可以位於別的語句之尾,也可單獨一行
9 Rem ;如: Rem定義全局變量;只能單獨一行 2)賦值語句是進行對變量或對象屬性賦值的語句,採用賦值號 =,如X=123:Form1.caption=”我的窗口 ” 對對象的賦值採用: set myobject=object 或 myobject:=object
第七節 書寫規範
1) VBA不區分標識符的字母大小寫,一律認爲是小寫字母;
2)一行可以書寫多條語句,各語句之間以冒號 : 分開;
3)一條語句可以多行書寫,以空格加下劃線 _ 來標識下行爲續行;
4)標識符最好能簡潔明瞭,不造成歧義。
第八節 條件語句
1) If…Then…Else語句
If condition Then [statements][Else elsestatements] 如1:If A>B And C<D Then A=B+2 Else A=C+2
如2:If x>250 Then x=x-100 或者,可以使用塊形式的語法: If condition Then [statements] [ElseIf condition-n Then [elseifstatements] ... [Else [elsestatements]] End If
如 1:
If Number < 10 Then Digits = 1 ElseIf Number < 100 Then Digits = 2 Else Digits = 3 End If
2) Select Case…Case…End Case語句 如1: Select Case Pid
Case “A101”
Price=200
Case “A102”
Price=300 …… Case Else
Price=900
End Case
3)Choose 函數
choose(index, choce-1,choice-2,…,choice-n),可以用來選擇自變量串列中的一個值,並將其返回, index
必要參數,數值表達式或字段,它的運算結果是一個數值,且界於 1 和可選擇的項目數之間。choice 必 要參數, Variant表達式,包含可選擇項目的其中之一。如:
GetChoice = Choose(Ind, "Speedy", "United", "Federal")
4) Switch函數
Switch(expr-1, value-1[, expr-2, value-2 _ [, expr-n,value-n]])
switch函數和 Choose函數類似,但它是以兩個一組的方式返回所要的值,在串列中,最先爲 TRUE的值 會被返回。 expr 必要參數,要加以計算的 Variant 表達式。value 必要參數。如果相關的表達式爲 True, 則返回此部分的數值或表達式,沒有一個表達式爲 True, Switch 會返回一個 Null值。
第九節 循環語句
1) For Next語句 以指定次數來重複執行一組語句 For counter = start To end [Step step] ' step 缺省值爲 1 [statements] [Exit For] [statements] Next [counter] 如1: For Words = 10 To 1 Step -1 ' 建立 10 次循環 For Chars = 0 To 9 ' 建立 10 次循環
MyString = MyString & Chars ' 將數字添加到字符串中 Next Chars ' Increment counter
MyString = MyString & " " ' 添加一個空格 Next Words
2) For Each…Next語句 主要功能是對一個數組或集合對象進行,讓所有元素重複執行一次語句 For Each element In group
Statements [Exit for] Statements
Next [element] 如1: For Each rang2 In range1
With range2.interior
.colorindex=6 .pattern=xlSolid
End with
Next
這上面一例中用到了 With…End With 語句,目的是省去對象多次調用,加快速度;語法爲:
With object [statements] End With
3)Do…loop語句 在條件爲 true時,重複執行區塊命令
Do {while |until} condition ' while 爲當型循環, until爲直到型循環,顧名思義,不多說啦
Statements
Exit do
Statements
Loop 或者使用下面語法 Do ' 先 do 再判斷,即不論如何先幹一次再說
Statements
Exit do
Statements
Loop {while |until} condition
第十節 其他類語句和錯誤語句處理
一.其他循環語句
結構化程序使用以上判斷和循環語句已經足夠,建議不要輕易使用下面的語句,雖然 VBA還支持。 1) Goto line 該語句爲跳轉到line語句行
2) On expression gosub destinatioinlist 或者 on expression goto destinationlist 語句爲根據 exprssion表達式
值來跳轉到所要的行號或行標記
3) Gosub line…line…Return語句, Return 返回到 Gosub line行,如下例: Sub gosubtry()
Dim num
Num=inputbox(“輸入一個數字,此值將會被判斷循環 ”)
If num>0 then Gosub Routine1 :Debug.print num:Exit sub
Routine1:
Num=num/5
Return
End sub 4) while…wend語句,只要條件爲TRUE,循環就執行,這是以前 VB老語法保留下來的,如下例: while condition ‘while I<50 [statements] ‘I=I+1 wend ‘Wend
二.錯誤語句處理
執行階段有時會有錯誤的情況發生,利用On Error語句來處理錯誤,啓動一個錯誤的處理程序。語法如下: On Error Goto Line ‘當錯誤發生時,會立刻轉移到line行去
On Error Resume Next ‘當錯誤發生時,會立刻轉移到發生錯誤的下一行去
On Erro Goto 0 ‘當錯誤發生時,會立刻停止過程中任何錯誤處理過程
第十一節 過程和函數
過程是構成程序的一個模塊,往往用來完成一個相對獨立的功能。過程可以使程序更清晰、更具結構
性。VBA具有四種過程:Sub 過程、 Function函數、 Property屬性過程和 Event事件過程。
一.Sub過程
Sub 過程的參數有兩種傳遞方式:按值傳遞(ByVal)和按地址傳遞 (ByRef)。如下例:
Sub password (ByVal x as integer, ByRef y as integer)
If y=100 then y=x+y else y=x-y x=x+100
End sub
Sub call_password ()
Dim x1 as integer
Dim y1 as integer x1=12 y1=100 Call password (x1,y1) ‘調用過程方式:1. Call 過程名 (參數 1, 參數 2…) ; 2. 過程名 參數 1, 參數 2… debug.print x1,y1 ‘結果是12、 112, y1按地址傳遞改變了值,而 x1按值傳遞,未改變原值
End sub
二. Function函數
函數實際是實現一種映射,它通過一定的映射規則,完成運算並返回結果。參數傳遞也兩種:按值傳
遞(ByVal)和按地址傳遞 (ByRef)。如下例:
Function password(ByVal x as integer, byref y as integer) as boolean
If y=100 then y=x+y else y=x-y x=x+100 if y=150 then password=true else password=false
End Function
Sub call_password ()
Dim x1 as integer
Dim y1 as integer x1=12 y1=100 if password then ‘調用函數: 1. 作爲一個表達式放在=右端 ; 2. 作爲參數使用 debug.print x1
end if End sub
三. Property屬性過程和 Event事件過程
這是 VB在對象功能上添加的兩個過程,與對象特徵密切相關,也是 VBA比較重要組成,技術比較
複雜,可以參考相關書籍。
第十二節內部函數
在 VBA程序語言中有許多內置函數,可以幫助程序代碼設計和減少代碼的編寫工作。
一.測試函數
IsNumeric(x) ‘是否爲數字 , 返回 Boolean結果,True or False
IsDate(x) ‘ 是否是日期 , 返回 Boolean結果,True or False
IsEmpty(x) ‘是否爲 Empty, 返回 Boolean結果,True or False
IsArray(x) ‘指出變量是否爲一個數組。
IsError(expression) ‘指出表達式是否爲一個錯誤值 IsNu ll(expression) ‘指出表達式是否不包含任何有效數據 (Null)。
IsObject(identifier) ‘指出標識符是否表示對象變量
二.數學函數
Sin(X)、 Cos(X)、 Tan(X)、 Atan(x) 三角函數,單位爲弧度
Log(x) 返回x的自然對數
Exp(x)返回 ex
Abs(x) 返回絕對值
Int(number)、Fix(number) 都返回參數的整數部分,區別: Int 將 -8.4 轉換成 -9,而 Fix 將-8.4 轉換成 -8
Sgn(number) 返回一個 Variant (Integer),指出參數的正負號
Sqr(number) 返回一個 Double,指定參數的平方根
VarType(varname) 返回一個 Integer,指出變量的子類型
Rnd(x)返回 0-1之間的單精度數據,x爲隨機種子
三.字符串函數
Trim (string) 去掉 string左右兩端空白
Ltrim( string) 去掉 string左端空白
Rtrim( string) 去掉 string右端空白
Len(string) 計算 string長度 Left(string, x) 取 string左段x個字符組成的字符串
Right(string, x) 取 string右段x個字符組成的字符串
Mid(string, start,x) 取 string從 start位開始的x個字符組成的字符串
Ucase(string) 轉換爲大寫
Lcase(string) 轉換爲小寫
Space(x) 返回x個空白的字符串 As c(string) 返回一個 integer,代表字符串中首字母的字符代碼
Chr(charcode) 返回 string,其中包含有與指定的字符代碼相關的字符
四.轉換函數
CBool(expression) 轉換爲 Boolean型 CByte(expression) 轉換爲 Byte型 CCur(expression) 轉換爲 Currency型 CDate(expression) 轉換爲 Date型 CDbl(expression) 轉換爲Double型 CDec(expression) 轉換爲 Decemal型 CInt(expression) 轉換爲 Integer型 CLng(expression)
轉換爲 Long型 CSng(expression) 轉換爲 Single型 CStr(expression) 轉換爲 String型 CVar(expression) 轉換爲 Variant型
Va l(string) 轉換爲數據型
Str(num ber) 轉換爲String
五.時間函數
Now 返回一個 Variant (Date),根據計算機系統設置的日期和時間來指定日期和時間。
Date 返回包含系統日期的 Variant (Date)。
Time 返回一個指明當前系統時間的 Variant (Date)。
Timer 返回一個 Single,代表從午夜開始到現在經過的秒數。
TimeSerial(hour, minute, second) 返回一個 Variant (Date),包含具有具體時、分、秒的時間。
DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]]) 返回 Variant (Long) 的值,表示兩個指定 日期間的時間間隔數目 Second(time) 返回一個 Variant (Integer),其值爲 0 到 59 之間的整數,表示一分鐘之中的某個秒
Minute(time) 返回一個 Variant (Integer),其值爲 0 到 59 之間的整數,表示一小時中的某分鐘
Hour(time) 返回一個 Variant (Integer),其值爲 0 到 23 之間的整數,表示一天之中的某一鐘點
Day(date) 返回一個 Variant (Integer),其值爲 1 到 31 之間的整數,表示一個月中的某一日
Month(date) 返回一個 Variant (Integer),其值爲 1 到 12 之間的整數,表示一年中的某月
Year(date) 返回 Variant (Integer),包含表示年份的整數。
Weekday(date, [firstdayofweek]) 返回一個 Variant (Integer),包含一個整數,代表某個日期是星期幾
第二章 Excel VBA常用對象之使用
第一節 文件的操作
1) Excel文件
1.1 新建與打開 一.新建 Workbooks.Add
二.打開
Workbooks.Open "路徑 /" & "文件名 .xls"
三.文件打開對話框的使用
Application.GetOpenFilename(fileFilter:="Excel files(*.xls),*.xls,All files (*.*),*.*")
示例 :
flag = False Do While Not flag ' 對話框打開已有 Excel文件 fm = Application.GetOpenFilename(fileFilter:=" Excel files(*.xls),*.xls, All files (*.*),*.*")
If fm <> False Then Workbooks.Open fm Set bb = ActiveWorkbook '把 bb變量設爲當前活動工作簿對象,打開一工作簿時,該工作簿自動爲當前活動工作簿 flag = True End If Loop
1.2 保存與關閉 一.保存 Workbooks("文件.xls").Save
二.另存對話框的使用
Application.GetSaveAsFilename(fileFilter:="Excel files (*.xls),*.xls,All files (*.*),*.*")
示例 :
flag = False Do While Not flag ' 循環要求必須輸入文件名或選擇文件名 fm = Application.GetSaveAsFilename(fileFilter:=" Excel files (*.xls),*.xls,All files (*.*),*.*")
If fm <> False Then activeworkbook.SaveAs fm ' 當前活動工作簿另存 flag = True End If Loop
三.關閉
1.單個文件關閉 Workbooks("filename.xls").Close 2.所有該 Excel程序打開的文件都關閉 Workbooks.Close
如果文件使用中改動過內容 , 那麼該命令使用時會彈出提示對話框 , 詢問是否保存 .
如果要想不彈出提示對話框,可以使用第三或第四種文件關閉方法 , 或者如下示例 .
示例 :
關閉工作簿“ Book1.xls”,但不提示用戶保存所作修訂。“ Book1.xls”中的所有修訂都不 會保存。 Application.DisplayAlerts = False '信息警告關閉
Workbooks("BOOK1.XLS").Close
Application.DisplayAlerts = True '信息警告開啓
四.關閉同時保存
Workbooks("filename.xls").Close savechanges:=True
五.關閉同時不保存
Workbooks("filename.xls").Close savechanges:=False
六 .Excel程序的關閉 Application.Quit
說明 :
使用本方法時,如果有未保存的工作簿處於打開狀態,則 Microsoft Excel 將彈出一個對話 框,詢問是否要保存所作修改。
爲防止這一情況出現,可在使用 Quit 方法前保存所有的工作簿或將 DisplayAlerts 屬性設 置爲 False。如果該屬性爲 False,則 Microsoft Excel 退出時,即使存在未保存的工作簿 退出,也不會顯示對話框,而且不保存就退出。如果將一個工作簿的 Saved 屬性設置爲 Tr ue,但是並沒有將其保存到磁盤上,則 Microsoft Excel 在退出時不會提示保存該工作簿。
七.工作簿的密碼保護與撤銷 保護工作簿使其不至被修改。 Workbooks(“工作簿名 ”).Protect (Password, Structure, Windows)
Password Variant 類型,可選。爲一個字符串,該字符串爲工作表或工作簿指定區分大小寫的密碼。如 果省略本參數,不用密碼就可以取消對該工作表或工作簿的保護。否則,必須指定密碼,通過密碼來取消 對該工作表或工作簿的保護。如果忘記了密碼,就無法取消對該工作表或工作簿的保護。最好在安全的地 方保存一份密碼及其對應文檔名的列表。 Structure Variant 類型,可選。如果爲 True,則保護工作簿結構(工作表的相對位置)。默認值爲 False。
Windows Variant 類型,可選。如果爲 True,則保護工作簿窗口。如果省略本參數,則窗口不受保護 如:Workbooks(“學生檔案”).protect ”1234”
Workbooks(“學生檔案”).Unprotect (Password)
Password Variant 類型,可選。指定用於解除工作表或工作簿的保護的密碼,此密碼是區分大小寫的。 如果工作表或工作簿不設密碼保護則忽略本參數。如果對工作表省略此參數,而該工作表又設有密碼保護, Microsoft Excel 將提示您要輸入密碼。如果對工作簿省略此參數,而該工作簿又設有密碼保護,本方法將 失敗。
1.3 示例
示例 :(使用了4個文件,宏程序文件操作了另外三個文件,還涉及到文件打開另存對話框)
一. 在 test.xls文件中編寫一個宏程序test,完成以下內容.打開當前目錄下 test1.xls 文件,計算 sheet1工作表上單元格 a1到a10的數據剩上 (0-1)的隨機數,計算結果保存在一個新
建工作簿的 sheet1的 a1到a10上,且結果還要保存在一個任意打開的 Excel文件下,示例中打開 test2.xls文件, 完成後關閉Excel程序.
test.xls 模塊中 Sub test()
Dim i As Integer, flag As Boolean, fm
Dim aa, bb, cc, temp
Application.ScreenUpdating = False '屏幕刷新關閉
Application.DisplayAlerts = False '信息警告關閉
Workbooks.Open ThisWorkbook.Path & "/test1.xls" '打開文件 test1.xls
Set aa = ActiveWorkbook.Sheets("Sheet1")
flag = False
Do While Not flag ' 對話框打開已有 Excel文件
fm = Application.GetOpenFilename(fileFilter:="Excel files (*.xls),*.xls, _ All files (*.*),*.*") If fm <> False Then
Workbooks.Open fm
Set bb = ActiveWorkbook
flag = True
End If
Loop
Workbooks.Add
Set cc = ActiveWorkbook
With cc.Sheets("Sheet1")
For i = 1 To 10
temp = aa.Cells(i, 1) * Int((10 * Rnd) + 1) ' 生成 1 到 10 之間的隨機數值
.Cells(i, 1) = temp
bb.Sheets(1).Cells(i, 1) = temp
Next
End With
flag = False
Do While Not flag ' 循環要求必須輸入文件名或選擇文件名
fm = Application.GetSaveAsFile name(fileFilter:="Excel files (*.xls),*.xl _ s,All files (*.*),*.*") If fm <> False Then
cc.SaveAs fm
flag = True
End If
Loop
bb.Save '保存
Set aa = Nothing: Set bb = Nothing: Set cc = Nothing '設置對象變量爲空
Application.Quit '關閉Excel
Application.ScreenUpdating = True '屏幕刷新關閉
Application.DisplayAlerts = True '信息警告開啓 End Sub
2) 文本文件 2.1 打開與新建 Open 語句 能夠對文件輸入/輸出 (I/O)。 語法 Open pathname For mode [Access access] [lock] As [#]filenumber [Len=reclength]
Open 語句的語法具有以下幾個部分: 部分 描輀 pathname 必要。字符串表達式,指定文件名,該文件名可能還包括目錄、文件夾及驅動器。 mode 必要。關鍵字,指定文件方式,有 Append、 Binary、 Input、 Output、或 Random 方 式。如果未指定方式,則以 Random 訪問方式打開文件。 access 可選。關鍵字,說明打開的文件可以進行的操作,有 Read、Write、或 Read Write 操 作。 lock 可選。關鍵字,說明限定於其它進程打開的文件的操作,有
Shared、Lock Read、Lock Write、和 Lock Read Write 操作。 filenumber 必要。一個有效的文件號,範圍在 1 到 511 之間。使用 FreeFile 函數可得到下一個 可用的文件號。 reclength 可選。小於或等於 32,767(字節)的一個數。對於用隨機訪問方式打開的文件,該值 就是記錄長度。對於順序文件,該值就是緩衝字符數。
說明
對文件做任何 I/O 操作之前都必須先打開文件。 Open 語句分配一個緩衝區供文件進行 I/O 之用,
並決定緩衝區所使用的訪問方式。
[新建] 如果 pathname 指定的文件不存在,那麼,在用 Append、 Binary、 Output、或 Random 方
式打開文件時,可以建立這一文件。
如果文件已由其它進程打開,而且不允許指定的訪問類型,則 Open 操作失敗,而且會有錯誤發生。
如果 mode 是 Binary 方式,則 Len 子句會被忽略掉。
重要
在 Binary、 Input 和 Random 方式下可以用不同的文件號打開同一文件,而不必先將該文件關閉。
在 Append 和 Output 方式下,如果要用不同的文件號打開同一文件,則必須在打開文件之前先關閉該 文件。
2.2 讀入與寫出
2.2.1讀入
Input #filenumber, varlist 從已打開的順序文件中讀出數據並將數據指定給變量
Get [#]filenumber, [recnumber], varname 將一個已打開的磁盤文件讀入一個變量之中 2.2.2寫入 Write #filenumber, [outputlist]
將數據寫入順序文件,以雙引號"數據"逗號,分隔數據
Print #filenumber, [outputlist] 將格式化顯示的數據寫入順序文件中
Put [#]filenumber, [recnumber], varname 將一個變量的數據寫入磁盤文件中。
2.3關閉
Close [filenumberlist] 關閉 Open 語句所打開的輸入/輸出 (I/O) 文件
注意 :
如果今後想用 Input # 語句讀出文件的數據,就要用 Write # 語句而不用 Print # 語句將數據寫入文件。 因爲在使用 Write # 時,將數據域分界就可確保每個數據域的完整性,因此可用 Input # 再將數據讀出來。 使用 Write # 還能確保任何地區的數據都被正確讀出。 Write 與 Print # 語句不同,當要將數據寫入文件 時,Write # 語句會在項目和用來標記字符串的引號之間插入逗號。Write # 語句在將 outputlist 中的最後 一個字符寫入文件後會插入一個新行字符,即回車換行符,(Chr(13)
+ Chr(10))
2.4其他文件函數
LOF(filenumber) 返回一個 Long,表示用 Open 語句打開的文件的大小,該大小以字節爲 單位。 EOF(filenumber) 返回一個 Integer,它包含 Boolean 值 True,表明已經到達爲 Random 或順序 Input 打開的文件的結尾。 Loc(filenumber) 返回一個 Long,在已打開的文件中指定當前讀/寫位置
Seek(filenumber) 返回一個 Long,在 Open 語句打開的文件中指定當前的讀/寫位置
2.5 示例
要求: 打開一文本文件 test1.txt, 已知其內容爲空格分隔 , 要求把其中每行首個數據寫入Excel 宏程序文件 的表1中, 再把數據寫入新建文件 test2.ini中
Sub test()
Dim Fm, i As Long, j As Long, k As Long
Dim TT, T1
On Error Resume Next
Fm = Application.GetOpenFilename("Text Files (*.txt), *.txt")
If Fm = False Then Exit Sub ' 取消選擇文件則退出 k = FreeFile
Open Fm For Input As #k ' 以隨機只讀的方式打開文件
f2 = FreeFile
Open "c:/test2.ini" For Output As #f2 ' 以隨機方式新建一個不存在的文件
j = 1
W ithWo rksheets("sheet1")
Do While Not EOF(k) ' 循環讀至文件最後一行 Line Input #k, TT ' 讀入一行數據並將其賦予某變量
T1 = Split(TT) ' 以文本中空格來分開這個字符串並賦值給變量,請參考 split函數幫助 .Cells(j, 1) = T1(0)
Print #f2, T1(0)
j = j + 1
Loop
EndW ith
Close #k ' 關閉文件
Close #f2 ' 關閉文件
End Sub
3) Access文件
使用 VBA來訪問數據庫,其實就是通過一定方法藉助數據庫引擎來訪問,關鍵是使用什麼方法來使
用引擎。目前訪問 ACCESS數據庫常用的有 DAO和 ADO方法,DAO就是 Database Access Object(數據庫 訪問對象 )的英文縮寫, DAO是老式的 , 它目前還在使用的原因是向下兼容和 ADO在一些地方還沒有取代 DAO的功能。 ADO是 ActiveX Data Object(數據控件對象)的英文縮寫,是目前較新和功能較強的方法。
通過 DAO或ADO可以訪問多種類型的數據庫,包括 Access、SQL Server、 Oracle等,也可訪問應用
程序的文件,如Excel文件、文本文件及 Email和 NEWS的文件。實際上利用控件來鏈接數據庫,其概念 大致相同,首先都需創建鏈接,其後用 Open方法產生各種類型的數據集對象,再對數據集對象操作來使 用數據庫內容。
3.1 DAO使用的步驟及方法 (1). 引用 DAO類型庫
從 VBE的”工具/引用”菜單中選擇可引用“Microsoft DAO 3.6 Object Library”項 .
設置DAO數據類型變量
(2). 定義 DAO對象變量
1) Dim db As Database, Database(數據庫 )變量對應於 Access數據庫 .
2) Dim rs As RecordSet, RecordSet(記錄集)變量對應於 Access數據庫的一個表或子表 . 多定義爲全局變量,以供程序多處使用。
(3). 打開數據庫
Set db = OpenDatabase (Thisworkbooks.path & "/數據庫名礀.mdb" ) ‘用 DAO怎麼樣打開有密碼的 ACCESS 數據庫 Set dbTemp = OpenDatabase("C:/db.mdb", False, False, ";PWD=1234 5")
(4).打開表或建立表的子表 A. 建立表的子表
Set rs = db.OpenRecordset("select * from 表名")
B. 打開表
Set RS = DB.OpenRecordset("表名", dbOpenDynaset)
Opendatabase 方法是打開數據庫並返回此數據庫的 database對象,其語法如下:
Set database的對象變量=opendatabase ([路徑及數據庫名礀 ],[除外性],[只讀 ]) 除外性:由true和 false值所構成,當值爲 true時代表僅允許唯一的使用者使用數據庫。 只讀:由 true和 false值所構成,爲 true代表數據庫僅提供讀取的服務
Openrecordset方法用來創建一個新的 recordset對象,語法爲:
Set recordset 對象變量=數據庫變量.openrecordset(來源,種類 ) recordset種類有5種,分別爲:表(table)、動態集(dynaset)、快照集(snapshot)、動態(dynamic)、正 向(forward-only),其中常用的時動態集(dynaset)實際上是引用一個或多個表中數據記錄的集合,是功 能最強的數據記錄集合類型,也是默認值。
(5). 操作數據庫記錄
對記錄的操作就是使用記錄集的對象方法和屬性來實現,特附錄常用屬性和方法如下。
記錄集對象的屬性和方法:
rs.Recordcount屬性 用來記錄目前數據記錄的數量,如判斷數據庫是否爲空 rs.EOF 屬性 是否是記錄的尾 rs.BOF 屬性 是否是記錄的頭 rs.Nomatch 屬性 返回上次查找成功與否
rs.Move n 方法 移動到第 n 條記錄 rs.Movenext 方法 移動到下一條記錄 rs.MovePrevious 方法 移動到上一條記錄 rs.Movefirst 方法 移動到第一條記錄 rs.Lastfirst 方法 移動到最後一條記錄 rs.Delete 方法 刪除當前記錄 rs.Edit 方法 修改當前記錄 (步驟爲三步: 1. 用 edit方法設置爲修改狀態;2. 將數據分別賦到記錄的各字 段; 3.用Updata方法,把記錄更新到數據庫中) rs.AddNew 方法 添加記錄
(添加記錄分三步:1. 用AddNew方法添加一個新的空白記錄;2. 將數據分別賦到記錄的各字段;3.用 Updata方法,把記錄更新到數據庫中去) rs.Updata 方法 更新內容到數據庫中 rs.Findfirst "字段名 = ' " & “查找內容 ” & " ' " 方法 查找記錄中字段與內容相配的首條記錄 rs.Findnext 方法 查找下一個匹配記錄 rs.FindLast 方法 查找最後一個匹配記錄 rs.FindPrevious方法 查找前一個匹配記錄 rs.Close
方法 關閉 記錄集關閉鏈接
字段集的屬性方法:
rs. Fields.Count 屬性 字段數目 rs. Fields(n) 第 n+1個字段 , Fields(0) 表示第一個字段 rs. Fields.Delete(Name As String) 方法 刪除字段 rs. Fields.Append (Object As Object) 方法 添加字段 rs. Fields.Refresh 方法 更新
字段的屬性方法 : rs. Fields(n).Name
rs. Fields(n).Size rs. Fields(n).Type rs. Fields(n).Fieldsize rs. Fields(n).value
示例: 打開一個數據庫,建立瀏覽, 查詢, 修改, 刪除, 添加等功能。 Option Explicit
Public totalRecs As Long, curRecNo As Long '用於記住 總記錄數 和 當前記錄號
Public DB1 As Database, RS1 As Recordset
Private Sub UserForm_Initialize() '窗口顯示
Set DB1 = OpenDatabase(ThisWorkbook.Path & "/pallet.mdb")
Set RS1 = DB1.OpenRecordset("pallet", dbOpenDynaset)
If RS1.EOF And RS1.BOF Then
MsgBox "Database is Null."
cmdExit_Click
Else
RS1.MoveLast ' 指針移動到最後記錄,以便統計記錄總數
RS1.MoveFirst
totalRecs = RS1.RecordCount
curRecNo = 1
SetData ' 設置窗口參數,按鈕是否可用
End If End Sub
Private Sub cmdFirst_Click() ' 第一條記錄 RS1.MoveFirst
curRecNo = 1
SetData End Sub
Private Sub cmdLast_Click() ' 最後一條記錄 RS1.MoveLast
curRecNo = totalRecs
SetData End Sub
Private Sub cmdPrevious_Click() '前一條記錄 RS1.MovePrevious
curRecNo = curRecNo - 1
SetData End Sub
Private Sub cmdNext_Click() ' 下一條記錄 RS1.MoveNext
curRecNo = curRecNo + 1
SetData End Sub
Private Sub cmdAdd_Click() ' 增加一條記錄 Dim i As Integer
RS1.AddNew
For i = 1 To 5
RS1.Fields(i) = Me.Controls("txt" & i)
Next i
RS1.Update
totalRecs = totalRecs + 1
curRecNo = totalRecs
RS1.MoveLast
SetData End Sub
Private Sub cmdDelete_Click() '刪除當前記錄 RS1.Delete
RS1.MoveNext
If RS1.EOF = True Then
RS1.MovePrevious ' 指針到底就朝前移
curRecNo = totalRecs - 1
End If
totalRecs = totalRecs - 1
SetData End Sub
Private Sub cmdModify_Click() '修改當前記錄 Dim i As Integer
RS1.Edit
For i = 1 To 5
RS1.Fields(i) = Me.Controls("txt" & i)
Next i
RS1.Update End Sub
Private Sub cmdFind_Click() ' 查找記錄,與第一個文本框內容相等
RS1.FindFirst "palletno='" & txt1.Text & "'"
If RS1.NoMatch Then
MsgBox "Sorry, find Nothing!"
Else
curRecNo = RS1.AbsolutePosition + 1
SetData
End If End Sub
Private Sub cmdClear_Click() ' 清除顯示內容 Dim i As Integer
For i = 1 To 5
Me.Controls("txt" & i) = ""
Next i End Sub
Private Sub cmdExit_Click() ' 退出窗口 RS1.Close
DB1.Close
Unload Me
End Sub
Sub SetData() ' 窗口數據設置 Dim i As Integer
txtCurRecNo.Text = curRecNo
cmdFirst.Enabled = curRecNo > 1
cmdPrevious.Enabled = curRecNo > 1
cmdLast.Enabled = curRecNo < totalRecs
cmdNext.Enabled = curRecNo < totalRecs
For i = 1 To 5
Me.Controls("txt" & i).Text = RS1.Fields(i)
Next End Sub
3.2 ADO使用的步驟及方法 (1). 引用 ADO類型庫
從 VBE的”工具/引用”菜單中選擇可引用“Microsoft ActiveX Data Object 2.5 Library”項 .
(2). 定義和生成ADO對象
1) Dim Cnn As New ADODB.Connection ‘數據庫連接 Connection對象變量
2) Dim Rst As New ADODB.Recordset ‘數據庫記錄集對象變量
3) Dim Fld As ADODB.Field ‘記錄字段對象變量
(3). 打開數據庫
Cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & This Workbook.Path & "/CONTACT1.MDB;" 用定義生成的數據庫連接對象的open方法,打開一個數據庫。如果要用ADO打開一個加密碼的數據庫, 方法如下: CNN.Open "provider=Microsoft.jet.OLEDB.4.0;Data Source=" & ThisWorkbook.Path & "/CONTACT1.MDB;" & ";Jet
OLEDB:Database Password=123"
(4).打開表或建立表的子表
Rst.Open "SELECT 字段名[,字段名] FROM 表名",Cnn, adOpenKeyset, adLockOptimistic 用記錄集對象的open方法,打開或生成一個數據庫的表或子表記錄。 如:Rs1.Open "Person", Cnn, adOpenKeyset, adLockOptimistic '取得聯繫人表所有記錄集內容
(5). 操作數據庫記錄
對記錄的操作就是使用記錄集的對象方法和屬性來實現,屬性和方法其實與 DAO的相似,這裏就不多說。 看下面示例,儘快學會使用 ADO. 示例 : 打開一個數據庫,建立瀏覽, 修改, 刪除, 添加和篩選等功能。使用 ADO修改和刪除記錄時,最關鍵 一條就是主關鍵字段不能重複,所以我們需要建立主關鍵字段爲自動編號類型 (Access自動編號 ),這樣就 不會重複,否則出錯!
Option Explicit
Public totalRecs As Long, curRecNo As Long '用於記住 總記錄數 和 當前記錄號
Public Cnn As ADODB.Connection ' 定義全局數據庫對象變量
Public Rs1 As ADODB.Recordset
'窗體啓動程序
Private Sub UserForm_Initialize() Set Cnn = New ADODB.Connection ' 創建一個連接和打開 Cnn 連接
Set Rs1 = New ADODB.Recordset ' 創建一個記錄集
Cnn.Open "Provider=Microsoft.Jet.O LEDB.4.0; DataSour ce=" &ThisWorkbook .Path& "/CONTACT1.MDB;" Rs1.Open "Person", Cnn, adOpenKeyset, adLockOptimistic ' 取得聯繫人表所有記錄集內容
Rs1.MoveLast
totalRecs = Rs1.RecordCount
curRecNo = 1
Rs1.MoveFirst
Call dis_form ' 顯示數據記錄到窗體 End Sub
'****[第一條]按鈕程序 **** Private Sub CommandButton1_Click() Rs1.MoveFirst curRecNo = 1 Call dis_form End Sub
'****[上一條]按鈕程序 **** Private Sub CommandButton2_Click() Rs1.MovePrevious curRecNo = curRecNo - 1 Call dis_form End Sub
'****[下一條]按鈕程序 **** Private Sub CommandButton3_Click() Rs1.MoveNext curRecNo = curRecNo + 1 Call dis_form End Sub
'****[最後一條]按鈕程序 **** Private Sub CommandButton4_Click() Rs1.MoveLast curRecNo = totalRecs Call dis_form End Sub
'****[刪除]按鈕程序 **** Private Sub CommandButton5_Click() Rs1.Delete totalRecs = totalRecs - 1
Rs1.MoveNext
If Rs1.EOF = True Then
Rs1.MovePrevious
curRecNo = curRecNo - 1
End If
Rs1.Update ' 更新數據記錄集,這點與DAO方法不同, DAO刪除後不需更新
Call dis_form End Sub
'**** [關閉]按鈕 ****
Private Sub CommandButton6_Click() Rs1.Close
Cnn.Close
Set Rs1 = Nothing: Set Cnn = Nothing ' 刪除對象
Unload Me ' 關閉窗體 End Sub
'****[更新]按鈕程序 **** Private Sub CommandButton8_Click() On Error Resume Next Rs1.Fields(1) = TextBox1.Text Rs1.Fields(2) = TextBox2.Text Rs1.Fields(3) = TextBox3.Text Rs1.Fields(4) = TextBox4.Text Rs1.Fields(5) = TextBox5.Text
Rs1.Fields(6) = TextBox6.Text Rs1.Fields(7) = TextBox7.Text Rs1.Fields(8) = TextBox8.Text Rs1.Update End Sub '****[查找]按鈕程序 **** Private Sub CommandButton10_Click() Dim Rs2 As New ADODB.Recordset Dim i As Integer Rs2.Open "select
* from person where 聯繫人編號 like " & TextBox1.Text, Cnn, adOpenKeyset, adLockOptimistic ‘SQL語言使用,查詢生成新的記錄集 If Rs2.EOF And Rs2.BOF Then MsgBox "Not find!" Else Sheets(1).Cells.ClearContents For i = 0 To Rs2.Fields.Count
- 1 Sheets(1).Cells(1, i + 1) = Rs2.Fields(i).Name Next Sheets(1).Cells(2, 1).CopyFromRecordset Rs2 MsgBox "The find result is displayed in Excel." End If
Rs2.Close
Set Rs2 = Nothing End Sub
'****[添加]按鈕程序 **** Private Sub CommandButton9_Click() Rs1.AddNew '添加一條記錄,注意Fields(0)字段爲主鍵且 Access自動編號,這可以保證添加內容可以重複,否則出 錯 totalRecs = totalRecs + 1 Rs1.Fields(1) = TextBox1.Text Rs1.Fields(2) = TextBox2.Text Rs1.Fields(3) = TextBox3.Text
Rs1.Fields(4) = TextBox4.Text Rs1.Fields(5) = TextBox5.Text Rs1.Fields(6) = TextBox6.Text Rs1.Fields(7) = TextBox7.Text Rs1.Fields(8) = TextBox8.Text Rs1.Update curRecNo = totalRecs Call dis_form End Sub
'****在窗體上顯示當前記錄***** Private Sub dis_form() TextBox1.Text = Rs1.Fields(1) TextBox2.Text = Rs1.Fields(2) TextBox3.Text = Rs1.Fields(3) TextBox4.Text = Rs1.Fields(4) TextBox5.Text = Rs1.Fields(5) TextBox6.Text = Rs1.Fields(6)
TextBox7.Text = Rs1.Fields(7) TextBox8.Text = Rs1.Fields(8) CommandButton1.Enabled = curRecNo > 1 CommandButton2.Enabled = curRecNo > 1 CommandButton3.Enabled = curRecNo < totalRecs CommandButton4.Enabled = curRecNo < totalRecs
TextBox9 = curRecNo End Sub
(6).數據庫使用 SQL查詢語言
數據庫一般都提供了關連式數據庫的查詢語言 SQL (Structured Query Language), 它是一種非常口語
化、既易學又易懂的語法。此語言幾乎是每個數據庫系統都必須提供的,用以表示關連式的操作,包含了 資料的定義 (DDL)以及資料的處理 (DML)。
對於 SQL語言的使用,請參考別的專業教程,本文就簡約介紹一下,示例中也僅用到一點SQL語言。
(6.1)資料定義 DDL(Data Definition Language)
資料定義語言是指對資料的格式和形態下定義的語言,他是每個數據庫要建立時候時首先要面對的, 舉凡資料分哪些表格關係、表格內的有什麼字段元主鍵、表格和表格之間互相參考的關係等等,都是在開 始的時候所必須規劃好的。 如建表格:Create Table table_name (column1 DATATYPE [NOT NULL] [NOT NULL PRIMARY KEY], column2 DATATYPE [NOT NULL],...)
(6.2)資料操作 DML(Data Manipulation Language)
資料定義好之後接下來的就是資料的操作。資料的操作不外乎增加資料( insert)、 查詢資料( query)、 更改資料( update) 、刪除資料( delete)四種模式,以下分別介紹他們的語法: 增加資料: INSERT INTO table_name (column1,column2,...) VALUES ( value1,value2, ...) 查詢資料: SELECT * FROM table_name WHERE conditions 更改資料:UPDATE table_name
SET column1=''xxx'' WHERE conditoins 刪除資料: DELETE FROM table_name WHERE conditions
4) 文件其它操作 4.1) 判斷文件存在
使用 Dir 函數判斷 , 格式: Dir [(pathname [, attributes] ) ] Dir 會返回匹配 pathname 的第一個文件名。示例如下 . strfile = Dir(ThisWorkbook.Path & "/filename.xls") '檢查文件是否存在 If strfile <> "" Then ‘存在就打開 Workbooks.Open ThisWorkbook.Path & "/filename.xls" Else ‘文件不存在就警告
MsgBox "文件不存在 ", vbOKOnly, "警告" End If
4.2) 搜查文件
使用 Application.FileSearch方法 示例如下 : pp = "D:/Temp": ff = 0 With Application.FileSearch .NewSearch .LookIn = pp .Filename = "prn*.tmp" ‘查找文件 prn*.tmp *爲指代符
If .Execute() > 0 Then ff = .FoundFiles.Count
End With
MsgBox pp & " 找到 " & ff & " 個檔案 !"
4.3) 刪除文件 使用 kill 方法 示例如下 : kill(“c:/mytest.txt”)
4.4) 取得文件日期屬性
使用 FileSystem object對象實現 , 示例函數如下
Function FileDate(filespec, datetype)
Dim fs, f, s
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFile(filespec) Select Case datetype Case 1: FileDate = f.DateCreated ' 檔案建立日期 Case 2: FileDate = f.DateLastAccessed ' 存取日期 Case 3: FileDate = f.DateLastModified '修改日期 End Select End Function
4.5) FileSystemObject文件系統對象的使用
FileSystemObject (FSO,下面簡礀爲 FSO) 對象模型,具有大量的屬性、方法和事件,使用面向對象
的“ object.method”語法,來處理文件夾和文件,可以在Office 2000 以後版本使用。 FileSystemObject 並 不是 VBA 的一部分,它是以一個 COM 組件的形式提供,可以在VB、 VBA、 VBScript 中使用。
FSO對象模型可以創建、改變、移動和刪除文件夾,或探測特定的文件夾是否存在,若存在,還可以
找出有關文件夾的信息,如名礀、被創建或最後一次修改的日期,等等。 FSO 對象模型還使文件處理變得 很容易。可以創建文件,插入和改變數據,以及輸出(讀取)數據。 FSO 對象模型,支持通過 TextStream 對象來創建和操作文本文件,但不支持二進制文件的創建或操作,這可以用 VBA語句完成。
使用 FileSystemObject 對象模型進行文件操作的步驟是: 1. 使用 CreateObject 方法來創建 FileSystemObject 對象;
2. 在新創建的對象上使用適當的方法;
3. 訪問對象的屬性。
下面代碼顯示如何創建 FileSystemObject 實例: Dim fso
Set fso = CreateObject("Scripting.FileSystemObject") 在這個示例中, Scripting 是類型庫的名字,而 FileSystemObject 則是想要創建的對象的名字。
使用 FSO 處理文件夾的任務和方法 創建文件夾 FileSystemObject.CreateFolder 刪除文件夾 Folder.Delete 或 FileSystemObject.DeleteFolder 移動文件夾 Folder.Move 或 FileSystemObject.MoveFolder 複製文件夾 Folder.Copy 或 FileSystemObject.CopyFolder 檢索文件夾 Folder.Name
如果文件夾在驅動器上存在,則找出它 FileSystemObject.FolderExists 獲得現有Folder 對象的實例 FileSystemObject.GetFolder 找出文件夾的父文件夾名 FileSystemObject.GetParentFolderName 找出系統文件夾的路徑 FileSystemObject.GetSpecialFolder
FSO 中寫數據到文本文件的方法
向打開的文本文件寫數據,不用後續一個新行字符 Write
向打開的文本文件寫數據,後續一個新行字符 WriteLine
向打開的文本文件寫一個或多個空白行 WriteBlankLines
FSO 中讀取文本文件的方法
從文件讀取指定數量的字符 Read
讀取一整行(一直到但不包括新行字符) ReadLine
讀取文本文件的整個內容 ReadAll
FSO 中移動、複製和刪除文件的方法 移動文件 File.Move 或 FileSystemObject.MoveFile 複製文件 File.Copy 或 FileSystemObject.CopyFile 刪除文件 File.Delete 或 FileSystemObject.DeleteFile
使用 FSO 處理文件、文件夾比使用 VBA 語句的方法具有更易操作的特點, FSO 除了不能處理二進制文 件,其文件和文件夾處理的方法也更完備,更直觀和易於使用。
第二節 工作表操作
在文件操作一節已經講了 Excel工作簿文件的打開、新建、保存和關閉了,這裏再講文件下的表格操作。 1) 新建與刪除 新建工作表、圖表或宏表。新建的工作表將成爲活動工作表。 Sheets.Add (Before, After, Count, Type) 說明:
Before Variant 類型,可選。指定工作表對象,新建的工作表將置於此工作表之前。
After Variant 類型,可選。指定工作表對象,新建的工作表將置於此工作表之後。
Count Variant 類型,可選。要新建的工作表的數目。默認值爲 1。
Type Variant 類型,可選。指定工作表類型。可爲以下 XlSheetType 常量之一: xlWorksheet、 xlChart、 xlExcel4MacroSheet 或 xlExcel4IntlMacroSheet。默認值爲 xlWorksheet。 如果 Before 和 After 兩者均省略,則新建的工作表將插入到活動工作表之前。 示例: Sheets.Add after:=Sheets(Sheets.Count) 該語句可以在最後一個工作表後增加一個新表
刪除工作表
Sheets(“工作表名 ”).Delete 示例:在工作表末新建一個和刪除倒數第二個表。
Sub MySht()
Application.DisplayAlerts = False '關閉刪除確認對話框
Sheets.Add after:=Sheets(Sheets.Count)
Sheets(Sheets.Count - 1).Delete
Application.DisplayAlerts = True '開啓確認對話框 End Sub
2) 隱藏與顯示
使用工作表的 visible屬性來設置工作表是否隱藏或顯示 隱藏 Sheets ("sheet2").Visible = False 顯示 Sheets ("sheet2").Visible =True
3)保護與撤銷
保護工作表使其不至被修改。
Sheets(“工作表名 ”).Protect (Password)
撤銷工作表保護使其被修改。
Sheets(“工作表名 ”).Unprotect (Password)
Password Variant 類型,可選。爲一個字符串,該字符串爲工作表或工作簿指定區分大小寫的密碼。如 果省略本參數,不用密碼就可以取消對該工作表或工作簿的保護。否則,必須指定密碼,通過密碼來取消 對該工作表或工作簿的保護。
示例: Sheets(“sheet1”).Protect “123456” Sheets(“sheet1”).Unprotect “123456”
如果要對工作進行詳細保護設置,可參考Excel VBA參考,這裏僅講簡單的參數設置。
第三節 單元格和區域操作
Excel數據的計算歸根到底還是對錶的單元進行的,所以單元格和區域操作非常重要的,這一節就詳
細介紹這方面的內容。
一、如何引用單元格和區域
1)用 Range屬性引用單元格和單元格區域 使用 Range 屬性來引用 A1 引用樣式中的單元格或單元格區域及進行屬性更改和賦值。如例句: Sheets("Sheet1").Range("A1:D5").Font.Bold = True
Sheets("Sheet1").Range("A1:D5").Value = 10000
Range 對象既可表單個單元格,也可表單元格區域。下面說明 Range 對象最常用方法。
引用 含義 Range("A1") 單元格 A1
Range("A1:B5") 從單元格 A1 到單元格 B5 的區域
Range("C5:D9,G9:H16") 多塊選定區域
Range("A:A") A 列
Range("1:1") 第一行
Range("1:5") 從第一行到第五行的區域
Range("1:1,3:3,8:8") 第 1、 3 和 8 行
Range("A:C") 從 A 列到 C 列的區域
Range("A:A,C:C,F:F") A 、 C 和 F 列
Range("單元格區域名礀 ") 命名的單元格區域
2)用 Cells屬性引用單元格
可用 Cells 屬性通過行列編號來引用單個單元格。下例中 Cells(6,1) 返回 Sheet1 上的單元格 A6,然後將 Value 屬性設置爲 10。如:Worksheets("Sheet1").Cells(6, 1).Value = 10 因爲可用變量替代行列編號,所以 Cells 屬性非常適合單元格區域中循環且速度很快。如下例所示: Sub CC () Dim Counter As Integer For Counter = 1 To 20 Worksheets("Sheet1").Cells(Counter,
3).Value = Counter Next Counter End Sub
3)用 Rows或Columns屬性引用行列
可用 Rows 屬性或 Columns 屬性來處理整行或整列。下例中,用 Rows(1) 返回 Sheet1 上的第一行,然
後將單元格區域的 Font 對象的 Bold 屬性設置爲 True。如:Worksheets("Sheet1").Rows(1).Font.Bold = True
下表舉例說明了使用 Rows 和 Columns 屬性的一些行和列的引用。 引用 含義 Rows(1) 第一行
Rows 工作表上所有的行
Columns(1) 第一列
Columns("A") 第一列
Columns 工作表上所有的列
4)用 Union方法合併區域後引用
若要同時處理若干行或列及區域,請創建一個對象變量並使用 Union 方法,將對多個區域組合起來。下 例將活動工作簿中第一張工作表上的第一行、第三行和第五行的字體設置爲加粗。 Sub SeveralRows() Worksheets("Sheet1").Activate Dim myUnion As Range Set myUnion = Union( Rows(1), Rows(3), Rows(5)) myUnion.Font.Bold = True End Sub
5)用括號 [ ]引用單元格和區域
可用方括號將 A1 引用樣式或命名區域括起來,作爲 Range 屬性的快捷方式。這樣就不必鍵入單詞 “ Range”或使用引號,如下例所示:Worksheets("Sheet1").[A1:B5].ClearContents [MyRange].Value = 30
6) 用 Offset相對其他單元格來引用單元格
處理相對於另一個單元格的某一單元格的常用方法是使用 Offset 屬性。下例中,將位於活動工作表上活 動單元格下一行和右邊三列的單元格的內容設置爲雙下劃線格式。 如:ActiveCell.Offset(1, 3).Font.Underline = xlDouble
7) 用 Selection 屬性引用活動區域
Select 方法激活工作表和工作表上的對象;而 Selection 屬性返回代表活動工作簿中活動工作表上的當前 選定區域的對象。在成功使用 Selection 屬性之前,必須先激活工作簿,並激活或選定工作表,然後用 Select 方法選定單元格區域(或其他對象)。
宏錄製器經常創建使用 Select 方法和 Selection 屬性的宏。下輀 Sub 過程是用宏錄製器創建的,該過程 演示了 Select 方法和 Selection 屬性在一起使用的方法。
Sub Macro1()
Sheets("Sheet1").Select
Range("A1").Select
ActiveCell.FormulaR1C1 = "Name"
Range("B1").Select
ActiveCell.FormulaR1C1 = "Address"
Range("A1:B1").Select
Selection.Font.Bold = True
End Sub
8)區域中循環引用單元格方法
使用 VBA時,經常需要對某一單元格區域內的每個單元格運行同一段語句。爲達到這一目的,可組
合循環語句和一個或多個方法來標識每個單元格,一次針對一個單元格,並執行該操作。
8.1) For...Next 循環語句與 Cells 屬性配合使用
使用 Cells 屬性時,可用循環計數器(或其他變量或表達式)來替代單元格索引編號。下例中變量
counter 代替行號。此過程在單元格區域 C1:C20 中循環,將絕對值小於 0.01的單元都置爲 0。
Sub RoundToZero1() For Counter = 1 To 20
If Abs(Cells(counter,3).value) < 0.01 Then Cells(counter,3) = 0
Next End Sub
8.2) For Each...Next 循環語句和 Range 屬性配合使用 示例如下: Sub RoundToZero2() For Each c In Worksheet s("Sheet1").Range("A1:D10").Cells If Abs(c.Value) < 0.01 Then c.Value = 0 Next End Sub
二、如何處理單元格和區域 1 處理三維區域 如果要處理若干工作表上相同位置的單元格區域,可用 Array 函數選定兩張或多張工作表。下例設置三 維單元格區域的邊框格式。 Sub FormatSheets() Sheets (Array("Sheet2", "Sheet3", "Sheet5")).Select Range("A1:H1").Select Selection.Borders(xlBottom).LineStyle = xlDouble End
Sub
2 處理活動單元格
ActiveCell 屬性返回代表活動單元格的 Range 對象。可對活動單元格應用 Range 對象的任何屬性和方 法,如下例所示。
Sub SetValue()
Worksheets("Sheet1").Activate
ActiveCell.Value = 35 End Sub 注意 只有活動單元格所在的工作表處於活動狀態時,才能處理該活動單元格。
3 選擇活動單元格周圍的單元格
CurrentRegion 屬性返回由空白行和空白列所包圍的單元格區域。下例中,選定區域擴充到與活動單元格
相鄰的包含數據的單元格中,然後用“貨幣”樣式設置該區域的格式。 Sub Region() Worksheets("Sheet1").Activate ActiveCell.CurrentRegion.Select Selection.Style = "Currency" End Sub
4 單元格和區域賦值
用賦值號 = 賦值,如給 A1賦值爲 10:Range(A1).Value=10 (由於 Value是默認屬性,所以可以直接省略 ) 區域賦值,如 Range(A1:D5)=10
5 單元格和區域賦予公式進行計算
把公式字符串賦予給單元格或區域的 Formula屬性,如下例 : 注意一點是公式字符串中要有開頭的等號=。 Sub EnterFormula() Worksheets("Sheet1").Range("D6").Formula = "=SUM(D2:D5)" End Sub
三、單元格和區域的定位
1) 使用單元格的 End屬性來定位邊界 如: 數據區域的最下行的確定: Sheets(1).cells( 65536,1).End(xlup).Row 數據區域的最右列的確定: Sheets(1).cells(1,1).End(xltoright).Column 選定包含單元格“ B4”的區域在 B 列中頂端的單元格: Range("B4").End(xlUp).Select 選定包含單元格“ B4”的區域在第 4 行中最右端的單元格: Range("B4").End(xlToRight).Select
將選定區域從單元格“ B4”延伸至第四行最後一個包含數據的單元格 : Range("B4", Range("B4").End (xlToRight)).Select
2) 善用已用區域UsedRange對象來獲得區域範圍 如:需要獲得先前表格已用區域的最右下角單元格位置 Sub Loc ()
temp = [a1] :[a1] = 1 ‘ 使用 A1單元格,保證已用區域從 A1開始 irow = ActiveSheet.UsedRange.Rows.Count ‘右下單元格行 icol = ActiveSheet.UsedRange.Columns.Count ‘右下單元格列 [a1] = temp ‘ 還原 A1的值 Cells(irow, icol).Select
‘ 選中右下角單元格
End sub
四、單元格和區域的保護與鎖定
1)工作表選擇改變事件過程中保護,如下:不許可用戶選擇及改動保護單元格區域,示例中保護 B1:B10 Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim rng As Range Set rng = Range("b1:b10") If Intersect(Target, rng) Is Nothing Then Exit Sub ‘ 選擇單元不在保護區內就退出 MsgBox "不可以選取單元格!"
& Target.Address ‘選擇單元在保護區內就改變選擇 ActiveSheet.Range("a1").Select End Sub
2)通過行列的隱藏來保護
本示例隱藏工作表“ Sheet1”的第5行和C列 Sub SetHide()
With Worksheets("Sheet1") ‘ 使用With …End With語句塊,提高效率 .Unprotect ‘ 撤銷保護,如果原先未保護則不需該句 .Rows(5).Hidden = True ‘ 隱藏第5行 .Columns("C").Hidden = True ‘ 隱藏C列 .Protect ‘ 啓動保護,如果原先未保護則不需該句
End with
End Sub
3)通過鎖定區域來保護,可限定未鎖定區域內輸入 Sub SetLock() ActiveSheet.Unprotect Cells.Locked = True ‘ 鎖定全表
Range("a1:b10").Locked =false ‘ 解鎖區域 A1:B10,限定該區域爲可輸入區
ActiveSheet.Protect End Sub
第四節 圖表的操作
Excel讓人喜愛的原因就是它有強大得計算功能和數圖相關聯的數據作圖功能。本節就介紹下 VBA代 碼作圖方面內容。通過代碼作重複的圖,可以大大提高效率,比如我的作品 GeoPlot(www.geoplot.net)。 Excel圖的代碼繪製,最好是學習錄製的宏來分析 VBA代碼的作用,最後優化而成通用程序塊。
一.新建及類型
1)設置一個對象等於新增圖表對象就建立好了一個新圖
1.1) 新圖賦值給對象變量
Set mychart = Sheets(1).ChartObjects.Add (ChrLeft, ChrTop, ChrWidth, ChrHeight)
說明:增加一個嵌入圖表,其左上角的位置座標爲( ChrLeft, ChrTop),長寬爲 ChrWidth×ChrHeight, 單位爲磅。1磅爲 1/72 英寸和 0.035 釐米,字體大小通常用磅數量度。 1.2) 直接增加一個圖對象到圖對象集Charts
Charts.A dd
2)圖的類型可以更改 Chart對象的屬性 ChartType來實現
2.1)圖表對象變量的使用
mychart.Chart.ChartType = xlXYScatterLines ' 散點圖折線類型
2.2)未設置對象變量的圖
它的類型更改需要在增加它後,連續操作讓它處於激活狀態( ActiveChart),這樣可通過當前活動
圖ActiveChart來使用。如:ActiveChart.ChartType = xlPie ‘餅圖
3)圖表有兩大類,一是嵌入工作表上的圖,另一類是作爲新工作表圖,其設置如下:
3.1)嵌入工作表上的圖
ActiveChart.Location Where:=xlLocationAsObject, Name:= "Sheet1" 或如1.1生成新圖時就定義爲
生成嵌入圖ChartObjects.Add
3.2)新工作表圖
ActiveChart.Location Where:=xlLocationAsNewSheet 或用圖表對象變量屬性更改 mychart.location
where:= xlLocationAsNewSheet
二.設置圖表的數據
一般是使用 Excel表格上數據,所以可以通過設置 Chart圖表對象的數據來源屬性來獲得作圖需要的
數據。如:ActiveChart.SetSource Date Source:=Sheets("Sheet1").Range("A1:B6"), PlotBy:= xlColumns 這裏的 PlotBy:= xlColumns表示按列繪製數據;也可以按行繪製,其參數爲PlotBy:= xlRows。
另外一種數據設置是對圖的橫、縱座標數據分別賦值。如:
mychart.chart.SeriesCollection.NewSeries ‘ 增加一個系列數據
mychart.chart.SeriesCollection(1).XValues = Array(45, 100) ‘ 橫座標數據組或單元對象
mychart.chart.SeriesCollection(1).Values = Array(50, 180) ‘ 縱座標數據組或單元對象
三.圖表格式設置
對於圖的格式設置,一般是錄製一個宏,再刪除不需要的語句,這樣是開發者最省事的方法。在本節
的示例中有詳細的格式設置,可以更改座標軸的名礀,大小範圍,刻度大小等。對不清楚的圖的類型名礀, 格式參數,我們都可以通過錄制宏來了解學習。時刻記住,錄製宏來分析代碼,是最好的學習方法。
四.散點圖增加一個系列和增加文字標籤
1)用圖表的系列集合對象的方法 NewSeries,就可以增加圖的系列,然後再對新系列進行設置,如下:
mychart.chart.SeriesCollection.NewSeries ‘ 增加一個系列數據 mychart.chart.SeriesCollection(1).XValues = Array(45, 100) ‘橫座標數據組或單元對象 mychart.chart.SeriesCollection(1).Values = Array(50, 180) ‘ 縱座標數據組或單元對象
2)對於散點圖,我們可以增加文字標籤於圖上,方法如下:增加一個新的系列,不過數據就一點,不顯 示數據點,而僅顯示它的數據標籤即可。如下示例。 With mychart.chart.SeriesCollection(2) .MarkerStyle = xlNone ' 不顯示點標記 .Points(1).HasDataLabel = True '
數據標記及顯示文字標籤 .Points(1).DataLabel.Text =”標籤文字” ' 標籤文字 .DataLabels.Position = xlLabelPositionCenter ' 位置風格,居中
End With
五.實例
1) 生成一個散點嵌入圖於工作表窗口中心,繪製一條直線(45,50)— (100,180), 在第一點顯示文字標籤
“Test”,此外還加一個點( 80, 100)。
代碼和詳細註釋如下:
Sub DrawChart()
'*******************************圖表對象的定義和生成*********************************** '定義對象變量,以便設置它爲圖表( chart)對象及圖位置大小變量
Dim mychart As Object, mysheet As Object
Dim ChrLeft As Long, ChrTop As Long, ChrWidth As Long, ChrHeight As Long
On Error Resume Next
Application.ScreenUpdating = False
ChrWidth = 250: ChrHeight = 250
ChrLeft = Abs(Windows(ThisWorkbook.Name).Width - ChrWidth) / 2
ChrTop = Abs(Windows(ThisWorkbook.Name).Height - ChrHeight) / 2 ' 計算圖表在窗口中心座標
Set mychart = Sheets(1).ChartObjects. Add(ChrLeft, ChrTop, ChrWidth, ChrHeight)
With mychart.Chart
.ChartType = xlXYScatterLines ' 散點折線圖類型
.SeriesCollection.NewSeries ' 增加一次投點,畫條直線
.SeriesCollection(1).XValues = Array(45, 100)
.SeriesCollection(1).Values = Array(50, 180)
.SeriesCollection(1).Points(1).HasDataLabel = True ' 點1是否顯示數據標籤
.SeriesCollection(1).Points(1).DataLabel.Text = "Test" ' 點1的標籤文字
.SeriesCollection.NewSeries ' 增加一次投點,就投個點( 80,100)
.SeriesCollection(2).XValues = 80
.SeriesCollection(2).Values = 100
End With '*******************************圖表風格定義*********************************** With mychart.Chart
.ChartArea.Font.Size = 10 ' 圖表字符的大小
.HasLegend = False ' 圖是否顯示圖例
.Axes(xlCategory, xlPrimary).HasTitle = True 'X 軸是否有座標名
.Axes(xlCategory, xlPr imary).AxisTitle.Characters.Text = "X"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrim ary).AxisTitle.Characters.Text = "Y" 'Y軸座標名"Y"
.PlotArea.Interior.ColorIndex = xlNone ' 定義投圖區爲透明
End With
With mychart.Chart.Axes(xlCategory)
.MinimumScale = 0 ' 定義X座標軸最小值
.MaximumScale = 200 ' 定義X座標軸最大值
.MinorUnit = 10 ' 定義次刻度線單位
.MajorUnit = 50 ' 定義主刻度線單位
.CrossesAt = 0 'X 軸交匯點設爲0
.MajorTickMark = xlInside ' 主刻度線方向朝內
.MinorTickMark = xlInside ' 次刻度線方向朝內
.HasMajorGridlines = False ' 是否顯示主網格線
.HasMinorGridlines = False ' 是否顯示次網格線
End With
With mychart.Chart.Axes(xlValue)
.MinimumScale = 0 ' 定義y座標軸最小值
.MaximumScale = 200 ' 定義y座標軸最大值
.MinorUnit = 10 ' 定義次刻度線單位
.MajorUnit = 50 ' 定義主刻度線單位
.CrossesAt = 0 'Y 軸交匯點設爲0
.MajorTickMark = xlInside ' 主刻度線方向朝內
.MinorTickMark = xlInside ' 次刻度線方向朝內
.HasMajorGridlines = False ' 是否顯示主網格線
.HasMinorGridlines = False ' 是否顯示次網格線
End With
Set mychart = Nothing ' 刪除圖表對象變量
Application.ScreenUpdating = True ' 恢復屏幕刷新 End Sub
2)根據工作表一的 A1:B10數據生成柱狀圖嵌入表一,位置爲數據右下角位置。
Sub Pic2() On Error Resume Next
Application.ScreenUpdating = False
Charts.Add
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceDat a Source:=Sheets("Sheet1").Range("A1:B10"), PlotBy:=xlColumns
ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet1"
ActiveSheet.Shapes(ActiveSheet.Shapes.C ount).Left = ActiveSheet.Cells(11, 3).Left '定位於單元格
(10,2)右下角
ActiveSheet.Shapes(ActiveSheet.Shape s.Count).Top = ActiveSheet.Cells(11, 3).Top
Application.ScreenUpdating = True End Sub
第三章 Excel VBA高級使用
通過以上章節的學習,估計大家都夠能使用 Excel VBA進行基本的數據計算、數據彙總、數據的保存、 數據庫的使用和繪製圖表了,這些功能已經可以解決我們平時所遇到的大多數問題。但有時還會遇到一些 較難的問題,如計算機硬件或底層方面的使用。這些問題可以使用本章介紹的Windows API來解決。
Windows API是Windows的 32位應用程序編程接口,是一系列複雜函數、消息和結構的集合。這種
集合被包含在一個後綴名爲 DLL的動態連接庫文件中,裝有Windows系統的電腦都有標準的Windows動 態連接庫文件。編程人員可用不同編程語言的引用方法來使用它們,進而編制出解決 Windows系統底層問 題的應用程序。Excel VBA中使用 API可以讓我們輕鬆實現一些高級功能,比如多媒體播放等,所以有必 要了解一些 API在 Excel VBA中的使用。一般來講,只有會了Windows API纔算真正進入了Windows系 統下程序開發的大門。
第一節 Win API的使用
Windows API 是英文Application Programming Interface的縮寫,Win32 API也就是微軟Windows 32位 操作系統的應用程序編程接口。我們可以認爲 API函數是構築整個Windows框架的基石,在它的下面是 Windows的操作系統核心,而它上面則是Windows的應用程序。在 Excel VBA中使用 API就是爲了開發 出實用高效的應用程序,而 VBA下使用 API函數需進行API函數的堀明才能使用。 一、堀明 API函數 堀明 VBA所在文件之外的過程或函數就能夠訪問
Windows API或其它外部動態連接庫( DLL)。在堀 明瞭過程或函數後,其調用方法與 VBA自己的過程或函數調用方法相同。要堀明一個 DLL文件中的過程
或函數,需要在代碼窗口增加一個 Declare語句。例如取的計算機名礀的函數 GetComputerName ,作如 下堀明:
Private Declare Function GetComputerName Lib "kernel 32" Alias "GetComputerNameA" (ByVal lpBuffer As
String, nSize As Long) As Long 或 Public Declare Function GetComputerName Lib "kernel 32" Alias "GetComputerNameA" (ByVal lpBuffer As
String, nSize As Long) As Long
以上堀明的不同在於所堀明函數的使用範圍, Private Declare堀明的是模塊私有,只能在堀明它的模 塊內調用; Public Declare堀明的是全局函數,可以在應用程序的任何地方調用,一般我們使用 Public Declare 堀明。堀明完畢後就能在程序中使用此函數。
二、使用 API函數或過程
以 API函數 Beep來說明 API函數的幾種使用方法, Beep函數的介紹如下: 【 VBA堀明】 Public Declare Function Beep Lib "kernel32" Alias "Beep" (ByVal dwFreq As Long, ByVal dwDuration As
Long) As Long 【說明】 用於生成簡單的堀音 【返回值】 Long,非零表示成功,否則返回零。 【參數表】 dwFreq --------- Long,堀音頻率(從 37Hz到32767Hz)。 dwDuration ----- Long,堀音的持續時間,以毫秒爲單位。如爲 -1,表示一直播放堀音,直到再次調用 該函數爲止。
可採用以下幾種方式使用API函數或過程,以 Beep爲例: (1)忽略函數返回值的調用: Beep 1000, 5000
注意此時函數的參數是不加括號的。
(2) Call方法調用: Call Beep(1000, 5000)
注意這裏需要加上括號,但我們不取回函數的返回值。
(3)取得函數返回值的調用: MyLng = Beep(1000, 5000)
此時需要加上括號,而且我們必須事先定義一個變量(變量的類型與函數返回值類型相同)來存儲
API函數的返回值。
三、堀明的一些說明
(1)堀明中的 Lib 和 Alias 是怎麼回事 一般情況下Win32 API函數總是包含在Windows系統自帶的或是其它公司提供的動態連接庫 DLL中, 而 Declare語句中的關鍵字Lib就是用來指定 DLL(動態連接庫)文件路徑是系統庫路徑的,這樣 VBA才 能找到這個 DLL文件,然後才能使用其中的 API函數。 如果我們只是列出 DLL文件名而不指出其完整路徑的話, VBA會自動到 Excel文件所在目錄、當前工 作目錄、Windows/System目錄、Windows目錄下搜尋這個
DLL文件。所以如果所要使用的 DLL文件不在
上輀幾個目錄下的話,我們應該指明其完整路徑。
Alias用於指定 API函數的別名,如果我們調用的 API函數要使用字符串(參數中包含 String型)的話, Alias關鍵字是必須的。這是因爲在 ANSI和 Unicode字符集中同一API函數的名礀可能不一樣,爲了保證 不出現堀明錯誤,所以我們使用 Alias關鍵字指出API函數的別名。
(2)常見API參數類型的說明
API函數的參數中最常見的是長整型數據( Long)類型,例如 API中的句柄、一些特定的常量、函數 的返回值都是此類型的值;另外幾種常見的參數類型有:整型Integer、 Byte型、String型等。
(3)堀明中的 ByVal是作什麼用的
這跟 VBA的參數傳遞方式有關,在默認情況下 VBA是通過傳值方式傳遞函數的參數、而有些 API函 數要求必須採用地址傳遞方式(ByRef)來傳遞函數參數(這兩種參數傳遞方式是不同的,前者傳遞的是 參數真實的值,而後者要求是一個地址指針)。堀明中的 ByVal 表明參數是傳遞一個值。
(4)怎樣輕鬆得到完整API函數堀明
Visual Basic 6.0 自帶 API文本查看器 API Text Viewer,我們可以使用它來找到 API函數的完整堀明, 然後把它粘貼到程序就可使用。如果未安裝VB6,大家可以到網上下載,此外網絡上還有很多 API函數的 介紹,大家也可以下載來學習。 大家使用 API有必要對它進行有一定了解,然後再去使用 API文本查看器。雖然不必刻意研究每個 API 函數(如果真的知道 100來個 API函數的使用,相信絕對有用),但是需要我們瞭解一下該函數的作用。 而對 API函數功能的介紹,網絡也有現成的軟件供大家下載使用。
四、示例
(1)彈出一個對話框,提示計算機的名礀,並且揚堀器喇叭會鳴叫。
Private Declare Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As
Long
Private Const MAX_COMPUTERNAME_LENGTH As Long = 31
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer
As String, nSize As Long) As Long
Sub ComputerName() Dim dwLen As Long
Dim strString As String
'創建緩衝區 32位
dwLen = MAX_COMPUTERNAME_LENGTH + 1
strString = String(dwLen, "X")
'獲得計算機名礀
GetComputerName strString, dwLen
'獲得實際名礀字串
strString = Left(strString, dwLen)
'播放頻率爲 4500赫茲的揚堀器堀音,持續 100微秒
For I = 0 To 5
Beep 4500, 100
DoEvents
Next
'顯示計算機名礀
MsgBox "電腦名礀是 " & strString & ", 我搞對了嗎? " End Sub
(2) API函數 ShellExecute的使用,打開網頁和發送郵件。 API函數 ShellExecute的介紹: 【 VBA堀明】
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long,
ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As
String, ByVal nShowCmd As Long) As Long 【別名】 ShellExecuteA 【說明】 查找與指定文件關聯在一起的程序的文件名 【返回值】 Long,非零表示成功,零表示失敗。 【參數表】 hwnd ----------- Long,指定一個窗口的句柄,有時候,windows程序有必要在創建自己的主窗口前 顯示一個消息框 lpOperation ---- String,指定字串“ open”來打開 lpFlie文檔,或指定“
Print”來打印它 lpFile --------- String,想用關聯程序打印或打開一個程序名或文件名 lpParameters --- String,如 lpszFlie是可執行文件,則這個字串包含傳遞給執行程序的參數 lpDirectory ---- String,想使用的完整路徑 nShowCmd ------- Long,定義瞭如何顯示啓動程序的常數值。參考ShowWindow函數的 nCmdShow 參數 示例代碼:
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Const SW_SHOWNORMAL As Long = 1
Private Sub CommandButton1_Click() Unload Me End Sub
Private Sub Label4_Click() '啓動郵件程序
ShellExecute 0, "Open", "mailto:[email protected]", "", "", SW_SHOWNORMAL
Unload Me End Sub
Private Sub Label5_Click()
'啓動網絡程序, 連接到Excelhome論壇的帖子上 ShellExecute 0, "Open", _ "http://club.excelhome.net/dispbbs.asp?boardid=2&replyid=462739&id=178278&page=1&skin=0&Star=1",
"", "", SW_SHOWNORMAL
Unload Me End Sub
第二節 Excel VBA程序的保密
Excel VBA 程序的保密是個難點,大家對此都感興趣,原因是想保護核心代碼和技術以及對商業的
Excel VBA 程序進行安全保障。Excel 對 VBA 工程加密僅起簡單保護作用,稍懂一點的程序員就可手工 破解或使用網上的破解軟件。目前唯一能保障 VBA 代碼就一個方法,把 VBA 核心代碼封裝到動態連接 庫( DLL)文件中。大家可以放心動態連接庫,因爲它是很難被反編譯的(反編譯的代價比開發還大) 、 非常安全。下面就開始介紹如何製作和使用動態連接庫 DLL。
一、動態連接庫 DLL的製作和使用
1)用 VB6 企業版下 ActiveX.DLL 工具開發,在缺省類代碼窗口輸入下面代碼:
Sub copy12(x As Integer, y As Integer) ' 目的是把表x單元格值賦值給表 y '定義將要用到的變量數據,對象變量,整型數據變量
Dim xlapp As Object, xlbok As Object,xlsht1 As Object,xlsht2 As Object, xlrng As Object
Dim i As Integer, j As Integer, irow1 As Integer, icol1 As Integer
Dim irow2 As Integer, icol2 As Integer, cellssum As Integer
Set xlapp = GetObject(, "Excel.Application") '取得 Excel實例
Set xlbok = xlapp.activeworkbook ' 取得 Excel實例下活動工作簿
Set xlsht1 = xlbok.Worksheets(x) ' 取得 Excel實例下活動工作簿的第 x表格
Set xlsht2 = xlbok.Worksheets(y) ' 取得 Excel實例下活動工作簿的第 y表格
Set xlrng = xlsht1.UsedRange ' 取得 Excel實例下活動工作簿的第x表格的已用區域
cellssum = xlrng.Count 'x 表格的已用區域的單元格數目
irow1 = xlrng.cells(1).row ' 已用區域的第1單元格的行
icol1 = xlrng.cells(1).Column ' 已用區域的第1單元格的列
irow2 = xlrng.cells(cellssum).row ' 已用區域的最後單元格的行
icol2 = xlrng.cells(cellssum).Column ' 已用區域的最後單元格的列
For i = irow1 To irow2 ' 從已用區域第1行到最後一行循環
For j = icol1 To icol2 ' 從已用區域第1列到最後一列循環
xlsht2.cells(i, j) = xlsht1.cells(i, j) ' 把x表已用區域單元格數據賦值給y表相同位置
Next ' 此處目的可用別方法實現,或加判斷實現別的
Next
Set xlapp = Nothing ' 清除定義的對象爲空
Set xlbok = Nothing
Set xlsht1 = Nothing
Set xlsht2 = Nothing
Set xlrng = Nothing End Sub
Function Getstrgs(STRG As String, FC As String, LC As String) As Variant '求字符間各子串賦值給數組 Dim ss() As String On Error Resume Next
Sum = 0
For i = 1 To Len(STRG) - 1
If Mid(STRG, i, 1) = FC Then
For j = i + 1 To Len(STRG)
If Mid(STRG, j, 1) = LC Then Sum = Sum + 1
Next
End If
Next
If Sum < 1 Then
MsgBox "No substring found!"
Exit Function
End If
ReDim ss(Sum - 1) As String
Sum = 0
For i = 1 To Len(STRG) - 1
If Mid(STRG, i, 1) = FC Then
For j = i + 1 To Len(STRG)
If Mid(STRG, j, 1) = LC Then
ss(Sum) = Mid(STRG, i + 1, j - i - 1)
Sum = Sum + 1
End If
Next
End If
Next
Getstrgs = ss End Function
以上代碼僅展示類中的過程和函數,以便在 VBA中使用。
2)修改將要引用的類名礀,在 VB6的類屬性窗口修改,本例修改爲 mycopy1to2
3)工程保存,本例保存爲 sheetcopy1to2
4) DLL生成,本例保存爲sheetcopy1to2.dll 2-4步驟對大家來說,不應該存在問題的。
二. VBA中調用 DLL
1) VBE窗口下,點工具菜單-引用,在點彈出窗口的瀏覽按鈕,找到你的 DLL文件,最好和 EXCEL
文件放一個目錄下,便於下一步驟。
2) DLL的註冊,如下:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Shell "Regsvr32 /u /s " & Chr(34) & ThisWorkbook.Path & "/sheetcopy1to2.dll" & Chr(34)
End Sub
Private Sub Workbook_Open()
'一定要先引用 dll,纔可以自動註冊."Regsvr32 /s " 中/s是表示不出現對話框
On Error GoTo errline
Shell "Regsvr32 /s " & Chr(34) & ThisWo rkbook.Path & "/sheetcopy1to2.dll" & Chr(34)
Exit Sub errline: MsgBox "程序在註冊DLL函數時出現錯誤! " End Sub
也可以在Windows 開始菜單下的運行命令對話框中運行 Regsvr32 "DLL全路徑/文件名 .dll" 來註冊
DLL文件
3) VBA中使用 DLL的過程和函數,代碼示例如下 VBE下新建如下模塊:
Sub mycopy1to2()
Dim bb As New mycopy1to2 ' 定義 bb爲 DLL中的類mycopy1to2 bb.copy12 1, 2 ' 表格1內容到表格2,使用類mycopy1to2新實例 bb的過程
Set bb = Nothing End Sub
Sub mycopy2to3()
Dim bb As New mycopy1to2 bb.copy12 2, 3 ' 表格2內容到表格 3
Set bb = Nothing End Sub
Sub mycopy3to1()
Dim bb As New mycopy1to2 bb.copy12 3, 1
Set bb = Nothing End Sub
Sub string1()
Dim aa As Variant
Dim bb As New mycopy1to2 ' 定義 bb爲 DLL中類 mycopy1to2 新實例 aa = bb.Getstrgs(Cells(1, 1), Cells(1, 2), Cells(1, 3)) '使用類mycopy1to2新實例 bb的函數
For i = 0 To UBound(aa) '用 DLL中類的函數求字符串的各子串
Cells(i + 2, 1) = aa(i)
Next
Set bb = Nothing End Sub
代碼能理解多少就多少,這是次要的,主要是學會如何輕鬆使用 DLL保護自己的 VBA代碼。學到這,
相信大家應該已經會製作 DLL文件和在 VBA中使用它了。
2) 獲得硬盤物理地址
爲什麼要獲得物理地址,那是因爲電腦上唯一不變的就是硬盤物理地址號碼。比如網卡的物理地址, 大家都會改動。因此獲得該硬盤物理地址號碼用來加密和註冊,便顯得非常之重要。其獲得地址的代碼如 示例,由於其較長,所以這裏就省略。實際使用時,把該代碼和註冊加密的代碼封裝到 DLL庫中使用。
3) 加密與註冊
對正版軟件的註冊,有效的方法是一機一碼,即一勻電腦一個註冊碼。即使別人獲得了註冊碼和軟
件,在別的機子上也無法使用。這一機一碼就是基於電腦硬盤的唯一物理地址。打個比方來理解這個方法: 電腦上的硬盤物理地址爲 DISK_ID,經過鑰匙串 KEY1加密得到User_ID;軟件開發人員然後根據鑰匙串 KEY1解密User_ID獲得用戶的 DISK_ID,再經鑰匙串 KEY2加密獲得所謂的註冊號Reg_ID;用戶輸入
Reg_ID並存在電腦註冊表或文件上,軟件啓動後,調用註冊覈對功能,通過 KEY2加密 DISK_ID獲得一 字符串,與 REG_ID對比,看是否一致,不一致則提示未註冊並關閉程序運行。這裏的KEY1和 KEY2及 加密解密算法,都存放在 DLL中,核心程序也存放在該DLL中,所以該方法註冊可以保證一機一碼且安 全。下面就介紹多種字符串加密解密算法的一種,是我以前看啥資料想到後設計出的。
基礎原理如下:
A. 可見字符的ASC碼:0-9的 Asc碼爲 48-57;大寫A-Z的 Asc碼爲 65-90;小寫a-z 的 Asc碼爲 97-122。
Asc碼是一整數型數據,佔一個字節8位長度。
B. 異或操作(對應位的數字不同則爲 1,相同爲0):舉個例,電腦裏一個字節的二進制數: 01101110
與11000011異或結果爲10101101,該結果在與11000011再異或一次,其結果是 01101110,這與開始的數 相同,所以一個數對另一個數兩次異或就會復原。
(1)加密步驟,PlainStr爲待加密字串, KEY爲鑰匙字串。
第一步:取 KEY第一個字符的 Asc碼和 PlainStr每一個字符的 Asc碼異或,如果異或結果爲可見字符的
Asc碼範圍,則其 Asc碼對應的字符爲新加密字符,否則新加密字符就是剛纔的 PlainStr對應位置的字符, 各個加密字符合並就是被 KEY第一個字符的 Asc碼加密過的字符串,並取代 PlainStr。
第二步:循環第一步,依次用 KEY的其餘字符按第一步方法執行,得到最後的PlainStr。
第三步:異或操作後的 PlainStr長度爲偶數,則分爲左右兩半,左右兩字符串各自進行反序,其後合併
成一個字符串。
第四步:經過以上三步的操作, PlainStr字符串就經過鑰匙字串 KEY的加密。
(2)解密步驟,PlainStr爲待解密字串, KEY爲鑰匙字串。
第一步:PlainStr長度爲偶數,則分爲左右兩半,左右兩字符串各自進行反序,其後合併成一個新的字
符串 PlainStr。
第二步:取 KEY最後一個字符的 Asc碼和 PlainStr每一個字符的 Asc碼異或,如果異或結果爲可見字符
的 Asc碼範圍,則其 Asc碼對應的字符爲新解密字符,否則新解密字符就是剛纔的 PlainStr對應位置的字 符,各個解密字符合並就是被 KEY最後一個字符的 Asc碼解密過的字符串,並取代 PlainStr。
第三步:循環第二步,依次用 KEY的其餘倒序字符按第二步方法執行,得到最後的PlainStr。
第四步:經過以上三步的操作, PlainStr字符串就經過鑰匙字串 KEY的解密。
示例代碼如下:
'****************************************************************************** ' 加密解密算法 '可見字符ASC碼: 48-57(0-9);65-90(A-Z);97-122(a-z) '異或結果爲可見字符則異或 '偶數則把異或結果分成兩半各自並反序,增加破解難度
'***********************************加密*************************************** Private Function Encrypt(PlainStr As String, key As String) as string
Dim Char As String, KeyChar As String, NewStr As String, AscCode As Long
Dim i As Integer, j As Integer, Side1 As String, Side2 As String
For j = 1 To Len(key) '鑰匙字符串正向逐個取字符,用其 Asc碼和待加密字符串各字 符的 Asc碼異或操作
NewStr = ""
KeyChar = Mid(key, j, 1)
For i = 1 To Len(PlainStr) ' 取待加密字符串各字符
Char = Mid(PlainStr, i, 1)
AscCode = Asc(Char) Xor Asc(KeyChar) ' 對字符的 Asc碼異或操作
If (AscCode <= 57 And AscCode >= 48) Or (AscCode <= 90 And AscCode >= 65) Or (AscCode <=
122 And AscCode >= 97) Then
NewStr = NewStr & Chr(AscCode) ' 異或後的 Asc碼是可見字符的 Asc碼,則把異或結
果轉成字符,加入異或結果字符串
Else
NewStr = NewStr & Char ' 異或後的 Asc碼是不可見字符的 Asc碼,則把原先
字符加入異或結果字符串
End If
Next i
PlainStr = NewStr Next j
If Len(PlainStr) Mod 2 = 0 Then ' 異或結果字符串,其長度爲偶數則分左右兩半並各自反
序
Side1 = StrReverse(Left(PlainStr, (Len(PlainStr) / 2)))
Side2 = StrReverse(Right(PlainStr, (Len(PlainStr) / 2)))
PlainStr = Side1 & Side2 ' 合併左右反序字符串 End If
Encrypt = PlainStr ' 生成加密結果字符串
End Function
'***********************************解密*************************************** Private Function Decrypt(PlainStr As String, key As String) as string
Dim Char As String, KeyChar As String, NewStr As String, AscCode As Long
Dim i As Integer, j As Integer, Side1 As String, Side2 As String
If Len(PlainStr) Mod 2 = 0 Then ' 字符串爲偶數長度,則分左右兩半並各自反序
Side1 = StrReverse(Left(PlainStr, (Len(PlainStr) / 2)))
Side2 = StrReverse(Right(PlainStr, (Len(PlainStr) / 2)))
PlainStr = Side1 & Side2 ' 合併左右反序後字符串 End If
For j = Len(key) To 1 Step -1 '反順序逐個取鑰匙字符串各字符,用其 Asc碼和待解密 字符串各字符的 Asc碼異或操作
NewStr = ""
KeyChar = Mid(key, j, 1)
For i = 1 To Len(PlainStr) ' 對字符串每個字符的 Asc碼進行異或
Char = Mid(PlainStr, i, 1)
AscCode = Asc(Char) Xor Asc(KeyChar) ' 字符的 Asc碼進行異或
If (AscCode <= 57 And AscCode >= 48) Or (AscCode <= 90 And AscCode >= 65) Or (AscCode <=
122 And AscCode >= 97) Then
NewStr = NewStr & Chr(AscCode) ' 異或後的 Asc碼是可見字符的 Asc碼,則把異或結
果轉成字符,加入異或結果字符串
Else
NewStr = NewStr & Char ' 異或後的 Asc碼是不可見字符的 Asc碼,則把原先
字符加入異或結果字符串
End If
Next i
PlainStr = NewStr Next j
Decrypt = PlainStr
End Function
第四章 Excel VBA優化及結束語
第一節 Excel VBA優化
由於 Microsoft Office辦公套件的廣泛應用,以及該軟件版本的不斷提升,功能不斷完善,在 Office 辦公套件平勻上開發出的的 VBA應用程序越來越多,而 VBA是一種宏語言,在運行速度上有很大的限制。 因此 VBA編程的方法直接關係到VBA程序運行的效率,本節列舉了一些提高VBA程序運行效率的方法。
方法1:儘量使用 VBA原有的屬性、方法和Worksheet函數
由於 Excel對象多達百多個,對象的屬性、方法、事件多不勝數,對於初學者來說可能對它們不全部
瞭解,這就產生了編程者經常編寫與 Excel對象的屬性、方法相同功能的 VBA代碼段,而這些代碼段的運 行效率顯然與Excel對象的屬性、方法完成任務的速度相差甚大。例如用 Range的屬性 CurrentRegion來返 回Range 對象,該對象代表當前區。(當前區指以任意空白行及空白列的組合爲邊界的區域)。同樣功能的 VBA代碼需數十行。因此編程前應儘可能多地瞭解 Excel對象的屬性、方法。
充分利用Worksheet函數是提高程序運行速度的極度有效的方法。如求平均工資的例子: For Each c In Worksheet(1).Range(″A1:A1000″)
TotalV alue =TotalV alue+ c.Value
Next
AverageValue = TotalValue / Worksheet(1).Range(″A1:A1000″).Rows.Count
而下面代碼程序比上面例子快得多:
AverageValue=Application.WorksheetFunction.Average(Worksheets(1).Range(″A1:A1000″))
其它函數如 Count,Counta,Countif,Match,Lookup等等,都能代替相同功能的 VBA程序代碼,提高程序
的運行速度。
方法2:儘量減少使用對象引用,尤其在循環中
每一個 Excel對象的屬性、方法的調用都需要通過 OLE接口的一個或多個調用,這些OLE調用都是
需要時間的,減少使用對象引用能加快 VBA代碼的運行。例如
1).使用With語句。
Workbooks(1).Sheets(1).Range(″A1:A1000″).Font.Name=″Pay″
Workbooks(1).Sheets(1).Range(″A1:A1000″).Font.FontStyle=″Bold″ ... 則以下語句比上面的快
With Workbooks(1).Sheets(1).Range(″A1:A1000″).Font
.Name = ″Pay″
.FontStyle = ″Bold″
...
End With
2).使用對象變量。
如果你發現一個對象引用被多次使用,則你可以將此對象用 Set 設置爲對象變量,以減少對對象
的訪問。如:
Workbooks(1).Sheets(1).Range(″A1″).Value = 100
Workbooks(1).Sheets(1).Range(″A2″).Value = 200
則以下代碼比上面的要快:
Set MySheet = Workbooks(1).Sheets(1)
MySheet.Range(″A1″).Value = 100
MySheet.Range(″A2″).Value = 200
3).在循環中要儘量減少對象的訪問。 For k = 1 To 1000
Sheets(″Sheet1″).Select
Cells(k,1).Value = Cells(1,1).Value
Next k
則以下代碼比上面的要快:
Set TheValue = Cells(1,1).Value
Sheets(″Sheet1″).Select
For k = 1 To 1000
Cells(k,1).Value = TheValue
Next k
方法3:減少對象的激活和選擇
如果你的通過錄制宏來學習 VBA的,則你的 VBA程序裏一定充滿了對象的激活和選擇,例如
Workbooks(XXX).Activate、 Sheets(XXX).Select、 Range(XXX).Select等,但事實上大多數情況下這些操作不 是必需的。例如
Sheets(″Sheet3″).Select
Range(″A1″).Value = 100
Range(″A2″).Value = 200
可改爲: With Sheets(″Sheet3″)
.Range(″A1″).Value = 100
.Range(″A2″).Value = 200
End With
方法4:關閉屏幕更新
如果你的 VBA程序前面三條做得比較差,則關閉屏幕更新是提高 VBA程序運行速度的最有效的方法,
縮短運行時間2/3左右。關閉屏幕更新的方法:
Application.ScreenUpdate = False
請不要忘記 VBA程序運行結束時再將該值設回來:
Application.ScreenU pdate =Tr ue
方法5:變量類型確定,少用變體變量
Option Explicit 語句, 在模塊級別中使用,強制顯式堀明模塊中的所有變量。 如果模塊中使用了
Option Explicit,則必須使用 Dim、 Private、 Public、 ReDim 或 Static 語句來顯式堀明所有的變量。如果 使用了未堀明的變量名在編譯時間會出現錯誤。如果沒有使用 Option Explicit 語句,一般所有未堀明的變 量都是 Variant 類型的。
注意 使用 Option Explicit 可以避免在鍵入已有變量時出錯,在變量的範圍不是很清楚的代碼中使用
該語句可以避免混亂 .
方法6:關閉Excel系統提示
'本示例關閉所有打開的工作簿。如果某個打開的工作簿有改變, Microsoft Excel 將顯示詢問是否保存
更改的對話框和相應提示。
Workbooks.Close 實際開發程序時,需要關閉提示信息對話框,給用戶簡潔高效的體驗.
Application.DisplayAlerts = False '信息警告關閉 請不要忘記 VBA程序運行結束時再將該值設回來: Application.DisplayA lerts =Tr ue '信息警告開啓
關閉信息警告後, 保存文檔及關閉需要先保存,在關閉 Workbooks("filename.xls").Save '文件保存
Workbooks("filename.xls").Close SaveChanges:=True '文件關閉, 不出現是否要保存的窗口,並保存所有對此工作簿的更改。 Workbooks("BOOK1.XLS").Close SaveChanges:=False '本示例關閉 Book1.xls,並放棄所有對此工作簿的更改。 這樣可以提高程序的簡潔性,給用戶服務 .
方法7: 提高關鍵代碼和循環代碼的效率
不同方法執行效率的差異,但千萬不要因爲追求效率而損失了代碼的可讀性、清晰性。效率的優化必
須是針對關鍵代碼的優化,對於一些在程序執行過程中,只執行很少次數的代碼,沒有必要犧牲可讀性而 進行優化。對於代碼執行效率,千萬不要人云亦云,必要時候,自己動手測試一下,結果往往會出 乎 意料。
代碼執行時間的測算VBA和 VB中,沒有專門的代碼執行事件測算工具和方法,筆者一般是使用 Timer
函數,其返回值是一個 Single類型的數值,代表從午夜開始到現在經過的秒數,此數值包括小數部分,但 精確程度在Windows NT,2000和 XP下大概接近 10毫秒。如果要測試一段代碼的執行速度,可以使用如 下方法:
Sub MeasureTime()
Dim Time1 As Single, Time2 As Single
Dim TotalTime As Single
Dim Times As Long
Dim i As Long
Times = 10000
Time1 = Timer
For i = 1 To Times Step 1
Mytest1
Next i
Time2 = Timer
TotalTime = (Time2 - Time1) * 1000
MsgBox "執行時間: " & TotalTime & " 毫秒(次數: " _
& Times & ")"
End Sub
SubMy test1() Dim i As Long
Dim s As String
i = Rnd
s = Format(i, "#.00")
End Sub
過程 MeasureTime可以測試一個過程的執行速度,因爲一般一個過程執行會很快,所以使 用循環, 執行n次(第8行設置),在第 12行調用測試的過程,通過循環前的時間(第9行)和 循環後的時 間(第15行),計算總共執行時間(第17行)。使用這個方法,就可以做一些測試,看哪些方法執行效率 更高。另外,由於Windows的多任務特定,測試時最好關閉其他無關程序,以獲得較準確的測試結果。
方法8 注意單元格寫法
cells(1,1) >>>>> range("a1")>>>>.[a1] cells(1,1)符合 EXCEL 結構,最快 range("a1")有對象,稍稍慢 [A1] 寫的快,運行慢
方法9 不要直呼其名
a= Worksheets(1).Name >>>>> a=Worksheets("Sheet1").name
方法10 少用 RANGE對象,可用數組取代,速度快 5-10倍, Test2就比 Test1快。
Sub Test1()
Dim i As Long, j As Long, buf As Long
For i = 1 To 10000
For j = 1 To 100
buf = Cells(i, j)
N ext j
Next i
End Sub
Sub Test2()
Dim i As Long, j As Long, buf As Long, C As Variant
For i = 1 To 10000
For j = 1 To 100
buf = C(i, j)
N ext j
Next i
End Sub
方法11 注意函數的類型 , 儘量少用 Variant變量,多用整型變量,如多用整型變量函數。
Chr$ ChrB$ Command$
CurDir$ Date$ Dir$
Error$ Format$ Hex$
Input$ InputB$ LCase$
LeftB$ LTrim$
Mid$ MidB$ Oct$
Right$ RightB$ RTrim$
Space$ Str$ String$
Time$ Trim$ UCase$
這些字符型函數 就比chr date space 等快,因爲不加後綴類型指定的函數,其返回值是 Variant類型結
果。
第二節 結束語
經過一禮拜的疲勞(沒功勞有苦勞,沒苦勞總有疲勞,套一句《瘋狂石頭》的電影對白) ,我總算結 束了開始的計劃,也算是有頭有尾,稍感欣慰。這期間,我要感謝各位 VBA愛好者的鼓勵和支持,你們 的堅持瀏覽讓我有信心繼續寫下去,讓我感到我寫的還有點用(不是瞎寫、亂寫的,無亂灌水之嫌疑)。
我對程序開發,以前學過很多東西,可以說是陪着一些計算機開發語言發展走過一段時間的。記得 96
年大學時,我們學彙編語言,那時覺得像天文;覺得難,就學習 Foxbase數據庫,記得考計算機二級時, 我上機得了滿分,一下子有信心了,就轉而學習 VB5,但學來學去,就是沒法突破,後來碩士期間,我學 會了 VB6,解決了一個實際問題,這下對 VB6開發及程序開發,有了更深刻的理解;但還是覺得VB6沒 能有好的辦法解決計算機複雜的問題,比如矢量圖的繪製和保存,我就一直搞不會。後來東看西看,學了 很多計算機東西。讀博士期間,用 Excel解決數據計算和作圖,由於是要重複作類似的,所以學下了 VBA, 突然發現
Excel VBA是很適合我這種使用者—需要快速解決工作學習的實際問題, 由此我也開發了世界一 流的地化數據投圖軟件Geoplot,關於它的論文發表在 Computers & Geosciences上。在開發這個軟件期間, 學了很多東西,這些核心的東西我都在這個論壇發過貼了。所以,我隆重推薦大家學習 VBA,由於它是入 門,學習,進階都很快速,很容易上手的,是解決實際工作的最佳工具(信不信由你!)。對於其它開發語 言,我認爲目前的開發語言越來越一致了,都是以對象爲核心,比如
VB.NET,VC++.NET等,所以學會一 種 VB.NET就可以解決其它開發問題,但普通用戶來講,是不需要學會和精通那些的,只要知道有它們的 存在,且找一本書學一下,如果真的有機會,有事情需要用到那些,再學習。因爲大家都很忙,所以建議 學習 VBA這種快速解決問題的工具,看我的內容,估計一個禮拜就學會了,再看看論壇上的貼子,我想 大家一個月就能成爲 VBA中級人員。程序開發,其實還需要一定天賦的,因爲核心的算法是要靠一定智 慧的,不同的人,搞出來的,雖然都解決問題,但速度差異很大等。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/risslin/archive/2009/12/31/5111401.aspx