目錄:
十六、DIR 指定一個文件路徑,其文件路徑下有這個文件,返回文件名,沒有這個文件,返回空
數據類型的最大值:
1bytes(1字節)=8bit,8bit可存儲28個數字,負數占一半,正數和0占一半
例如:整型類型所占2個字節,2字節=16位,可存儲216個數據,負數占一半,正數和0占一半
在定義變量時,不知道定義的變量類型,此時可以設置成Variant(變體型)類型
1.可以使用字母、數字個一些標點符號,但是第一個字符必須為字母
2.不能使用空格和句點
3.不能含有特殊的聲明字符(#、¥、%、&、、!)
4.變量名不能超過254個字符
5.變量名不區分大小寫
空白符:空格符、制表符、換行符等統稱為空白符,主要用於規范程序格式
運算符的結合性:
對於算數運算符而言,計算的順序為從左至右
對於賦值運算符而言,計算的順序為從右至左
跳出FOR循環,用exit for(常於if搭配使用)
用於按指定的次數執行循環體
For each in Next循環:
針對一個集合或是數組中的每個元素循環執行操作
For each in next相當於python中的for I in range
他會遍歷對象中的每一個元素
如將其他工作表的名稱放入到 部門 表中
分支控制語句(IF語句、Select Case語句)
IF結構:
兩種語言不同的點在於Python將VBA中IF\ElseIF的Then換成了冒號,VBA中的ElseIF不能簡寫成Elif
Select Case語句
針對多重判定任務反復進行循環操作處理
While循環的兩種寫法:
DO…Until循環
Until語句又稱為“直到型”循環結構處理語句。也就是直到條件成立的時候才結束循環體。
工作表有四種:
'工作表的選擇
Sheet1.Select '選擇工作表1
Sheets(3).Select '選擇第三個工作表
Sheets("一月").Select '選擇名稱為一月的工作表
'插入工作表
Sheets.Add '在當前工作表前面插入新的工作表
Sheets.Add , after:=Sheet3 '在sheet3后面插入新的工作表
'在sheet3后面插入100個新的工作表
Dim i As Integer
For i = 1 To 100 Sheets.Add , after:=Sheet3 Next
'統計工作簿中工作表的數量
Sheet5.Range("a1") = Sheets.Count '在工作表的A1單元格中輸出工作簿中所有工作表的數量
Sheet5.Range("a1") = Sheet1.Name '在工作表的A1單元格中輸出I作表1的名稱
Sheet1.Name = "匯總" '將工作表1的名稱改為匯總
'使其總是在最后張工作表后面插入新表
Sheets.Add , after:=Sheets(Sheets.Count) '創建十二個月的工作表
Dim i As Integer
For i = 1 To 12 Sheets.Add , after:=Sheets(Sheets.Count) '這里的Sheets.Count表示插入前的工作表數
Sheets(Sheets.Count).Name = i & "月" '這里的Sheets.Count表示插入后的工作表數,與上句相差1
Next Excel.Application.DisplayAlerts = False '關閉Excel 的報錯機制
Sheet3.Delete '刪除工作表3
Excel.Application.DisplayAlerts = True '開啟Excel 的報錯機制
'插入100張工作表
Sheets.Add , Count:=100
'刪除100張工作表
Dim i As Integer Excel.Application.DisplayAlerts = False
For i = 1 To 100 Sheets(1).Delete '總是刪除左起第一 張工作表,這里也可以用step -1 倒序刪除
Next Excel.Application.DisplayAlerts = True Sheet1.Copy , after:=Sheets(2) '復制工作表,並且將其置於左起第二 張工作表之后
Sheet1.Copy , after:=Sheets(Sheets.Count) '復制工作表,並且始終將其置在最后端
操作工作簿:
Sub open_file() '關閉錯誤提示框
Application.DisplayAlerts = False
'關閉屏幕更新
Application.ScreenUpdating = False
'打開路徑文件,文件名需要填寫完整
Workbooks.Open Filename:=("E:\Excel_date\case.xlsx") '給活動工作簿的表1添加值
ActiveWorkbook.Sheets(1).Range("A1") = "到此一游o"
'保存
ActiveWorkbook.Save '關閉
ActiveWorkbook.Close Application.DisplayAlerts = True
End Sub
Sub create_file() '創建新的工作簿
Workbooks.Add ActiveWorkbook.Sheets(1).Range("A1") = "測試內容"
'文件另存為
ActiveWorkbook.SaveAs Filename:=("E:\Excel_date\caeate.xlsx") '關閉
ActiveWorkbook.Close End Sub
將工作表另存為工作簿:
代碼:
單元格是EXCEL中最小的對象
單元格對象Range:(跳轉到指定單元格搭配select使用)
Range: Sub try_case_2() '彈出A1單元格所在的當前區域的最后一個單元格的行號
MsgBox Range("A1").End(xlDown).Row '從a65536單元格向上移動到第一個有數據的單元格
MsgBox Range("A65536").End(xlUp).Row End Sub Range("A6").EntireRow.Select '選中A6所在單元格的整行
Range("A6").Resize(1, 3).Select '以A6單元格為參照,重新框選選區
Range("H7:L7").Copy , Range("N7") '將H7:L7復制到N7
'注意:如果是復制一整行的話,最好在相同列復制
Range("A7").EntireRow.Copy , Range("A10") '這樣就會報錯,因為列號不匹配,會導致粘貼區域范圍不夠
Range("A7").EntireRow.Copy , Range("B10") Sub 合並單元格() Dim rng As Range For Each rng In Range("H21:O21") '將H21與H22合並,直到021與022合並
rng.Resize(2, 1).Merge Next
End Sub
注意:如果活動單元格不是sheet1,那么以下代碼就會報錯
Sub case_1() Sheet1.Range("c2").Select End Sub
如下就不會報錯:
Sub case_1() Sheet1.Select Sheet1.Range("c2").Select End Sub
Cells指定單元格對象: (跳轉到指定單元格搭配select使用)
Selection:當前選區,表示當前選中的單元格區域
ActiveCell:活動單元格,有且僅有一個
UsedRange:已使用區域,表示使用過的所有區域,(對某個單元格進行格式設置,即使沒有輸入內容,也屬於已使用區域)
CurrentRegion:當前區域,表示此單元格四周相連的單元格區域
1.篩選的原理就是將不符合條件的數據隱藏起來(行高設為0)
Sub 篩選() Sheet8.Range("$A$9:$C$13").AutoFilter Field:=2, Criteria1:="凱迪拉克"
'Field:=2表示數據區域第幾列應用篩選 'Criteria1:="凱迪拉克"表示篩選條件
Sheet8.Range("$A$9:$C$13").AutoFilter '關閉篩選
End Sub
2.With與End With:
作用就是節省代碼,使代碼簡潔,書寫方便
Sub case_1() With Sheet1 .Range("A1") = 1 .Range("A2") = 2 .Range("A3") = 3 Sheet2.Range("A1") = 1
End Sub
只有前面加點的才會應用with
工作表事件:
例如:用事件在工作表中修改顏色,即單元格選區發生改變,所在選區的那一行設置為黃色底紋,其余行的底紋顏色為透明
Sub change_color() Cells.Interior.Pattern = xlNone Selection.EntireRow.Interior.Color = 65535
End Sub
Change事件的注意:
點擊表格自動更新事件:
工作簿事件:
舉例:在保存工作簿前的時候備份數據到指定文件下且文件名字為當前時間
Application.WorksheetFunction.函數名 ‘工作表函數調用方式 On Error Resume Next ‘程序崩潰請繼續執行代碼
舉例:考生成績統計查詢系統
題目示例
Sub try_1() Dim i, k, n As Integer
For i = 2 To Sheets.Count k = k + Application.WorksheetFunction.CountA(Sheets(i).Columns("A")) - 1 v = v + Application.WorksheetFunction.CountIf(Sheets(i).Columns("F"), "男") n = n + Application.WorksheetFunction.CountIf(Sheets(i).Columns("F"), "女") Next Sheet1.Range("D26") = k Sheet1.Range("D27") = v Sheet1.Range("D28") = n End Sub
Sub try_2() On Error Resume Next '如果代碼崩潰,繼續執行代碼
Dim i As Integer Sheet1.Range("D14").ClearContents For i = 2 To Sheets.Count Sheet1.Range("D14") = Application.WorksheetFunction.VLookup(Sheet1.Range("D9"), Sheets(i).Columns("A:H"), 5, 0) Sheet1.Range("D16") = Application.WorksheetFunction.VLookup(Sheet1.Range("D9"), Sheets(i).Columns("A:H"), 6, 0) Sheet1.Range("D18") = Application.WorksheetFunction.VLookup(Sheet1.Range("D9"), Sheets(i).Columns("A:H"), 3, 0) Sheet1.Range("D20") = Application.WorksheetFunction.VLookup(Sheet1.Range("D9"), Sheets(i).Columns("A:H"), 8, 0) Sheet1.Range("D22") = Sheets(i).Name If Sheet1.Range("D14") <> "" Then
Exit For '結束循環
End If
Next
End Sub
1.isnumeric(參數)
判斷參數是不是數字
2.參數=val(參數)
將參數轉為數值型
l = InputBox("請輸入你要按哪列分") If IsNumeric(l) = False Or l < 1 Then
Exit Sub
End If l = Val(l)
VBA函數調用方式:
完整寫法:
VBA.Strings.Left (參數)
第二個單詞表示VBA函數類型,使用函數要准確寫出其所屬類型
3.instr
用來確定參數2,在參數1中處於第幾位的,如果參數2沒在參數1中則返回0(find函數查找的時候,如果沒有會程序崩潰)
舉例:截取@前面的字符:
Sub try() Sheet1.Range("B2") = VBA.Strings.Left(Sheet1.Range("A2"), VBA.Strings.InStr(Sheet1.Range("A2"), "@") - 1) End Sub
結果:
4.split
Split(參數1,參數2)表示在參數1中用參數2進行分割,得到的結果為一個數組
數組的第一個值為0,即用python中索引的方式去取數,索引從0開始
Sub try() Dim i As Integer
For i = 2 To Range("A65535").End(xlUp).Row If InStr(Range("A" & i), "-") <> 0 Then Range("B" & i) = Split(Range("A" & i), "-")(2) & "年 第" & Split(Range("A" & i), "-")(3) & "周"
End If
Next
End Sub
結果:
在工作中使用自定義的函數
可以將VBA中的函數作為一個新的函數,這樣這個函數不僅可以在SUB過程中被調用,也可以在工作表中被調用
例如:將VBA函數中的Split函數封裝為 截取字符 函數,這樣工作表中和sub過程中都可以調用
結果:
創建帶參數的SUB:
根據表格內容創建新的工作表,工作表名為表格內容
按值傳遞與按引用傳遞:
想讓代碼在任何工作簿中都可以使用,需要做三件事:
1.將代碼放入代碼庫中
點擊已經寫好代碼的工作簿的另存為---瀏覽---保存類型選擇xlam或者xla
Excel會自動跳到保存加載宏的文件夾,起好名字點擊保存
2.告訴Excel每次打開工作簿都加載此代碼
3.將代碼設置一個按鈕(添加到快速訪問工具欄)
先關閉打開的工作簿,打開一個新的工作簿---文件---選項
但是需要注意的是,加載宏的代碼必須具有可移植性,相當於軟代碼的感覺,要保證這塊代碼在任何工作簿中都可以完整且正確的執行
加載宏的代碼一定不能出現Thisworkbook這種類型的自動,因為在加載宏的文件里,Thisworkbook代表那個原本的xla文件,可以使用變量,將變量定義為當前的活動工作簿即可
在刪除代碼庫的時候,需要先將第二步中的加載項取消勾選,然后再找到路徑去刪除(可以另存為選擇xlam類型自動跳轉到文件夾的時候刪除,即第一步的窗口中刪除)
十六、DIR 指定一個文件路徑,其文件路徑下有這個文件,返回文件名,沒有這個文件,返回空
DIR里支持通配符操作,可以幫助我們回避掉文件同名,格式不同的情況
Dir多條符合值的辨析:
當有多個文件符合Dir的結果時,第一個Dir需要加條件,並返在內存中存儲一個符合結果的序列,其后的Dir如果不加文件路徑,返回的是結果序列的第二個值,以此類推。
如果只有兩個符合結果的值,第一個Dir返回的是序列一的值,第二個返回序列二的值,第三個返回空,第四個會報錯
例如:(文件路徑下蘇州只有兩個 蘇州.xls和蘇州.xlsx)
於是,我想查找文件路徑下所有的文件可以這樣寫:
Dir的殼子:
打開路徑文件里的所有數據,然后執行一些操作,然后關閉
案例:將路徑文件下工作簿里的表復制到指定工作簿中
Sub try() Dim i, v As Integer
Dim str As String
Dim sht As Worksheet str = Dir("E:\Excel_date\*.*") For i = 1 To 100
Set wb = Workbooks.Open("E:\Excel_date\" & str) For v = 1 To wb.Sheets.Count wb.Sheets(v).Copy after:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count).Name = Split(wb.Name, ".")(0) & wb.Sheets(v).Name Next wb.Close str = Dir
If str = "" Then
Exit For
End If
Next
End Sub
VBA中的FIND功能很強大,完全可以替換Vlookup函數,甚至突破Vlookup函數的局限性,比如,姓名不在數據第一列、查找數據橫向的任何一個單元格(改變offset參數)、對單元格進行清除 格式設置 等等一系列操作
舉例:
一維數組:
二維數組:
在VBA中最經常涉及的就是讀寫工作表中的單元格,如果讀寫操作次數較多,或者涉及到的單元格數量較多,往往會導致程序運行效率較低。這時經常用到的解決方法就是使用數組保存數據,在內存中進行數據處理和加工,最后一次行更新工作表,這樣的操作方式往往會極大提升程序的運行效率。
對比:
在for循環中盡量不用range,而是用數組替代,當代碼量特別大的時候它們的區別就會特別明顯
數組應用例子:
數組可以幫我們虛擬出來一個內存空間,臨時存放一些中間用到的數據(輔助列)
數組可以直接用在函數里
Dim 與 ReDim:
Dim里面的東西必須用常量,Dim arr(1 to i)就會報錯
上述圖片中的數組應用例子,只能有4行,如果A列為N個產品呢?此時我們就需要將數組中的元素個數設置為1 to n
在開發工具的設計模式下,可點擊右鍵進行屬性設置
1.CommandButton控件(按鈕)
常用屬性:
Enabled可用性
Caption標題
Visible可見性
常用事件:Click事件(點擊事件)
2.Label控件(標簽)
常用屬性:
Enabled可用性
Caption標題
Visible可見性
一般沒有應用的事件,就一個文本框而已
3. OptionButton控件(選項按鈕)
常見屬性:
Caption 標題
Enabled 可用性
GroupName 組名
Value 返回值
Visible 可見性
常見事件: Click事件(點擊事件)
4. SpinButton控件(微調按鈕)
可以根據長寬比調整是上下布局還是左右布局
常見屬性:
Enabled可用性
Value 返回值 可返回按鈕改變之后的數值大小
Visible可見性
Min 最小值
Max 最大值
常用事件:
Change事件
5.chexbox按鈕(復選框)
一組之中各個選項不會互斥,即都可以選擇
但是可以用事件,也可以將chekbox做成互斥的模樣,即click事件,然后另外一個的值為False
6.Textbox(文本框控件)
常見屬性:
Enabled 可用性
Value 返回值
Visible 可見性
PasswordChar 密碼字符
即保護用戶輸入信息掩碼
TabIndex 按下Tab鍵時的切換順序,多個控件之間用Tab鍵切換,可在屬性設置
注意值為0開始
舉例事件:輸入賬號密碼的文本框事件舉例
7. ComboBox復合框控件(下拉框)
常用屬性:
Enable Value Visible
List 數據源列表
常用方法:
AddItem 增加一個下拉項目
RemoveItem 移除一個項目
Clear 清除
舉例:使用的時候可以結合各種事件來調用相應的sub
'增加下拉框的選項
Sub test1() UserForm1.ComboBox1.AddItem "蘇州"
End Sub
'把單元格一列數據設置為下拉的數據源
Sub test2() For i = 2 To 6 UserForm1.ComboBox1.AddItem Sheet1.Range("a" & i) Next
End Sub
'刪除掉下拉框里的一項
Sub test3() Call test2 UserForm1.ComboBox1.RemoveItem (1) '刪除第二項
End Sub
'清空下拉框數據源
Sub test4() Call test2 UserForm1.ComboBox1.Clear End Sub
'計算下拉框里有多少個選項
Sub test5() Call test2 MsgBox UserForm1.ComboBox1.ListCount End Sub
'把下拉框數據源里某個值輸出到單元格
Sub test6() Call test2 Range("c2") = UserForm1.ComboBox1.List(1) End Sub
'把下拉框里所有的選項輸出到單元格區域
Sub test7() Call test2 Range("d1:d5") = UserForm1.ComboBox1.List End Sub
8.listbox(列表框)
舉例:使用的時候可以結合各種事件來調用相應的sub
'增加列表框的選項
Sub test1() UserForm1.ListBox1.AddItem "蘇州"
End Sub
'把單元格一列數據設置為列表框的數據源
Sub test2() For i = 2 To 5 UserForm1.ListBox1.AddItem Sheet1.Range("a" & i) Next
End Sub
'刪除掉列表框里的一項
Sub test3() Call test2 UserForm1.ListBox1.RemoveItem (1) '刪除第二項
End Sub
'清空列表框數據源
Sub test4() Call test2 UserForm1.ListBox1.Clear End Sub
'計算列表里有多少個選項
Sub test5() Call test2 MsgBox UserForm1.ListBox1.ListCount End Sub
'把組合框數據源里某個值輸出到單元格
Sub test6() Call test2 Range("c2") = UserForm1.ListBox1.List(1) End Sub
'把下拉框里所有的選項輸出到單元格區域
Sub test7() Call test2 Range("d1:d4") = UserForm1.ListBox1.List End Sub
'把一個區域的一列數據設置為列表框的數據源 Sub test8() UserForm1.ListBox1.List =Range("d1:d4").value End Sub
二十、窗體
窗體對應屬性:
Enabled 可用性
Caption 標題
Visible 可見性
ShowModal 顯示模式
True表示獨占,False表示不獨占,設置獨占之后此窗口以外的對象則不能被點擊,當有多個窗體的獨占模式有錯誤時,會報以下錯誤:
窗體常用方法:
Show 顯示
Hide 隱藏
窗體常用事件:
UserForm_Activate 激活
UserForm_QueryClose 退出
在窗體背后寫代碼時,直接雙擊就可以進入事件代碼編輯區域,雙擊窗體上的按鈕可以直接跳轉到該按鈕對應的事件代碼編輯區域
窗體常用方法可與事件搭配使用:
例如當工作簿一打開,就顯示此窗口
Msgbox有四個參數:(這里只需掌握三個即可)
第一個參數表示文本框內容
第二個參數表示按鈕顯示類型
第三個參數表示彈出框標題
例如:
效果圖:
樣式參數
對於第二個參數來說:需要多種樣式組合就用加號連接
Msgbox的返回值:
返回值的對應結果:
返回1說明點擊了確定,以此類推
Inputbox有兩個,一個是函數,一個是方法
Inputbox函數
Inputbox方法
1.GetOpenFilename
返回所選文件的完整路徑
那么根據前面Dir殼子的思路,可以利用GetOpenFilename也做一個打開文件,關閉文件的殼子,但是不同的是文件是用戶自己選de
Sub try() Dim arr() Dim i As Integer
Dim wb As Workbook arr = Application.GetOpenFilename("Excel文件,*.xls*", 1, , , True) On Error Resume Next '防止用戶沒有選擇文件直接點擊取消
If arr(1) <> "False" Then
For i = LBound(arr) To UBound(arr) Set wb = Workbooks.Open(arr(i)) '這里寫需要進行的操作
wb.Close Next
End If
End Sub
2.Application.Dialogs
用於操作Excel中所有的對話框
在使用的時候需要注意有的操作要先選中對象,才能再執行對話框,比如指定宏的對話框,需要先選中指定宏的控件,在執行sub過程即可
1、在VBE界面中工具—引用—勾選Microsoft ActiveX Data Object x.x Library(x.x表示版本號)
2、連接代碼
Sub test() Dim conn As New ADODB.Connection Dim sql As String conn.Open "Provider = Microsoft.ACE.OLEDB.12.0;Data Source=E:\Excel_date\Adata.accdb" sql = "" '雙引號里是一組sql代碼語句,要用雙引號把整個代碼括起來 "
Columns("A:Z").ClearComments Range("A2").CopyFromRecordset conn.Execute(sql) '如果sql代碼沒有返回值那么就只保留coon.Execute(sql)的代碼
conn.Close End Sub
以下給出各種數據庫連接的語句(即上文加粗部分)

Excel文件 conn.Open "Provider = Microsoft.ACE.OLEDB.12.0;Data Source=D:\data\Edata.xlsx;extended properties=""excel 12.0;HDR=YES""" conn.Close ACCESS文件 conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\data\Adata.accdb" Mysql數據庫 conn.Open "Provider=SQLOLEDB;DataSource=" & Path & ";Initial Catolog=" & strDataName MSSQL數據庫 conn.Open "Provider=MSDASQL;Driver={SQL Server};Server=" & Path & ";Database=" & strDataName Oracle數據庫 conn.Open "Provider=madaora;Data Source=MyOracleDB; User Id=UserID; Password=Password"
插入圖片案例:
圖表對象:
在不知道如何操作的時候一定要想到錄制宏
Name 案例:
將圖片文件的名字改為姓名加身份證號:
當做很復雜的程序(點擊切換題目點擊計算分數)等需要編程的東西我們使用Active X 控件,對於調查文件等只需要勾選的情況,就可以使用表單控件,又小又靈活
表單控件的所有控件都要設置單元格鏈接地址來獲取返回值
選中控件---右鍵 設置空間格式---控制
Active X控件有分組屬性,在表單控件中只能使用分組框來框選表單控件來達到分組的目的
那么如何隱藏分組框還讓他發揮作用的,這里就涉及到觸類旁通的思想,在VBA的學習過程中要不斷地去嘗試觸類旁通的思想,推測思想以及錄制宏的方式去解決
相當於Mysql中like,只不過稍微有點區別
* 任意字符
# 任意一位數字
? 一位字符
! 邏輯非
[A-Z] 大寫字母
[A-Z a-z] 字母
[0-9] 數字
[!A-Z] 非大寫字母
[!0-9] 非數字
這里的共有與私有相當於python中的局部變量和全局變量
對於sub而言,在一個模塊中可以相互調用,在另外一個模塊中也可以相互調用(sub 默認為 public 公有的)
對於private sub而言,其在一個模塊中可以調用private sub,另外的模塊就不能調用(private 私有的)
對於變量而言:
在實際開發過程中,盡量少用public 定義全局變量,可以使用定義一個函數作為橋梁進行傳遞:
靜態變量:
普通變量用Dim聲明,過程結束后內存就會釋放其變量的存儲空間,多次執行的話,每次都要開辟新的空間
靜態變量用Static聲明,過程結束內存也不會釋放其變量的存儲空間,多次執行的話,就會在原基礎上繼續進行運算
用於保存以類或對象方式編寫的代碼。
通過創建類模塊,可以創建用戶自定義類和對象。
使用已建立的類模塊,不需要編碼者了解具體是如何工作的,因此可以實現共享代碼
bilibili視頻講解地址:https://www.bilibili.com/video/bv14i4y1g7dH
類模塊變量定義方法: Dim 變量名 as new 類模塊名
定義方式:
方法1
工具-引用-瀏覽-找到scrrun.dll-確定
Dim dic As New Dictionary
方法2 (推薦)
Dim dic
Set dic = CreateObject("Scripting.Dictionary")
可以把字典理解成只有兩列數據的數組
字典有兩個優點:
一是查詢非常快根據鍵值配對value
二是可以自動去重
可以將需要賦值給字典的單元格區域設置成數組模式,既快速又簡潔
在單元格給數組區域賦值的時候隨便幾行幾列都沒問題,在給字典賦值的時候只能是一列鍵值,一列value而已,將數組的某一列區域賦值給字典的keys,可以達到去重的效果