VBA中的四類模塊:“標(biāo)準(zhǔn)模塊”、Microsoft Excel工作簿和工作表對象、窗體、類模塊。(VBE→插入菜單)
文檔模塊:Sheet1,Sheet2,Sheet3,ThisWorkbook;
窗體模塊:UserForm1,包含窗體有關(guān)的代碼;
標(biāo)準(zhǔn)模塊:模塊1,包含自定義過程和函數(shù)有關(guān)的代碼;
類模塊:類1,包含自定義類有關(guān)的代碼;
A Sub is a procedure that performs a specific task but does not return a specific value.
Sub是執(zhí)行特定任務(wù)但不返回特定值的過程。
Sub ProcedureName ([argument_list]) [statements]End Sub
If no access modifier is specified, a procedure is Public by default.
如果未指定訪問修飾符,則默認(rèn)情況下,過程是公共的。
demo code:
'合并單元格并保留全部內(nèi)容'先選定需要合并的區(qū)域;Sub MergerSelectedCells() Application.DisplayAlerts = False Dim allstr As String Dim Str As Object For Each Str In Selection If Str.Value <> '' Then allstr = allstr & ' ' & Str.Value allstr = Application.WorksheetFunction.Trim(allstr) End If Next Str With Selection .MergeCells = True .Value = allstr .WrapText = True .HorizontalAlignment = xlGeneral .VerticalAlignment = xlTop End With Application.DisplayAlerts = TrueEnd Sub
A Function is a procedure that is given data and returns a value, ideally without global or module-scope sideeffects.
函數(shù)是一個給定數(shù)據(jù)并返回值的過程,理想情況下沒有全局或模塊范圍的副作用。
Function ProcedureName ([argument_list]) [As ReturnType] [statements]End Function
實例代碼:
'自定義函數(shù)maxg(m, n),求最大公約數(shù)Function maxg(m, n) If m < n Then t = m m = n n = t End If r = m Mod n Do While r > 0 m = n n = r r = m Mod n Loop maxg = nEnd FunctionFunction mygcd(m As Integer, n As Integer) If n = 0 Then mygcd = m Else mygcd = mygcd(n, m Mod n) End IfEnd Function
VBA中,自定義類型相當(dāng)于C語言中的結(jié)構(gòu)體,枚舉類型也與C語言中的枚舉類型相似。自定義類型和枚舉類型放到模塊的子過程的前面即可。
'1自定義類型'1.1 自定義類型的聲明Public Type Car Name As String Price As Currency Length As Single ShouDongDang As Boolean ProductionDate As DateEnd Type'1.2 自定義類型的使用Sub Test1() Dim MyCar As Car, YourCar As Car With MyCar .Name = '桑塔納' .Price = 300000@ .Length = 4.2 .ShouDongDang = False .ProductionDate = #7/8/2015# End With With YourCar .Name = '大眾' .Price = 80000@ .Length = 4.5 .ShouDongDang = True .ProductionDate = #2/18/2015# End With MsgBox '兩輛車總價值:' & (MyCar.Price + YourCar.Price)End Sub'2 自定義枚舉類型的聲明和使用'2.1 自定義枚舉類型的聲明Public Enum JapaneseWeekDay 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日 日曜日End EnumPublic Enum Screen Width = 1366 Height = 768End Enum'2.2自定義枚舉類型的使用Sub Test1() Dim a As Long, b As Long a = JapaneseWeekDay.金曜日 b = JapaneseWeekDay.土曜日 MsgBox a + bEnd SubSub Test2() MsgBox Screen.Width * Screen.HeightEnd Sub
VBA雖是基于對象的語言,但也可以自定義類。
VBA中, 類模塊相當(dāng)于C語言中的類,類模板要單獨放到類模塊中(自定義類型和子過程放在模塊中),類模板的名稱就是類的名稱,可以做為新的類型進行聲明和定義。
Alt+F11→“插入”→“類模塊”→在“屬性”窗口中修改類的名稱為'clsADO'。
'1 創(chuàng)建私有變量Option Explicit'使用本類模塊,需添ADO的引用'Microsoft ActiveX Data Objects 2.8 Library'Private cnn As Connection '連接對象Private rs As Recordset '記錄集對象Private m_DBFullName As String 'Access數(shù)據(jù)庫名稱(包含路徑信息)Private m_CommandText As String 'SQL語句'2 創(chuàng)建Property Get過程來獲取對象的屬性值Property Get DBFullName() As String '返回數(shù)據(jù)庫名稱 DBFullName = m_DBFullNameEnd PropertyProperty Get CommandText() As String '返回SQL語句 CommandText = m_CommandTextEnd Property'3 創(chuàng)建Property Let過程改變對象屬性Property Let DBFullName(strDBFullName As String) '設(shè)置數(shù)據(jù)名稱 If LCase(Right(strDBFullName, 4)) <> '.mdb' And _ LCase(Right(strDBFullName, 6)) <> '.accdb' Then Exit Property End If m_DBFullName = strDBFullNameEnd PropertyProperty Let CommandText(strSQL As String) '設(shè)置SQL語句 m_CommandText = strSQLEnd Property'3 定義類的方法Private Sub ConnDB() '連接數(shù)據(jù)庫 If cnn.State = 0 And Len(m_DBFullName) > 0 Then cnn.Provider = 'Microsoft.Jet.OLEDB.4.0' cnn.Open m_DBFullName End IfEnd SubPublic Sub CloseDB() '關(guān)閉連接 cnn.CloseEnd SubPublic Function RunSQL() As Recordset '執(zhí)行SQL語句 If Len(m_CommandText) > 0 Then Call ConnDB '創(chuàng)建數(shù)據(jù)庫連接 If rs.State <> 0 Then rs.Close rs.Open Source:=m_CommandText, _ ActiveConnection:=cnn, _ CursorType:=adOpenStatic, _ LockType:=adLockReadOnly Set RunSQL = rs '返回記錄集 End IfEnd Function'2.4 定義類模塊的事件Private Sub Class_Initialize() '初始化類 Set cnn = New Connection Set rs = New RecordsetEnd SubPrivate Sub Class_Terminate() '終止類 If cnn.State = 1 Then cnn.Close End If Set cnn = Nothing Set rs = NothingEnd Sub'3 使用類模塊'3.1 用新定義的類聲明對象Dim tstADO As New clsADO'3.2 使用對象編寫過程Sub test() Dim rs As Recordset, fld As Field On Error Resume Next tstADO.DBFullName = ThisWorkbook.Path & '\Northwind.mdb' '設(shè)置屬性 tstADO.CommandText = 'select * from 客戶' '設(shè)置屬性 Set rs = tstADO.RunSQL '調(diào)用自定義對象的方法 With Worksheets(1) i = 1: j = 1 For Each fld In rs.Fields .Cells(i, j) = fld.Name j = j + 1 Next j = 1 i = i + 1 Do While Not rs.EOF For Each fld In rs.Fields .Cells(i, j) = fld.Value j = j + 1 Next j = 1 rs.MoveNext i = i + 1 Loop End WithEnd Sub
A Property is a procedure that encapsulates module data. A property can have up to 3 accessors: Get to return a value or object reference, Let to assign a value, and/or Set to assign an object reference.
屬性是封裝模塊數(shù)據(jù)的過程。一個屬性最多可以有3個訪問器:Get以返回值或?qū)ο笠茫琇et以指定值,和/或Set以指定對象引用。
Property Get|Let|Set PropertyName([argument_list]) [As ReturnType] [statements]End Property
Properties are usually used in class modules (although they are allowed in standard modules as well), exposing accessor to data that is otherwise inaccessible to the calling code. A property that only exposes a Get accessor is 'read-only'; a property that would only expose a Let and/or Set accessor is 'write-only'. Write-only properties are not considered a good programming practice - if the client code can write a value, it should be able to read it back.
屬性通常在類模塊中使用(盡管在標(biāo)準(zhǔn)模塊中也允許使用),對訪問者暴露調(diào)用代碼無法訪問的數(shù)據(jù)。僅公開Get訪問器的屬性為“只讀”;僅公開Let和/或Set訪問器的屬性為“只寫”。只寫屬性被認(rèn)為不是一種好的編程實踐——如果客戶機代碼可以寫一個值,它應(yīng)該能夠讀回它。
A Function or Property Get procedure can (and should!) return a value to its caller. This is done by assigning the identifier of the procedure:
函數(shù)或Property Get過程可以(而且應(yīng)該?。⒅捣祷亟o其調(diào)用者。這是通過給過程的標(biāo)識符賦值來完成的:
Property Get Foo() As Integer Foo = 42End Property
Any public Sub, Function, or Property inside a class module can be called by preceding the call with an object reference:
通過在調(diào)用之前使用對象引用,可以調(diào)用類模塊中的任何公共子、函數(shù)或?qū)傩裕?/p>
Object.Procedure
-End-