學習目的是建立簡易的管理系統
當前學習路線:excel的宏的簡單了解→access數據庫的了解→兩者的結合
excel的宏的簡單了解:
關於宏的使用,大部分文章都提到說Vba很難寫,但是可以通過一段現成的代碼,修改關鍵部分來為自己所用,現成代碼的獲得方式就是錄制宏,在其自動生成的代碼上添加循環等修改,達到自己想要的效果。
關於宏的錄制與代碼的修改運行如下:
1.首先要在excel中找到開發工具(WPS也有,但當前使用的是office的)
在excel的“文件”→“選項”→“自定義功能區”的“主選項卡”部分,把“開發工具”一項勾選上,點擊右下角的確定,這樣excel的操作欄就會顯示開發工具選項卡了
接下來舉例實現功能:錄制宏操作,對A1:A10單元格添加批注,批注內容是“你好”
首先,在開發工具中點擊錄制宏
接下來做正常的批注操作,批注好之后點擊停止錄制
然后點擊Visual Basic 會彈窗出來如圖所示的界面
首先要在左側的工程界面找到我們需要操作的對象,是example.xlsx的模塊,打開后才會顯示右側的代碼部分,宏2是錄制下來的“本體”生成的代碼,把它修改為宏1的形式就完成了從A列的1到10都批注“你好”的功能
這里有一個小知識點:
Cstr()函數可以將數字轉換成字符,如 2 → “2”
Val()函數可以將字符(數字字符)轉換成數字, 如 “2” → 2
代碼寫好之后,運行即可(注意!!!如果錄制的宏是對A1批注,代碼中的循環操作又包括了對A1的操作的話,會報錯的,需要先把原A1的批注刪除掉,即不能對已經存在的操作重復操作)
access數據庫的建立
首先可以在目標文件夾新建一個.accdb格式的數據庫文檔
數據庫的數據來源可以手動添加,也可以根據excel導入(推薦),即可建立一個數據庫可供使用
如下圖所示
兩者的結合
首先明確一下目標:是為了通過對宏的編寫和調用,實現excel和access連接,通過一些sql語句,將目標數據從數據庫中提取到excel中
在Visual Basic新建一個新的模塊,即新建了一個宏,然后要現嘗試着把excel和access連接起來,在Visual Basic for Applications的窗口中找到 “工具” → “引用”
如圖所示
在可使用的引用中找到“Microsoft ActiveX Data Objects”(簡稱ADO)可能有很多版本,選擇最高的版本即可,勾選然后點擊確定
接下來就是代碼的實現了,代碼部分如下
1 Sub ConnectDBtest() 2 '第一步,告訴電腦需要使用ADO工具,在工具→引用中找到ADO確認引用 3 4 '第二步,創建連接對象 5 '2-1,給連接對象取名字 6 Dim con As ADODB.Connection '聲明對象變量 7 '2-2,創建對象變量並賦值 8 Set con = New ADODB.Connection '創建對象變量 9 10 '第三步,建立數據庫的連接 11 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & ThisWorkbook.Path & "\example.accdb" 12 13 14 MsgBox "連接成功" 15 16 17 End Sub
第一行是給這部分代碼命名
第六行是聲明對象變量的類型 Dim ...As ...
第八行是正式創建這個變量
第十一行是建立對象與數據庫的連接,其中要注意兩點,第一是數據驅動引擎即provider的版本,第二是所連接的數據庫的位置
1.版本: 可以根據數據庫文件的后綴名進行簡單的判斷,03版的后綴名是.mdb,07版以上用的是accdb,對應使用的provider就是12.0的
2.數據庫的位置:本地的數據庫可以照上方第十一行的寫法,ThisWorkbook.Path,如果是其他位置的數據庫,可以按照如下所示的方法,把數據庫位置設置為變量
1 '第三步,建立數據庫的連接 2 Dim mydblocation As String 3 mydblocation = "數據庫位置" 4 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "\example.accdb" 5 MsgBox "連接成功"
以上是確保了數據庫與excel的連接,連接成功后會出現彈窗提示 “連接成功”【判斷連接成功還有一個方法是通過查看本地是否出現了example.laccdb這樣的一個文件,出現則表明數據庫已經被打開了】
接下來要實現把數據庫的內容通過SQL語言來帥選出來,放入excel指定的位置,代碼如下
1 Sub ConnectDBtest() 2 '第一步,告訴電腦需要使用ADO工具,在工具→引用中找到ADO確認引用 3 4 '第二部,創建連接對象 5 '2-1,給連接對象取名字 6 Dim con As ADODB.Connection '聲明對象變量 7 '2-2,創建對象變量並賦值 8 Set con = New ADODB.Connection '創建對象變量 9 10 '第三步,建立數據庫的連接 11 Dim mydblocation As String 12 mydblocation = "數據庫遠程的位置" 13 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "\example.accdb" 14 MsgBox "連接成功" 15 16 '第四步,查詢表中滿足條件的字段,這里是列出工作表 “Summary of frame-parallel test” decoder一列下為google的行的內容 17 Sql = "select * from [Summary of frame-parallel test] where [decoder] = 'google'" 18 Dim rs As New ADODB.Recordset '創建記錄集對象 19 20 '第五步,執行sql查詢語句 21 Set rs = con.Execute(Sql) 22 23 '獲取字段名即col的title 24 Dim i As Integer 25 For i = 0 To rs.Fields.Count - 1 26 Cells(1, i + 1) = rs.Fields(i).Name 27 Next 28 29 30 Sheets("sheet1").Range("A2").CopyFromRecordset rs '將記錄集rs中的數據返回到工作表中 31 32 33 '清空緩存區 34 rs.Close: Set rs = Nothing 35 con.Close: Set con = Nothing 36 37 38 End Sub
第十七行是定義了數據庫查詢的內容
第十八行和21行是定義了裝載查詢后結果的容器為rs,即記錄集,21行是執行,執行后結果都放在rs中
第24~27行是遍歷獲取數據庫的列的title並寫進excel的第一行
第30行是復制了數據集rs中的內容到excel工作薄中,名為“sheet1”的工作表,且從A2開始寫
第34~35行是清空rs記錄集和對象的緩存
其中第21行生成記錄集的方法:
1.第21行的方法可以稱之為“使用connection對象的Execute方法產生記錄集”,這種方法產生的記錄集特點:一.rs是只讀的,不能修改記錄,通常用於做一些不需要返回的操作。二.不能獲取記錄的條數
2.還有一種方法較叫“使用recordset對象的open方法”產生記錄集,這種方法獲得的記錄集是可讀可寫的,可以修改記錄,語句是
$ rs.Open sql,con,adOpenKeyset,adLockOptimistic
其中Open后面跟的四個參數,第一個sql表示所執行的命令字符串(因為此例中第17行已經定義了查詢語句為sql),第二個參數寫的是當前連接的哪一個數據庫,這里是連接了con數據庫,第三個參數選游標的運動方式,選動態的(其實這里選固定的adOpenKeyset即可包括后面第四個參數也是一樣)
這種方式可以獲取到符合條件的記錄的條數,便於做判斷,使表格使用更方便(如果無記錄,使用if語句判斷一下,彈窗提示即可,無需再生成一個空表格)
如下代碼所示,實現的是如果沒有查找到記錄,會彈窗提示無記錄而不是報錯
1 Sub ConnectDBtest() 2 '第一步,告訴電腦需要使用ADO工具,在工具→引用中找到ADO確認引用 3 4 '第二部,創建連接對象 5 '2-1,給連接對象取名字 6 Dim con As ADODB.Connection '聲明對象變量 7 '2-2,創建對象變量並賦值 8 Set con = New ADODB.Connection '創建對象變量 9 10 '第三步,建立數據庫的連接 11 Dim mydblocation As String 12 mydblocation = "數據庫位置" 13 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "\example.accdb" 14 MsgBox "連接成功" 15 16 '第四步,查詢表中滿足條件的字段 17 Sql = "select * from [Summary of frame-parallel test] where [decoder] = 'ci'" 18 19 Dim rs As New ADODB.Recordset '創建記錄集對象方式1 20 21 '第五步,執行sql查詢語句 22 rs.Open Sql, con, adOpenKeyset, adLockOptimistic 23 24 If rs.RecordCount <= 0 Then '表示沒有滿足條件的記錄 25 MsgBox "沒有滿足條件的記錄" 26 Else 27 '獲取字段名即col的title 28 Dim i As Integer 29 For i = 0 To rs.Fields.Count - 1 30 Cells(1, i + 1) = rs.Fields(i).Name 31 Next 32 33 34 Sheets("sheet1").Range("A2").CopyFromRecordset rs '將記錄集rs中的數據返回到工作表中 35 End If 36 37 '清空緩存區 38 rs.Close: Set rs = Nothing 39 con.Close: Set con = Nothing 40 41 42 End Sub
如果用connection對象的Execute方法產生記錄集,也可以實現判空的功能,代碼如下
1 Sub ConnectDBtest() 2 '第一步,告訴電腦需要使用ADO工具,在工具→引用中找到ADO確認引用 3 4 '第二部,創建連接對象 5 '2-1,給連接對象取名字 6 Dim con As ADODB.Connection '聲明對象變量 7 '2-2,創建對象變量並賦值 8 Set con = New ADODB.Connection '創建對象變量 9 10 '第三步,建立數據庫的連接 11 Dim mydblocation As String 12 mydblocation = "數據庫位置" 13 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "\example.accdb" 14 MsgBox "連接成功" 15 16 '第四步,查詢表中滿足條件的字段 17 Sql = "select * from [Summary of frame-parallel test] where [decoder] = 'ci'" 18 19 Dim rs As New ADODB.Recordset '創建記錄集對象方式1 20 Set rs = con.Execute(Sql) 21 22 'EOF表示記錄的結尾,BOF表示記錄的開頭 23 If rs.EOF And rs.BOF Then '指針既指向開頭又指向末尾,說明沒有記錄 24 25 '第五步,執行sql查詢語句 26 'rs.Open Sql, con, adOpenKeyset, adLockOptimistic 27 'If rs.RecordCount <= 0 Then '表示沒有滿足條件的記錄 28 MsgBox "沒有滿足條件的記錄" 29 Else 30 '獲取字段名即col的title 31 Dim i As Integer 32 For i = 0 To rs.Fields.Count - 1 33 Cells(1, i + 1) = rs.Fields(i).Name 34 Next 35 36 37 Sheets("sheet1").Range("A2").CopyFromRecordset rs '將記錄集rs中的數據返回到工作表中 38 End If 39 40 '清空緩存區 41 rs.Close: Set rs = Nothing 42 con.Close: Set con = Nothing 43 44 45 End Sub
窗體的設置
excel要結合窗體才能實現更便捷的功能,設置方法如下:
首先在excel的Visual Basic中找到對應工程,點擊菜單欄中的插入→用戶窗體
接下來會出現如圖所示的界面
窗體調出來之后,是需要有個模塊來專門編輯窗體信息的,在此再點擊插入→模塊,創建一個新的模塊
1 '定義一個函數名為OpenMenuWindow來打來窗體 2 Sub OpenMenuWindow() 3 4 '窗體名稱.show可以調出目標窗體 5 UserForm1.Show 6 7 End Sub
運行這個函數就可以打開窗體了
窗體的外形和內容設計的方法是:在窗體的編輯頁面下,右鍵點擊窗體,再點擊查看代碼會出現如圖所示的界面
意思是當前的窗體UserForm是單擊事件,我們需要把它改掉,進行初始化的設置
可以先點進去UserForm1的界面,在工具箱的控件中選擇“框架”,畫出一個框架如圖所示
然后點擊“列表框”,在框架中畫出一個列表框
在UserForm1的空白處點擊一下,可以預覽到大致的效果如圖
我們要對這個框架和列表框的名稱進行修改,便於后續的調用操作,於是可以先選中列表框,在左側的屬性欄中,修改“名稱”為“Listphone”,再選中框架,修改名稱為“selectphone”,再把“caption”修改為“選擇手機型號”,這樣完成的效果為
右鍵點擊這個userform1,查看代碼,可以把里面的東西都清除干凈,然后,選擇這個userform1的類型為initialize,補充函數如下
1 Option Explicit 2 Dim con As ADODB.Connection 3 Dim rs As Recordset 4 5 '當窗體加載時顯示Android Phone這個列表框的內容 6 Private Sub UserForm_initialize() 7 8 Set con = New ADODB.Connection 9 Set rs = New ADODB.Recordset 10 '建立數據庫的連接 11 Dim mydblocation As String 12 mydblocation = "數據庫地址" 13 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "\example.accdb" 14 MsgBox "連接成功" 15 16 '提取不重復的手機類型 17 Dim sql1 As String '定義命令字符串變量 18 sql1 = "select distinct [Android Phone] from [Summary of frame-parallel test]" 19 rs.Open sql1, con, adOpenKeyset, adLockOptimistic 20 21 Dim i As Integer 22 With Listphone 23 .Clear 24 For i = 1 To rs.RecordCount 25 .AddItem rs("Android Phone") 26 rs.MoveNext 27 28 Next i 29 30 End With 31 End Sub
函數說明:
2,3行分別是聲明連接對象變量、聲明記錄集對象變量
第6行往下就是這函數的正式內容了
8,9行分別是創建連接對象變量,創建記錄集對象變量
11~14行是建立數據庫的連接
17~19行是用open方法去提取不重復的手機類型,把結果放入記錄集rs中
22是用with + 模塊名稱,表示操作對象(23行是清除此次之前的列表框中的記錄)
24行是表示開始遍歷記錄集中數據
25行說明了要取的rs中的數據
26行是將記錄集中的指針指向下一條記錄
28行是指針+1
30行,31行是結束with部分和結束函數部分
樣例分析
此樣例是實現了:對任意access數據庫的數據表,任選三個字段名為條件進行篩選查詢(目前存在的缺陷是數據中如果某字段名的列單元格為空,那么選這個字段為條件就會報錯“類型不匹配”)