zoukankan      html  css  js  c++  java
  • VBA学习笔记-02

    目录

    CH6 单元格操作

    CH7 EXCEL事件

    CH8 VBA数组

    CH9 VBA字典

    <br />


    <br />

    CH6 单元格操作

    一、单元格的选取

    1 表示一个单元格(a1)

     Sub s()
           Range("a1").Select
           Cells(1, 1).Select
           Range("A" & 1).Select
           Cells(1, "A").Select
           Cells(1).Select
           [a1].Select
     End Sub
    

    2 表示相邻单元格区域

     Sub d()                              ‘选取单元格a1:c5
             Range("a1:c5").Select
             Range("A1", "C5").Select
             Range(Cells(1, 1), Cells(5, 3)).Select
             Range("a1:a10").Offset(0, 1).Select
            Range("a1").Resize(5, 3).Select
     End Sub
    

    3 表示不相邻的单元格区域

    Sub d1()
    
      Range("a1,c1:f4,a7").Select
      
      Union(Range("a1"), Range("c1:f4"), Range("a7")).Select
      
    End Sub
    
    Sub dd() union示例
      Dim rg As Range, x As Integer
      For x = 2 To 10 Step 2
        If x = 2 Then Set rg = Cells(x, 1)
        
        Set rg = Union(rg, Cells(x, 1))
      Next x
      rg.Select
    End Sub
    

    4 表示行

    Sub h()    
      Rows(1).Select
      Rows("3:7").Select
      Range("1:2,4:5").Select
       Range("c4:f5").EntireRow.Select       
    End Sub
    

    5 表示列

     Sub L()    
       Columns(1).Select
       Columns("A:B").Select
       Range("A:B,D:E").Select
      Range("c4:f5").EntireColumn.Select 选取c4:f5所在的行       
     End Sub
    

    6 重置坐标下的单元格表示方法

    Sub cc()
    
      Range("b2").Range("a1") = 100
      
    End Sub
    

    7 表示正在选取的单元格区域

     Sub d2()
           Selection.Value = 100
     End Sub
    

    二、特殊单元格定位

    1 已使用的单元格区域

    Sub d1()  
          Sheets("sheet2").UsedRange.Select    
          wb.Sheets(1).Range("a1:a10").Copy Range("i1")    
    End Sub
    

    2 某单元格所在的单元格区域

     Sub d2()    
          Range("b8").CurrentRegion.Select    
     End Sub
    

    3 两个单元格区域共同的区域

    Sub d3()     
          Intersect(Columns("b:c"), Rows("3:5")).Select  
    End Sub
    

    4 调用定位条件选取特殊单元格

    Sub d4()  
       Range("A1:A6").SpecialCells(xlCellTypeBlanks).Select       
    End Sub
    

    5 端点单元格

     Sub d5()   
           Range("a65536").End(xlUp).Offset(1, 0) = 1000     
     End Sub
    
     Sub d6()   
           Range(Range("b6"), Range("b6").End(xlToRight)).Select     
     End Sub
    

    三、单元格信息

    1 单元格的值

     Sub x1()
            Range("b10") = Range("c2").Value
            Range("b11") = Range("c2").Text
          Range("c10") = "" & Range("I3").Formula
     End Sub
    

    2 单元格的地址

    Sub x2()
     With Range("b2").CurrentRegion
       [b12] = .Address
       [c12] = .Address(0, 0)
       [d12] = .Address(1, 0)
       [e12] = .Address(0, 1)
       [f12] = .Address(1, 1)
     End With
    End Sub
    

    3 单元格的行列信息

    Sub x3()
      With Range("b2").CurrentRegion
        [b13] = .Row
        [b14] = .Rows.Count
        [b15] = .Column
        [b16] = .Columns.Count
        [b17] = .Range("a1").Address
      End With
    End Sub
    

    4、单元格的格式信息

    Sub x4()
      With Range("b2")
        [b19] = .Font.Size
        [b20] = .Font.ColorIndex
        [b21] = .Interior.ColorIndex
        [b22] = .Borders.LineStyle
      End With
    End Sub
    

    5、单元格批注信息

     Sub x5()
        [B24] = Range("I2").Comment.Text
     End Sub
    

    6 单元格的位置信息

     Sub x6()
        With Range("b3")
          [b26] = .Top
          [b27] = .Left
          [b28] = .Height
          [b29] = .Width
        End With
     End Sub
    

    7 单元格的上级信息

    Sub x7()
      With Range("b3")
        [b31] = .Parent.Name
        [b32] = .Parent.Parent.Name
      End With
    End Sub
    

    8 内容判断

      Sub x8()
       With Range("i3")
        [b34] = .HasFormula
        [b35] = .Hyperlinks.Count
       End With
      End Sub
    

    四、单元格的数字格式

    1.判断数值的格式

    (1) 判断是否为空单元格

    Sub d1()
       [b1] = ""
       If Range("a1") = "" Then
       If Len([a1]) = 0 Then
       If VBA.IsEmpty([a1]) Then
          [b1] = "空值"
        End If
    End Sub
    

    (2) 判断是否为数字

    Sub d2()
      [b2] = ""
      If VBA.IsNumeric([a2]) And [a2] <> "" Then
      If Application.WorksheetFunction.IsNumber([a2]) Then
        [b2] = "数字"
      End If
    End Sub
    

    (3) 判断是否为文本

    Sub d3()
      [b3] = ""
      If Application.WorksheetFunction.IsText([A3]) Then
       If VBA.TypeName([a3].Value) = "String" Then
         [b3] = "文本"
      End If
    End Sub
    

    (4) 判断是否为汉字

     Sub d4()
        [b4] = ""
        If [a4] > "z" Then
          [b4] = "汉字"
        End If
     End Sub
    

    (5) 判断错误值

    Sub d10()
      [b5] = ""
      If VBA.IsError([a5]) Then
      If Application.WorksheetFunction.IsError([a5]) Then
         [b5] = "错误值"
      End If
    End Sub
     Sub d11()
      [b6] = ""
      If VBA.IsDate([a6]) Then
         [b6] = "日期"
      End If
    End Sub
    

    2.设置单元格自定义格式

     Sub d30()
        Range("d1:d8").NumberFormatLocal = "0.00"
     End Sub
    

    3.按指定格式从单元格返回数值

    Format函数语法(和工作表数Text用法基本一致)

    Format(数值,自定义格式代码)
    

    五、设置Excel中的颜色

    Excel中的颜色可以用两种方式获取,一种是EXCEL内置颜色,另一种是利用QBCOLOR函数返回

    Sub y1()
         Dim x As Integer
        Range("a1:b60").Clear
        For x = 1 To 56
              Range("a" & x) = x
              Range("b" & x).Font.ColorIndex = 3
        Next x
    End Sub
    
     Sub y2()
          Dim x As Integer
         For x = 0 To 15
            Range("d" & x + 1) = x
            Range("e" & x + 1).Interior.Color = QBColor(x)
         Next x
     End Sub
    
    Sub y3()
          Dim 红 As Integer, 绿 As Integer, 蓝 As Integer
                  红 = 255
                  绿 = 123
                  蓝 = 100
          Range("g1").Interior.Color = RGB(红, 绿, 蓝)
    End Sub
    

    六、单元格合并

    1.单元格合并

    Sub h1()    
          Range("g1:h3").Merge    
    End Sub
    

    2.合并区域的返回信息

    Sub h2()   
         Range("e1") = Range("b3").MergeArea.Address         ' 返回单元格所在的合并单元格区域   
    End Sub
    

    3.判断是否含合并单元格

    Sub h3()
         MsgBox Range("b2").MergeCells
         MsgBox Range("A1:D7").MergeCells
        Range("e2") = IsNull(Range("a1:d7").MergeCells)
        Range("e3") = IsNull(Range("a9:d72").MergeCells)
    End Sub
    

    4.综合示例

    合并H列相同单元格

     Sub h4()
      Dim x As Integer
      Dim rg As Range
      Set rg = Range("h1")
       Application.DisplayAlerts = False
      For x = 1 To 13
        If Range("h" & x + 1) = Range("h" & x) Then
          Set rg = Union(rg, Range("h" & x + 1))
        Else
         
           rg.Merge
          
          Set rg = Range("h" & x + 1)
        End If
      Next x
      Application.DisplayAlerts = True
     End Sub
    

    七、单元格输入

    1 单元格输入

    Sub t1()
      Range("a1") = "a" & "b"
      Range("b1") = "a" & Chr(10) & "b"          换行答输入
    End Sub
    

    2 单元格复制和剪切

      Sub t2()
        Range("a1:a10").Copy Range("c1")          A1:A10的内容复制到C1
      End Sub
    
      Sub t3()
        Range("a1:a10").Copy
        ActiveSheet.Paste Range("d1")             粘贴至D1
      End Sub
      
      Sub t4()
        Range("a1:a10").Copy
        Range("e1").PasteSpecial (xlPasteValues)       只粘贴为数值
      End Sub
      
      Sub t5()
        Range("a1:a10").Cut
        ActiveSheet.Paste Range("f1")                  粘贴到f1
      End Sub
    
      Sub t6()
        Range("c1:c10").Copy
        Range("a1:a10").PasteSpecial Operation:=xlAdd          选择粘贴-加
      End Sub
      
      Sub T7()
          Range("G1:G10") = Range("A1:A10").Value
      End Sub
    

    3 填充公式

    Sub T8()
      Range("b1") = "=a1*10"
      Range("b1:b10").FillDown                     向下填充公式
    End Sub
    

    4.插入行并复制公式

    (1)插入行

    Sub c1()
        Rows(4).Insert
    End Sub
    

    (2)插入行并复制公式

    Sub c2()                      '插入行并复制公式
            Rows(4).Insert
            Range("3:4").FillDown
          Range("4:4").SpecialCells(xlCellTypeConstants) = ""
    End Sub
    

    (3)如不相同,则插入一行

    Sub c3()
          Dim x As Integer
          For x = 2 To 20
          If Cells(x, 3) <> Cells(x + 1, 3) Then
                Rows(x + 1).Insert
            x = x + 1
        End If
      Next x
    End Sub
    

    (4)相同部门插入小计汇总

    Sub c4()
      Dim x As Integer, m1 As Integer, m2 As Integer
      Dim k As Integer
      m1 = 2
      For x = 2 To 1000
          If Cells(x, 1) = "" Then Exit Sub
          If Cells(x, 3) <> Cells(x + 1, 3) Then
              m2 = x
              Rows(x + 1).Insert
              Cells(x + 1, "c") = Cells(x, "c") & " 小计"
              Cells(x + 1, "h") = "=sum(h" & m1 & ":h" & m2 & ")"
              Cells(x + 1, "h").Resize(1, 4).FillRight
              Cells(x + 1, "i") = ""
              x = x + 1
              m1 = m2 + 2
          End If
     Next x
    End Sub
    

    (5)删除小计行

    Sub dd() 删除小计行
         Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
    End Sub
    

    八、单元格查询

    1 使用循环查找 (在单元格中查找效率太低)

    2 调用工作表函数

    Sub c1() 判断是否存在,并查找所在行数
      Dim hao As Integer
      Dim icount As Integer
      icount = Application.WorksheetFunction.CountIf(Sheets("库存明细表").[b:b], [g3])
      If icount > 0 Then
       MsgBox "该入库单号码已经存在,请不要重复录入"
       MsgBox Application.WorksheetFunction.Match([g3], Sheets("库存明细表").[b:b], 0)
      End If
    End Sub
    

    3 使用Find方法

    Sub c2()
      Dim r As Integer, r1 As Integer
      Dim icount As Integer
      icount = Application.WorksheetFunction.CountIf(Sheets("库存明细表").[b:b], [g3])
      If icount > 0 Then
       r = Sheets("库存明细表").[b:b].Find(Range("G3"), Lookat:=xlWhole).Row 查找号码第一次出现的位置
       r1 = Sheets("库存明细表").[b:b].Find([g3], , , , , xlPrevious).Row
       MsgBox r & ":" & r1
      End If
    End Sub
    

    4 返回最下一行非空行的行数

     Sub c3() 返回最下一行非空行的行数    
      MsgBox Sheets("库存明细表").Cells.Find("*", , , , , xlPrevious).Row    
     End Sub
    

    5 入库单查询实例

    Sub 输入()
          Dim c As Integer   '号码在库存表中的个数
          Dim r As Integer   '入库单的数据行数
          Dim cr As Integer  '库存明细表中第一个空行的行数
          With Sheets("库存明细表")
          c = Application.CountIf(.[b:b], Range("g3"))
          If c > 0 Then
                 MsgBox "该单据号码已经存在!,请不要重复录入"
           Exit Sub
          Else
               r = Application.CountIf(Range("b6:b10"), "<>")
               cr = .[b65536].End(xlUp).Row + 1
                       .Cells(cr, 1).Resize(r, 1) = Range("e3")
                       .Cells(cr, 2).Resize(r, 1) = Range("g3")
                       .Cells(cr, 3).Resize(r, 1) = Range("c3")
                       .Cells(cr, 4).Resize(r, 6) = Cells(6, 2).Resize(r, 6).Value
               MsgBox "输入已完成"
          End If
         End With
    End Sub
    
    
    Sub 查找()
          Dim c As Integer   '号码在库存表中的个数
          Dim r As Integer   '入库单的数据行数  
          With Sheets("库存明细表")
            c = Application.CountIf(.[b:b], Range("g3"))
            If c = 0 Then
                   MsgBox "该单据号码不存在!"
             Exit Sub
            Else
             r = .[b:b].Find(Range("g3"), , , , , xlNext).Row
            Range("c3") = .Cells(r, 3)
            Range("e3") = .Cells(r, 1)
            Cells(6, 2).Resize(c, 5) = .Cells(r, 4).Resize(c, 5).Value
           MsgBox "查询已完成"
           End If
         End With
    End Sub
    
    Sub 删除()
         Dim c As Integer   '号码在库存表中的个数
        Dim r As Integer   '入库单的数据行数  
        With Sheets("库存明细表")
                c = Application.CountIf(.[b:b], Range("g3"))
                If c = 0 Then
                         MsgBox "该单据号码不存在!"
               Exit Sub
                Else
                      r = .[b:b].Find(Range("g3"), , , , , xlNext).Row
                            .Range(r & ":" & c + r - 1).Delete
                     MsgBox "删除已完成"
              End If
       End With
     End Sub
    
    Sub 修改()
        Call 删除
        Call 输入
    End Sub
    

    <br />


    <br />

    CH7 EXCEL事件

    单元格发生变动时提醒
    worksheet selectionchange
    加入代码
    private sub worksheet.change(byval target as range)
    msgbox target.address &"单元格的值被改为"&target.value
    <br />


    <br />

    CH8 数组

    一、VBA数组概念

    1、什么是VBA数组呢?

    VBA数组就是储存一组数据的数据空间?数据类型可以数字,可以是文本,可以是对象,也可以是VBA数组.

    2 VBA数组存在形态

    VBA数组是以变量形式存放的一个空间,它也有行有列,也可以是三维空间。

    1. 常量数组
      array(1,2)
      array(array(1,2,4),array("a","b","c"))
    2. 静态数组
      x(4) 有5个位置,编号从0~4
      arr(1 to 10) 有10个位置,编号1~10
      arr(1 to 10,1 to 2) 10行2列的空间,总共20个位置,这是二维数组
      arr(1 to 10,1 to 2,1 to 3) 三维数组,总1023=60个位置。这是三维数组
      3)动态数组
      arr() 不知道有多少行多少列

    二、数组的读取

    1.VBA数组写入

    1)按编号(标)写入和读取

     Sub t1()     写入一维数组
     Dim x As Integer
     Dim arr(1 To 10)
     arr(2) = 190
     arr(10) = 5
     End Sub
    
    Sub t2()     向二维数组写入数据和读取
     Dim x As Integer, y As Integer
     Dim arr(1 To 5, 1 To 4)
     For x = 1 To 5
       For y = 1 To 4
         arr(x, y) = Cells(x, y)
       Next y
     Next x
    MsgBox arr(3, 1)
    End Sub
    

    2)动态数组

       Sub t3()
        Dim arr()
        Dim row
        row = Sheets("sheet2").Range("a65536").End(xlUp).row - 1
        ReDim arr(1 To row)
        For x = 1 To row
           arr(x) = Cells(x, 1)
        Next x
        Stop
       End Sub
    

    3)批量写入

      Sub t4()     由常量数组导入
      Dim arr
      arr = Array(1, 2, 3, "a")
      Stop
      End Sub
    
     Sub t5()     由单元格区域导入
       Dim arr
       arr = Range("a1:d5")
       Stop
     End Sub
    

    2.数组的读取

    1)在内存中读取
    在内存中读取后用于继续运算,直接用下面的格式
    数组变量(5)
    数组变量(3,2)
    例:

        Sub d1()
         Dim arr, arr1()
         Dim x As Integer, k As Integer, m As Integer
         arr = Range("a1:a10")     把单元格区域导入内存数组中
         m = Application.CountIf(Range("a1:a10"), ">10")     计算大于10的个数
         ReDim arr1(1 To m)
         For x = 1 To 10
           If arr(x, 1) > 10 Then
              k = k + 1
              arr1(k) = arr(x, 1)
           End If
         Next x
        End Sub
    

    2)读取存入单元格中

      Sub d2()     二维数组存入单元格
        Dim arr, arr1(1 To 5, 1 To 1)
        Dim x As Integer
        arr = Range("b2:c6")
        For x = 1 To 5
          arr1(x, 1) = arr(x, 1) * arr(x, 2)
        Next x
        Range("d2").Resize(10) = arr1
      End Sub
      
      Sub d3()     一维数组存入单元格
        Dim arr, arr1(1 To 5)
        Dim x As Integer
        arr = Range("b2:c6")
        For x = 1 To 5
          arr1(x) = arr(x, 1) * arr(x, 2)
        Next x
            Range("a13").Resize(1, 5) = arr1
        Range("d2").Resize(5) = Application.Transpose(arr1)
      End Sub
       
      Sub d4()     数组部分存入
        Dim arr, arr1(1 To 10000, 1 To 1)
        Dim x As Integer
        arr = Range("b2:c6")
        For x = 1 To 5
          arr1(x, 1) = arr(x, 1) * arr(x, 2)
        Next x
        Range("d2").Resize(5) = arr1
      End Sub
    

    三、数组的空间

    1、数组的大小

    数组是用编号排序的,那么如何获得一个数组的大小呢

    Lbound(数组) 可以获取数组的最小下标(编号)
    Ubound(数组) 可以获取数组的最大上标(编号)
    Ubound(数组,1) 可以获得数组的行方面(第1维)最大上标
    Ubound(数组,2) 可以获得数组的列方向(第2维)的最大上标

    Sub d6()
        Dim arr
        Dim k, m
        arr = Range("a2:d5")
        For x = 1 To UBound(arr, 1)
    
        Next x
    End Sub
    

    2、动态数组的动态扩充

    如果一个数组无法或不方便计算出总的大小,而在一些特殊情况下又不允许有空位。这时我们就需要用动态的导入方法

    ReDim Preserve arr() 可以声明一个动态大小的数组,而且可以保留原来的数值,就相当于厂房小了,可以改扩建增大,但是它只能 让最未维实现动态,如果是一维不存在最未维,只有一维

    1)扩充方式1
    Sub d7()
    Dim arr, arr1()
     arr = Range("a1:d6")
     Dim x, k
     For x = 1 To UBound(arr)
      If arr(x, 1) = "B" Then
         k = k + 1
         ReDim Preserve arr1(1 To 4, 1 To k)
         arr1(1, k) = arr(x, 1)
         arr1(2, k) = arr(x, 2)
         arr1(3, k) = arr(x, 3)
         arr1(4, k) = arr(x, 4)
      End If
     Next x
    Range("a8").Resize(k, 4) = Application.Transpose(arr1)
    End Sub
    

    (2)方式二:申明足够大的数组
    Sub d8()
    Dim arr, arr1(1 To 100000, 1 To 4)
    arr = Range("a1:d6")
    Dim x, k
    For x = 1 To UBound(arr)
    If arr(x, 1) = "B" Then
    k = k + 1
    arr1(k, 1) = arr(x, 1)
    arr1(k, 2) = arr(x, 2)
    arr1(k, 3) = arr(x, 3)
    arr1(k, 4) = arr(x, 4)
    End If
    Next x
    Range("a15").Resize(k, 4) = arr1
    End Sub

    3 清空数组

    清空数组使用erase语句

    Sub d9()
    Dim arr, arr1(1 To 1000, 1 To 1)
    Dim x, m, k
    arr = Range("a1:a16")
    For x = 1 To UBound(arr)
     If arr(x, 1) <> "" Then
        k = k + 1
        arr1(k, 1) = arr(x, 1)
     Else
        m = m + 1
        Range("c1").Offset(0, m).Resize(k) = arr1
        Erase arr1
        k = 0
     End If
    Next x
    End Sub
    

    四、可以生成数组的函数

    1、split函数

    按分隔符把字符串截取成VBA数组,该数组是一维数组,编号从0开始

    split(字符串,分隔符)

    Sub t1()
      Dim sr, arr
      sr = "A-BC-FGR-H"
      arr = VBA.Split(sr, "-")
      MsgBox Join(arr, ",")
    End Sub
    

    2、Filter函数:只能模糊匹配

    按条件筛选符合条件的值组成一个新的数组

    Filter(数组,筛选条件,是/否)

    注:如果是(true)则返回包含的数组,如果否则返回非包含的数组

    Sub t2()
     Dim arr, arr1, arr2
     arr = Application.Transpose(Range("A2:A10"))
     arr1 = VBA.Filter(arr, "W", True)
     arr2 = VBA.Filter(arr, "W", False)
     Range("B2").Resize(UBound(arr1) + 1) = Application.Transpose(arr1)
     Range("C2").Resize(UBound(arr2) + 1) = Application.Transpose(arr2)
    End Sub
    

    3、index函数:

    调用该工作表函数可以把二维数组的某一列或某一行截取出来,构成一个新的数组。
    Application.Index(二维数组,0,列数)) 返回二维数组
    Application.Index(二维数组,行数,0)) 返回一维数组

    Sub t3()
     Dim arr, arr1, arr2
      arr = Range("a2:d6")
      arr1 = Application.Index(arr, , 1)
      arr2 = Application.Index(arr, 4, 0)
      Stop
    End Sub
    

    4、vlookup函数

    Vlookup函数的第一个参数可以用VBA数组,返回的也是一个VBA数组

    Sub t4()
    Dim arr, arr1
      arr = Range("a2:d6")
      arr1 = Application.VLookup(Array("B", "C"), arr, 4, 0)
    End Sub
    

    5 Sumif函数和Countif函数

    Countif和sumif函数的第二个参数都可以使用数组,所以也可以返回一个VBA数组,如:

     Sub t5()
     Dim T
     T = Timer
       Dim arr
       arr = Application.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000"))
     MsgBox Timer - T
     Stop
     End Sub
    
    Sub t55()
     Dim T
     T = Timer
      Dim arr, arr1(1 To 4, 1 To 2), x
      arr1(1, 1) = "B"
      arr1(2, 1) = "C"
      arr1(3, 1) = "G"
      arr1(4, 1) = "R"
     
      For x = 2 To 10000
         Select Case Cells(x, 1)
         Case "B"
            arr1(1, 2) = arr1(1, 2) + Cells(x, 2)
         Case "C"
            arr1(2, 2) = arr1(2, 2) + Cells(x, 2)
         Case "G"
            arr1(3, 2) = arr1(3, 2) + Cells(x, 2)
         Case "R"
            arr1(4, 2) = arr1(4, 2) + Cells(x, 2)
         End Select
      Next x
     MsgBox Timer - T
    End Sub    
    

    五、单元格格式

    1.金额大于500填上红色

    Sub 单元格循环()
    Dim x As Integer
    Dim t
    清除颜色
    t = Timer
    For x = 2 To Range("a65536").End(xlUp).Row
        If Range("d" & x) > 500 Then
           Range(Cells(x, 1), Cells(x, 4)).Interior.ColorIndex = 3
       End If
    Next x
    MsgBox Timer - t
    End Sub
    

    2.清除颜色

    Sub 清除颜色()
      Range("a:d").Interior.ColorIndex = xlNone
    End Sub
    

    3.数组方法1

    Sub 数组方法()
     Dim arr, t
     Dim x As Integer
     Dim sr As String, sr1 As String
     清除颜色
      t = Timer
      arr = Range("d2:d" & Range("a65536").End(xlUp).Row)
     For x = 1 To UBound(arr)
          If x = UBound(arr) And sr <> "" Then Range(Left(sr, Len(sr) - 1)).Interior.ColorIndex = 3
              If arr(x, 1) > 500 Then
                  sr1 = sr
                  sr = sr & "A" & x + 1 & ":D" & x + 1 & ","
             If Len(sr) > 255 Then
                    sr = sr1
                    Range(Left(sr, Len(sr) - 1)).Interior.ColorIndex = 3
                     sr = ""
            End If
       End If
     Next x
    MsgBox Timer - t
    End Sub
    

    4.数组方法2

    Sub 数组方法2()
    Dim arr, t
    Dim x As Integer, x1 As Integer
    Dim sr As String, sr1 As String
    清除颜色
    t = Timer
    arr = Range("d2:d" & Range("a65536").End(xlUp).Row)
    For x = 1 To UBound(arr)
          If x = UBound(arr) Then Range(Left(sr, Len(sr) - 1)).Interior.ColorIndex = 3
               If arr(x, 1) > 500 Then
                   sr1 = sr
                   x1 = x + 1
                   Do
                         x = x + 1
                   Loop Until arr(x, 1) <= 500      
         sr = sr & "A" & x1 & ":D" & x & ","
      If Len(sr) > 255 Then
        sr = sr1
        x = x1 - 1
        Range(Left(sr, Len(sr) - 1)).Interior.ColorIndex = 3
        sr = ""
      End If
      x = x - 1
    End If
    Next x
    MsgBox Timer - t
    End Sub
    

    5.数组方法3

    Sub 数组方法3()
        Dim arr, t
        Dim x As Integer, x1 As Integer
        Dim sr As String, sr1 As String
       清除颜色
       t = Timer
      arr = Range("d2:d" & Range("a65536").End(xlUp).Row)
      For x = 1 To UBound(arr)
      If x = UBound(arr) Then Application.Intersect(Range("a:d"), Range(Left(sr, Len(sr) - 1))).Interior.ColorIndex = 3
           If arr(x, 1) > 500 Then
            sr1 = sr
           x1 = x + 1
          Do
               x = x + 1
         Loop Until arr(x, 1) <= 500      
         sr = sr & x1 & ":" & x & ","
         If Len(sr) > 255 Then
              sr = sr1
             x = x1 - 1
            Application.Intersect(Range("a:d"), Range(Left(sr, Len(sr) - 1))).Interior.ColorIndex = 3
            sr = ""
         End If
      x = x - 1
     End If
     Next x
     MsgBox Timer - t
    End Sub
    

    Option Explicit
    '数组也可以设置格式?
    '数组除了数字类型外,当然没有颜色、字体等格式,但是别忘了range对象可以表示多个连续或不连续的单元格区域
    '利用上述特点,我们就是要数组构造单元格地址串,然后批量对单元格进行格式设置。
    '注意,单元格地址串不能>255,所以如果单元格操作过多,我们还需要分次分批设置单元格格式

    Sub 填充颜色()
     Range("a2:d2,a7:d7,a10:d10").Interior.ColorIndex = 3
    End Sub
    

    六、数组函数补充

    1 数组的最值

     Sub s()
     Dim arr1()
     
    arr1 = Array(1, 12, 4, 5, 19)
     
    MsgBox "1, 12, 4, 5, 19最大值" & Application.Max(arr1)
     MsgBox "1, 12, 4, 5, 19最小值:" & Application.Min(arr1)
     MsgBox "1, 12, 4, 5, 19第二大值:" & Application.Large(arr1, 2)
     MsgBox "1, 12, 4, 5, 19第二小值:" & Application.Small(arr1, 2)
     
    End Sub
    

    2、求和

     用application.Sum (数组)
    

    3 统计个数

    counta和count函数可以统计VBA数组的数字个数及所有已填充内容的个数

     Sub s1()
      
      Dim arr1, arr2(0 To 10), x
      arr1 = Array("a", "3", "", 4, 6)
      For x = 0 To 4
        arr2(x) = arr1(x)
      Next x
      
      MsgBox "数组1的数字个数:" & Application.Count(arr2)
      
      MsgBox "数组2的已填充数值的个数" & Application.CountA(arr2)
      
      End Sub
    

    4 在数组里查找

      Sub s2()
       Dim arr
       On Error Resume Next
       arr = Array("a", "c", "b", "f", "d")
       MsgBox Application.Match("f", arr, 0)
      If Err.Number = 13 Then
         MsgBox "查找不到"
       End If
      End Sub  
    

    二、数组函数

    1、split函数

     '按分隔符把字符串截取成VBA数组,该数组是一维数组,编号从0开始
    
     'split(字符串,分隔符)
    
    Sub t1()
      Dim sr, arr
      sr = "A-BC-FGR-H"
      arr = VBA.Split(sr, "-")
      MsgBox Join(arr, ",")
    End Sub
    

    2、Filter函数:

     '按条件筛选符合条件的值组成一个新的数组
    
     'Filter(数组,筛选条件,是/否)
     
     '注:如果是(true)则返回包含的数组,如果否则返回非包含的数组
    Sub t2()
     Dim arr, arr1, arr2
     arr = Application.Transpose(Range("A2:A10"))
     arr1 = VBA.Filter(arr, "W", True)
     arr2 = VBA.Filter(arr, "W", False)
     Range("B2").Resize(UBound(arr1) + 1) = Application.Transpose(arr1)
     Range("C2").Resize(UBound(arr2) + 1) = Application.Transpose(arr2)
    End Sub
    

    3、index函数:

    '调用该工作表函数可以把二维数组的某一列或某一行截取出来,构成一个新的数组。
    
    ' Application.Index(二维数组,0,列数)) 返回二维数组
      ' Application.Index(二维数组,行数,0)) 返回一维数组
     Sub t3()
      Dim arr, arr1, arr2
    
       arr = Range("a2:d6")
       arr1 = Application.Index(arr, , 1)
       arr2 = Application.Index(arr, 4, 0)
       Stop
     End Sub
    

    4、vlookup函数

      'Vlookup函数的第一个参数可以用VBA数组,返回的也是一个VBA数组
    
        Sub t4()
        Dim arr, arr1
          arr = Range("a2:d6")
          arr1 = Application.VLookup(Array("B", "C"), arr, 4, 0)
        End Sub
    

    5 Sumif函数和Countif函数

     'Countif和sumif函数的第二个参数都可以使用数组,所以也可以返回一个VBA数组,如:
    
     Sub t5()
         Dim T
         T = Timer
           Dim arr
           arr = Application.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000"))
         MsgBox Timer - T
         Stop
         End Sub
    
       Sub t55()
         Dim T
         T = Timer
          Dim arr, arr1(1 To 4, 1 To 2), x
          arr1(1, 1) = "B"
          arr1(2, 1) = "C"
          arr1(3, 1) = "G"
          arr1(4, 1) = "R"
         ' arr = Range("a1:d10000")
          For x = 2 To 10000
             Select Case Cells(x, 1)
             Case "B"
                arr1(1, 2) = arr1(1, 2) + Cells(x, 2)
             Case "C"
                arr1(2, 2) = arr1(2, 2) + Cells(x, 2)
             Case "G"
                arr1(3, 2) = arr1(3, 2) + Cells(x, 2)
             Case "R"
                arr1(4, 2) = arr1(4, 2) + Cells(x, 2)
             End Select
          Next x
         MsgBox Timer - T
       End Sub
    

    七、VBA排序算法

    1.插入排序

    Sub 插入排序()
    Dim arr, temp, x, y, t, iMax, k, k1, k2
         t = Timer
        arr = Range("a1:a10")
        For x = 1 + 1 To UBound(arr)  
        temp = arr(x, 1)     记得要插入的值     
        For y = x - 1 To 1 Step -1
       If arr(y, 1) <= temp Then Exit For
       arr(y + 1, 1) = arr(y, 1)
           k1 = k1 + 1
       Next y
       arr(y + 1, 1) = temp
             k2 = k2 + 1
      Next
         Range("d3").Resize(UBound(arr)) = ""
         Range("d3").Resize(UBound(arr)) = arr
         Range("d2") = Timer - t
         MsgBox k1
    End Sub
    
    Sub 插入排序单元格演示()
         On Error Resume Next
        Dim arr, temp, x, y, t, iMax, k
        For x = 2 To 10  
            temp = Cells(x, 1)     记得要插入的值
                     Range("A" & x).Interior.ColorIndex = 3
           For y = x - 1 To 1 Step -1
                   Range("A" & y).Interior.ColorIndex = 4
            If Cells(y, 1) <= temp Then Exit For
                   Cells(y + 1, 1) = Cells(y, 1)
                   Range("A" & y).Interior.ColorIndex = xlNone
           Next y
           Cells(y + 1, 1) = temp
               Range("A" & y).Interior.ColorIndex = xlNone
               Range("A" & x).Interior.ColorIndex = xlNone
       Next
    End Sub
    

    2.快速排序

    Sub dd()
    Dim arr1(0 To 4999) As Long, arr, x, t
    t = Timer
    arr = Range("a1:a5000")
    For x = 1 To 5000
      arr1(x - 1) = arr(x, 1)
    Next x
    QuickSort arr1()
    Range("f2") = Timer - t
     End Sub 
    
    Public Sub QuickSort(ByRef lngArray() As Long)
        Dim iLBound As Long
        Dim iUBound As Long
        Dim iTemp As Long
        Dim iOuter As Long
        Dim iMax As Long
                 iLBound = LBound(lngArray)
                iUBound = UBound(lngArray)     
                If (iUBound - iLBound) Then
                    For iOuter = iLBound To iUBound   
                If lngArray(iOuter) > lngArray(iMax) Then iMax = iOuter
                      Next iOuter
                       iTemp = lngArray(iMax)
                      lngArray(iMax) = lngArray(iUBound)
                      lngArray(iUBound) = iTemp            开始快速排序
                      InnerQuickSort lngArray, iLBound, iUBound
                End If
            R ange("f3").Resize(5000) = Application.Transpose(lngArray)
        End Sub
    
    
    
    Private Sub InnerQuickSort(ByRef lngArray() As Long, ByVal iLeftEnd As Long, ByVal iRightEnd As Long)
    
    Dim iLeftCur As Long
    
    Dim iRightCur As Long
    
    Dim iPivot As Long
    
    Dim iTemp As Long
    
    
    
    If iLeftEnd >= iRightEnd Then Exit Sub
    
    
    
    iLeftCur = iLeftEnd
    
    iRightCur = iRightEnd + 1
    
    iPivot = lngArray(iLeftEnd)  
    
    Do
        Do
            iLeftCur = iLeftCur + 1
        Loop While lngArray(iLeftCur) < iPivot       
    
        Do
    
            iRightCur = iRightCur - 1
        Loop While lngArray(iRightCur) > iPivot       
    
        If iLeftCur >= iRightCur Then Exit Do              
       交换值
        iTemp = lngArray(iLeftCur)
        lngArray(iLeftCur) = lngArray(iRightCur)
        lngArray(iRightCur) = iTemp
    Loop  
    
        递归快速排序
    lngArray(iLeftEnd) = lngArray(iRightCur)
    lngArray(iRightCur) = iPivot
    InnerQuickSort lngArray, iLeftEnd, iRightCur - 1
    InnerQuickSort lngArray, iRightCur + 1, iRightEnd
    End Sub
    

    3.冒泡排序

    Sub 冒泡排序()
       Dim arr, temp, x, y, t, k
       t = Timer
       arr = Range("a1:a10")
       For x = 1 To UBound(arr) - 1
             For y = x + 1 To UBound(arr)     只和当前数字下面的数进行比较
                 If arr(x, 1) > arr(y, 1) Then     如果它大于它下面某一个数字
                         temp = arr(x, 1)
                         arr(x, 1) = arr(y, 1)
                         arr(y, 1) = temp
                 End If
       
             Next y
         Next x
         Range("b3").Resize(x) = ""
         Range("b3").Resize(x) = arr
                 Range("b2") = Timer - t
         MsgBox k
    End Sub
    
    
    Sub 冒泡排序演示()
         Dim arr, temp, x, y, t, k
         For x = 1 To 9
                    Range("a" & x).Interior.ColorIndex = 3
         For y = x + 1 To 10      只和当前数字下面的数进行比较
                         Range("a" & y).Interior.ColorIndex = 4
         If Cells(x, 1) > Cells(y, 1) Then     如果它大于它下面某一个数字
               temp = Cells(x, 1)
               Cells(x, 1) = Cells(y, 1)
               Cells(y, 1) = temp
         End If
                         Range("a" & y).Interior.ColorIndex = xlNone
         Next y
                         Range("a" & x).Interior.ColorIndex = xlNone                         
         Next x
    End Sub
    

    4.希尔排序

    Sub 希尔排序()
        Dim arr
        Dim 总大小, 间隔, x, y, temp, t
        t = Timer
        arr = Range("a1:a30")
        总大小 = UBound(arr) - LBound(arr) + 1
        间隔 = 1
        If 总大小 > 13 Then
                 Do While 间隔 < 总大小
                       间隔 = 间隔 * 3 + 1
                 Loop
                 间隔 = 间隔  9
        End If
          Stop
        Do While 间隔
               For x = LBound(arr) + 间隔 To UBound(arr)
                temp = arr(x, 1)
              For y = x - 间隔 To LBound(arr) Step -间隔
                         If arr(y, 1) <= temp Then Exit For
                           arr(y + 间隔, 1) = arr(y, 1)
                                   k1 = k1 + 1
              Next y
                      arr(y + 间隔, 1) = temp
                       Next x
                      间隔 = 间隔  3
               Loop
                       MsgBox k1
                       Range("e3").Resize(5000) = ""
                      Range("d1").Resize(UBound(arr)) = arr
                               Range("e2") = Timer - t
      End Sub
    Sub 打乱顺序()
         Dim arr, temp, x
         arr = Range("a1:a" & Range("a65536").End(xlUp).Row)
         For x = 1 To UBound(arr)
               num = Int(Rnd() * UBound(arr) + 1)
               temp = arr(num, 1)
               arr(num, 1) = arr(x, 1)
               arr(x, 1) = temp
         Next x
         Range("a1").Resize(x - 1) = arr
     End Sub
         Sub 希尔排序单元格演示()
           Dim arr
           Dim 总大小, 间隔, x, y, temp, t
           t = Timer
           arr = Range("a1:a" & Range("a65536").End(xlUp).Row)
           总大小 = UBound(arr) - LBound(arr) + 1
           间隔 = 1
           If 总大小 > 13 Then
              Do While 间隔 < 总大小
                间隔 = 间隔 * 3 + 1
              Loop
              间隔 = 间隔  9
           End If
               Stop
           Do While 间隔
              For x = LBound(arr) + 间隔 To UBound(arr)
               temp = Cells(x, 1)
               Range("a" & x).Interior.ColorIndex = 3
               For y = x - 间隔 To LBound(arr) Step -间隔
                   Range("a" & y).Interior.ColorIndex = 6
                  If Cells(y, 1) <= temp Then Exit For
                  Cells(y + 间隔, 1) = Cells(y, 1)
                      k1 = k1 + 1
               Next y
               Cells(y + 间隔, 1) = temp
               Range("a1:a30").Interior.ColorIndex = xlNone
              Next x
             间隔 = 间隔  3
            Loop
                MsgBox k1
                Range("e3").Resize(5000) = ""
                 Range("d1").Resize(UBound(arr)) = arr
                Range("e2") = Timer - t
         End Sub
    

    5.选择排序

         Sub 选择排序()
           Dim arr, temp, x, y, t, iMax, k, k1, k2
           t = Timer
           arr = Range("a1:a10")
           For x = UBound(arr) To 1 + 1 Step -1
              iMax = 1     最大的索引
              For y = 1 To x
                   If arr(y, 1) > arr(iMax, 1) Then iMax = y
              Next y
              temp = arr(iMax, 1)
              arr(iMax, 1) = arr(x, 1)
              arr(x, 1) = temp
           Next x  
               Range("c3").Resize(UBound(arr)) = ""
               Range("c3").Resize(UBound(arr)) = arr
               Range("c2") = Timer - t
               MsgBox k1
         End Sub
    
         Sub 选择排序单元格演示()
           Dim arr, temp, x, y, t, iMax, k, k1, k2
           For x = 10 To 2 Step -1
              iMax = 1
                                Range("a" & x).Interior.ColorIndex = 3
              For y = 1 To x
                                Range("a" & y).Interior.ColorIndex = 4
                   If Cells(y, 1) > Cells(iMax, 1) Then
                                Range("a" & iMax).Interior.ColorIndex = xlNone
                    iMax = y
                   End If
                                Range("a" & y).Interior.ColorIndex = xlNone
                                Range("a" & iMax).Interior.ColorIndex = 6                       
              Next y
              temp = Cells(iMax, 1)
              Cells(iMax, 1) = Cells(x, 1)
              Cells(x, 1) = temp
              Range("a" & x).Interior.ColorIndex = xlNone
              Range("a" & iMax).Interior.ColorIndex = xlNone
           Next x
         End Sub
    

    <br />


    <br />

    CH9 VBA字典

    一、基本概念

    1 什么是VBA字典?
    字典(dictionary)是一个储存数据的小仓库。共有两列。
    第一列叫key , 不允许有重复的元素。
    第二列是item,每一个key对应一个item,本列允许为重复
    Key item
    A 10
    B 20
    C 30
    Z 10

    2 即然有数组,为什么还要学字典?
    原因:提速,具体表现在
    1) A列只能装入非重复的元素,利用这个特点可以很方便的提取不重复的值
    2) 每一个key对应一个唯一的item,只要指点key的值,就可以马上返回其对应的item,利用字典可以实现快速的查找

    3 字典有什么局限?
    字典只有两列,如果要处理多列的数据,还需要通过字符串的组合和拆分来实现。
    字典调用会耗费一定时间,如果是数据量不大,字典的优势就无法体现出来。

    4 字典在哪里?如何创建字典?
    字典是由scrrun.dll链接库提供的,要调用字典有两种方法
    第一种方法:直接创建法
    Set d = CreateObject("scripting.dictionary")
    第二种方法:引用法
    工具-引用-浏览-找到scrrun.dll-确定

    二、VBA字典的使用

    1 装入数据

    Sub t1()
      Dim d As New Dictionary
      Dim x As Integer
      For x = 2 To 4
       d.Add Cells(x, 1).Value, Cells(x, 2).Value
      Next x
      MsgBox d.Keys(1)
          Stop
    End Sub
    

    2 读取数据

    Sub t2()
      Dim d
      Dim arr
      Dim x As Integer
      Set d = CreateObject("scripting.dictionary")
      For x = 2 To 4
       d.Add Cells(x, 1).Value, Cells(x, 2).Value
      Next x
          MsgBox d("李四")
          MsgBox d.Keys(2)
      Range("d1").Resize(d.Count) = Application.Transpose(d.Keys)
      Range("e1").Resize(d.Count) = Application.Transpose(d.Items)
      arr = d.Items
    End Sub
    

    3 修改数据

    Sub t3()
      Dim d As New Dictionary
      Dim x As Integer
      For x = 2 To 4
       d.Add Cells(x, 1).Value, Cells(x, 2).Value
      Next x
      d("李四") = 78
      MsgBox d("李四")
      d("赵六") = 100
      MsgBox d("赵六")
    End Sub
    

    4 删除数据

    Sub t4()
      Dim d As New Dictionary
      Dim x As Integer
      For x = 2 To 4
        d(Cells(x, 1).Value) = Cells(x, 2).Value
      Next x
       d.Remove "李四"
          MsgBox d.Exists("李四")
      d.RemoveAll
      MsgBox d.Count
    End Sub
    

    5.区分大小写

    Sub t5()
      Dim d As New Dictionary
      Dim x
      For x = 1 To 5
        d(Cells(x, 1).Value) = ""
      Next x
      Stop
    End Sub
    

    三、字典与查找

         Sub 多表双向查找()
          Dim d As New Dictionary
          Dim x, y
          Dim arr
          For x = 3 To 5
            arr = Sheets(x).Range("a2").Resize(Sheets(x).Range("a65536").End(xlUp).Row - 1, 2)
            For y = 1 To UBound(arr)
              d(arr(y, 1)) = arr(y, 2)
              d(arr(y, 2)) = arr(y, 1)
            Next y
          Next x
          MsgBox d("C1")
          MsgBox d("吴情")
         End Sub
    

    四、字典与求和

          Dim d As New Dictionary
          Dim arr, x
          arr = Range("a2:b10")
          For x = 1 To UBound(arr)
            d(arr(x, 1)) = d(arr(x, 1)) + arr(x, 2) 'key对应的item的值在原来的基础上加新的
          Next x
          Range("d2").Resize(d.Count) = Application.Transpose(d.Keys)
          Range("e2").Resize(d.Count) = Application.Transpose(d.Items)
         End Sub
    

    五、字典与唯一值

         Sub 提取不重复的产品()
          Dim d As New Dictionary
          Dim arr, x
          arr = Range("a2:a12")
          For x = 1 To UBound(arr)
               d(arr(x, 1)) = ""
          Next x
          Range("c2").Resize(d.Count) = Application.Transpose(d.Keys)
         End Sub
    

    六、字典综合算法

    1.多列汇总

         Sub 下棋法之多列汇总()
          Dim 棋盘(1 To 10000, 1 To 3)
          Dim 行数
          Dim arr, x, k
          Dim d As New Dictionary
          arr = Range("a2:c" & Range("a65536").End(xlUp).Row)
          For x = 1 To UBound(arr)
            If d.Exists(arr(x, 1)) Then
               行数 = d(arr(x, 1))
               棋盘(行数, 2) = 棋盘(行数, 2) + arr(x, 2)
               棋盘(行数, 3) = 棋盘(行数, 3) + arr(x, 3)
            Else
               k = k + 1
               d(arr(x, 1)) = k
               棋盘(k, 1) = arr(x, 1)
               棋盘(k, 2) = arr(x, 2)
               棋盘(k, 3) = arr(x, 3)
            End If
          Next x
          Range("f2").Resize(k, 3) = 棋盘
         End Sub
    

    2.多条件多列汇总

         Sub 下棋法之多条件多列汇总()
          Dim 棋盘(1 To 10000, 1 To 4)
          Dim 行数
          Dim arr, x As Integer, sr As String, k As Integer
          Dim d As New Dictionary
          arr = Range("a2:d" & Range("a65536").End(xlUp).Row)
          For x = 1 To UBound(arr)
             sr = arr(x, 1) & "-" & arr(x, 2)
             If d.Exists(sr) Then
               行数 = d(sr)
               棋盘(行数, 3) = 棋盘(行数, 3) + arr(x, 3)
               棋盘(行数, 4) = 棋盘(行数, 4) + arr(x, 4)
             Else
               k = k + 1
               d(sr) = k
               棋盘(k, 1) = arr(x, 1)
               棋盘(k, 2) = arr(x, 2)
               棋盘(k, 3) = arr(x, 3)
               棋盘(k, 4) = arr(x, 4)
             End If
          Next x
            Range("g2").Resize(k, 4) = 棋盘
         End Sub
    

    3.数据透视表式汇总

         Sub 下棋法之数据透视表式汇总()
          Dim d As New Dictionary
          Dim 棋盘(1 To 10000, 1 To 7)
          Dim 行数, 列数
          Dim arr, x, k 
          arr = Range("a2:c" & Range("a65536").End(xlUp).Row) 
          For x = 1 To UBound(arr)
            列数 = (InStr("1月2月3月4月5月6月", arr(x, 2)) + 1) / 2 + 1
            If d.Exists(arr(x, 1)) Then
               行数 = d(arr(x, 1))      
               棋盘(行数, 列数) = 棋盘(行数, 列数) + arr(x, 3)
            Else
               k = k + 1
               d(arr(x, 1)) = k
               棋盘(k, 1) = arr(x, 1)
               棋盘(k, 列数) = arr(x, 3)
            End If
          Next x 
          Range("f2").Resize(k, 7) = 棋盘
         End Sub




  • 相关阅读:
    c语言结构体数组引用
    c语言结构体数组定义的三种方式
    如何为SAP WebIDE开发扩展(Extension),并部署到SAP云平台上
    SAP SRM ABAP Webdynpro和CFCA usb key集成的一个原型开发
    使用SAP API portal进行SAP SuccessFactors的API测试
    SAP UI5应用里的页面路由处理
    在SAP WebIDE Database Explorer里操作hdi实例
    如何使用SAP事务码SAT进行UI应用的性能分析
    使用SAP WebIDE进行SAP Cloud Platform Business Application开发
    SAP CRM WebClient UI ON_NEW_FOCUS的用途
  • 原文地址:https://www.cnblogs.com/plyc/p/14613661.html
Copyright © 2011-2022 走看看