一、代码优化的一些方法
尽量减少在循环中遍历调用对象,公式计算
(操作VBA代码若出现屏幕闪屏,会拖慢运行速度),可以禁止屏幕闪屏。多用在操作工作表/薄,单元格的时候。
Application.ScreenUpdating = False
需声明变量类型,减少工作表函数的使用。(多写循环代替工作表函数)
减少VBA函数的使用,如int10000/3) 可以用10000 3 替代
单元格填充数据前先清空单元格数据
批量操作及减少循环次数
巧妙填充公式,如单元格的filldown方法向下复制,避开循环
cell2,a) = ” = b2*c2″
[a2:a100].FillDown
二、关于其他操作
1、字体及边框设置
Public Sub RngFont) With Range"d3").Font .Name = "华文彩云" .FontStyle = "Bold" .Size = 28 .ColorIndex = 3 .Underline = 5 End With With Range"d3").Interior .Pattern = xlPatternCrissCross '设置内部图案为十字图案 .PatternColorIndex = 6 End With End Sub
2、单元格区域设置样式,borders方法,BorderAround 用于区域最外边框设置
Sub AddVBorders) Dim rng As Range Set rng = Range"a5:c9") With rng.Borders .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = 5 End With rng.BorderAround xlContinuous, xlMedium, 5 Set rng = Nothing End Sub
BorderAround 后参数:
区域中多格式:
Sub bordersDemo) Dim rng As Range Set rng = Range"e5:g9") With rng.BordersxlInsideHorizontal) .LineStyle = xlDot .Weight = xlThin .ColorIndex = 5 End With With rng.BordersxlInsideVertical) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = 5 End With rng.BorderAround xlContinuous, xlMedium, 5 Set rng = Nothing End Sub
3、行高、列宽设置 (磅或厘米)
Sub RngToPoints) With Range"i14") .RowHeight = Application.CentimetersToPoints1.2) .ColumnWidth = Application.CentimetersToPoints0.8) End With With Range"j15") .RowHeight = Application.InchesToPoints0.5) .ColumnWidth = Application.InchesToPoints0.2) End With End Sub
样式如下:
4、单元格数据有效性设置 Validation对象add方法
Sub Validation) '建立数据有效性 With Range"a1:a3").Validation .Delete .Add Type:=xlValidateList, _ Operator:=xlBetween, _ Formula1:="1,2,3,4,5,6,7" 'formula1,formula2可设置有效性公式 End With '判断数据有效性 On Error GoTo Line If Range"a1").Validation.Type >= 0 Then MsgBox "have validation" Exit Sub End If Line: MsgBox "none" End Sub
建立动态数据有效性:
Private Sub worksheet_SelectionchangeByVal target As Range) If target.Column = 1 And target.Count = 1 And target.Row > 1 Then With target.Validation .Delete .Add Type:=xlValidateList, _ Operator:=xlBetween, _ Formula1:="主机,显示器" End With End If If target.Column = 2 Then Application.SendKeys "%{down}" ' 点击单元格自动下拉展示所有选项 End If End Sub Private Sub worksheet_changeByVal target As Range) If target.Column = 1 And target.Row > 1 And target.Count = 1 Then With target.Offset0, 1).Validation .Delete Select Case target Case "主机" .Add Type:=xlValidateList, _ AlertStyle:=xlValidAlertStop, _ Operator:=xlBetween, _ Formula1:="z286,z386,z486,z586" Case "显示器" .Add Type:=xlValidateList, _ AlertStyle:=xlValidAlertStop, _ Operator:=xlBetween, _ Formula1:="三星1,飞利浦1,三星2,飞利浦2" End Select End With End If End Sub
效果:
5、检测选择区域是否含有公式(Hasformula函数),并输出公式位置
Private Sub CommandButton1_Click) Select Case Selection.HasFormula Case True MsgBox "公式单元格" Case False MsgBox "非公式单元格" Case Else MsgBox "公式位置" & Selection.SpecialCellsxlCellTypeFormulas, 23).Address0, 0) End Select End Sub
若需要返回公式引用的单元格区域则使用公式单元格Precedents属性,exp: range”c1″).Precedents.address0,0)
6、判断是否为空
1)逻辑值判断 – 空时返回True
range”a1″)=””
lenrange”a1″)) = 0
VBA.IsEmptyrange”a1″))
2)值判断
VBA.TypeNamerange”a1″).Value) 值返回为Empty时为空
7、判断是否为数字、文本、错误值、数组、日期
1)逻辑值判断
VBA.IsNumericrange”c1″))
Application.WorkSheetFunction.IsNumberrange”c1″))
2) 值判断,不是返回Error–均用于判断数字和错误值
VBA.TypeNamerange”a1″).Value)
3)判断文本
Application.IsTextrange”a1″))
4)判断是否错误值
VBA.IsErrorrange”a1″).value)
5)数组判断
VBA.IsArrayarr)
6)日期判断
VBA.IsDaterange”a1″))
8、数据类型转换
类型装换函数:CBool,CByte,Ccur,CDate,CDbl,CDec,CInt,CLng,CSng,CStr,CVar
format , ) 函数可将一种类型格式化显示为数字或文本类型
exp: format234.5678,”0.00″)
9、日期时间常用处理方式
1)常用转换:
formatnow,”yyyy-mm-dd”) 如2002-12-11
formatnow,”yyyy年mm月dd天”)
formatnow,”yyyy年mm月dd天 h:mm:ss”)
formatnow,”d-mmm-yy”) 英文日期如19-Oct-02
formatnow,”d-mmmm-yy”) 英文日期月份完整拼写 如19-October-02
formatnow,”aaaa”) 中文日期星期几 如星期三
formatnow,”ddd”) 英文日期星期几(简写) 如Sat
formatnow,”dddd”) 英文日期星期几完整写法) 如Saturday
2)日期时间的连接
日期连接 VBA.DateSerial2011,10,1)
时间连接 VBA.TimeSerial1,2,1)
3) 日期时间返回 yearnow)
Year)函数、month)、day)、hour)、VBA.,Minute)、second)
4) 日期时间计算datediff,dateadd
datediff”yyyy”,d1,d2)
datediff”d”,d1,d2) 等等。。注意datediff”q”,d1,d2) q为计算季度差,对年计算时需要参数为4个yyyy,计算分钟时参数为n dateadd”n”,10,d1)
dateadd”d”,10,d1) 加10天 等等 。。 注意计算分钟时参数为n dateadd”n”,10,d1),对年计算时需要参数为4个yyyy
5)制作一个简单计时器(application 的ontime函数)案例:注意设置doevents的意义为当前程序运行时允许其他程序运行,当公共变量k值改变则程序停止。
Option Explicit Dim k Public Sub clock) Dim x If k = 1 Then k = 0 End End If With Range"c5").Font .Name = "Times New Roman" .FontStyle = "bold" .Size = 28 .ColorIndex = 3 End With With Range"c5").Interior .Pattern = xlPatternCrissCross .PatternColorIndex = 6 End With Range"c5") = FormatNow, "h:mm:ss") Application.OnTime Now + TimeValue"00:00:01"), "clock" x = DoEvents '此处设置终止 End Sub Sub stopclock) k = 1 End Sub Sub startclock) Call clock End Sub
效果:
10、随机抽取数据(换位)
案例1:
Sub rndSelect) Dim arr Dim x, num, k As Integer, sr As String Range"c1:c10") = "" Range"a1:a10") = Application.TransposeArray"A", "B", "C", "D", "E", "F", "G", "H", "I", "J")) For x = 1 To 10 num = Rnd) * 10 - x) + 1) 1 '1 表示除1取整 Range"a1:a" & 10 - x + 1)).Interior.ColorIndex = xlNone Range"a" & num).Interior.ColorIndex = 6 Range"c" & x) = Range"a" & num) sr = Range"a" & num) Range"a" & num) = Range"a" & 10 - x + 1)) Range"a" & 10 - x + 1)) = sr Range"a" & 10 - x + 1)).Interior.ColorIndex = 3 Next x End Sub
案例2 : A列20000行数据A1,A2….A20000
不重复随机抽取的三种方式:1、字典 2、换位法(换取的A列数据为字符串)3、换位法优化(添加一维数组辅助交换,索引为1~20000的数组,值为对应的索引,此时交换的值为integer型)
Sub rndict) '字典法 Dim d As Object Set d = CreateObject"scripting.dictionary") Dim arr, num As Integer, x As Integer, arr11 To 20000, 1 To 1) As String, t t = Timer arr = Range"a1:a20000") For x = 1 To 20000 100: num = Rnd) * 20000 - 1) + 1 If d.existsnum) Then GoTo 100 Else dnum) = "" arr1x, 1) = arrnum, 1) End If Next x Range"c1:c20000") = "" Range"c1:c20000") = arr1 [d65535].EndxlUp).Offset1, 0) = Timer - t End Sub Sub rndSel) ' 换位法,换字符串效率相对低 Dim arr Dim x, num As Integer, arr11 To 20000, 1 To 1), sr As String, t t = Timer arr = Range"a1:a20000") For x = 1 To UBoundarr) num = Rnd) * 20000 - x) + 1) 1 arr1x, 1) = arrnum, 1) sr = arrnum, 1) arrnum, 1) = arr20000 - x + 1, 1) arr20000 - x + 1, 1) = sr Next x Range"c1:c20000") = "" Range"c1:c20000") = arr1 [d65535].EndxlUp).Offset1, 0) = Timer - t End Sub Sub rndsel2) '换位法,添加辅助数字列,换数字 提高运行效率 Dim arr Dim arr11 To 20000, 1 To 1), sr As String Dim x, num, arr21 To 20000) As Integer, t t = Timer arr = Range"a1:a20000") For x = 1 To 20000 arr2x) = x Next x For x = 1 To UBoundarr) num = Rnd) * 20000 - x) + 1) arr1x, 1) = arrarr2num), 1) sr = arr2num) arr2num) = arr220000 - x + 1) arr220000 - x + 1) = sr Next x Range"c1:c20000") = "" Range"c1:c20000") = arr1 [d65535].EndxlUp).Offset1, 0) = Timer - t End Sub
效果如下:
明显发现采用第三种方式效率更高。