精华内容
下载资源
问答
  • 定义方式 dim arr11 (5) dim arr12 (0 to 5 ) dim arr13 (1 to 5) dim arr21(1,5) dim arr22(0 to 1 ,0 to 5) dim arr22(1 to 1 ,1 to 5) dim arr3() 静态数组 dim arr51(5) ...redim arr61(13) r...

     

    定义方式
    dim  arr11 (5)
    dim  arr12 (0 to 5 )
    dim  arr13 (1 to 5)

    dim arr21(1,5)
    dim arr22(0 to 1 ,0 to 5)
    dim arr22(1 to 1 ,1 to 5)

    dim arr3()


    静态数组
    dim  arr51(5)

    动态数组
    dim arr61()
    redim arr61(13)
    redim arr61(20)
    redim arr61(j)
    redim arr61(1 to k)


    dim arr71()
    redim preserve  arr71( 1 to 10)

    dim arr81()
    arr81(0)=1
    redim preserve  arr81( 1 to 10)


    dim arr91()
    arr91(1)=2
    redim preserve  arr91( 1 to 10)
     

     

    数组的定义方式的差别

    • Dim arr1 As Range         '定义为excel对象,arr1是对象名。range是EXCEL的对象,cells也是
    •                                         '并且这样的数组一定是 2维数组
    • Dim arr2                          '定义变量,arr2是变量名
    •                                         '变量最灵活,变量可以被 对象赋值,也可以被数组直接赋值  
    • Dim arr3()                        '定义为数组,arr3是数组名
    •                                         '而且这是动态数组,index默认了从0开始
    •                                         ' 动态数组才配合用 redim ,静态数组不需要
    •                                         ' 动态数组只能改变最后1个维度
    • dim  arr4(5)                      '这是静态数组,静态数组不需要redim

     

    数组定义与数组个数

    • dim arr1(5)                                        'index是 0,1,2,3,4,5,共6个index
    • dim arr1(1 to 5)                                 'index是 1,2,3,4,5,共5个index
    • option base 2   dim arr1(5)               'index是 2,3,4,5,共4个index

     

    什么时候用redim 和 preserve

    • 数组先被定义为了 动态数组 dim arr1()
    • 后面可以重新定义 redim arr1(k)
    • 可以进行多次redim
    • 如果下次redim想 保留之前 arr1里的数据,则需要写 redim preserve arr1(k) 
    • 容易出错的地方 redim preserve arr1(1 to k)往往会报错,越界,因为之前index从0开始,无法匹配preserve
    • 代码中使用了ReDim Preserve语句,出现类型不匹配? 多半是因为在声明变量时写成了arr,而非arr()

    举例子

    • 如果要用 redim perserve arr1() ,那需要arr1先别定义为动态数组 dim arr1(), 只是定义为变量时不行的 dim arr1
    • 实际上这段代码不需要preserve!!用来语法举例,
    Sub ponyma_array2()
    Dim arr1()  '当数组定义,且默认开始的index为0! preserve时需要有0的index
    'dim arr1 当变量定义
    
    'Application.WorksheetFunction.CountA (Range("c:c"))
    'Debug.Print Application.WorksheetFunction.CountA("c:c")
    '这种counta只会把"a:a"当成1个字符串,不知道是对象1列,只会统计出1
    
       k = 1
       m = 1
       
       ReDim  preserve arr1(0 To Application.WorksheetFunction.CountA(Range("c:c")))
    ' 下标越界  ReDim  preserve arr1(1 To Application.WorksheetFunction.CountA(Range("c:c")))
          
    '   Debug.Print Application.WorksheetFunction.CountA(Range("c:c"))
    '   Debug.Print Range("c65536").End(xlUp).Row
    
       For i = 1 To Range("c65536").End(xlUp).Row Step 1
           If Cells(i, 3) <> "" Then
         
              Debug.Print Cells(i, 3)
              arr1(k) = Cells(i, 3)
              Debug.Print arr1(k)
              k = k + 1
    '          Debug.Print arr1(k),写在这里问题1:k已经变了,下一个k还没赋值为空,2最后的k越界
    '          循环是很精巧的,放的地方很讲究,放得不对,就错误百出
             
           End If
       Next i
       
       For j = 1 To UBound(arr1, 1)
           Cells(m, 10) = arr1(j)
           m = m + 1
       Next j
    
    End Sub

     

    数组的边界

    • 一维数组边界
    • lbound (arr1,1)  或 lbound (arr1)     下边界
    • ubound(arr1,1)  或 ubound(arr1)     上边界
    •  
    •  
    • 二维数组边界
    • lbound(arr1,1)          第1维的下边界,excel里的最小行数
    • ubound(arr1,1)         第1维的上边界,excel里的最大行数
    • lbound(arr1,2)          第2维的下边界,excel里的最小列数
    • ubound(arr1,2)         第2维的上边界,excel里的最大行数

     

    数组的赋值

     

     

     

     

     

    https://blog.csdn.net/weixin_42832348/article/details/81430634

     

    https://zhidao.baidu.com/question/525808449407658485.html

     

    如果要保留值改变数组的大小,只能修改数组的最后一维大小。
    类型不匹配是因为re没有声明,你改成dim re()

    http://www.excelpx.com/thread-322210-1-1.html

    1. Sub aa()
    2.     Dim arr, x, aa, bb, xx, cc, d, s
    3.     Dim re()  '下面需要重新定义数组,所以开始要先定义re为一个数组
    4.     arr3 = Range("x5").CurrentRegion.Value
    5.     'x5 的区域都是非空数值
    6.     ReDim re(1 To UBound(arr3) * 8, 1 To 1) '因为重新定义了数组,所以数组是空的
    7.     '如果重新定义前,数组赋值过,REDIM 后也会把数组清空的
    8.     '如果数组赋值过,REDIM 时还要保留源数据,需要加上 Preserve关键字
    9.     '写法  ReDim Preserve re(1 To UBound(arr3) * 8, 1 To 1)
    10.     '新数组re赋值,可以使用循环的方法进行赋值
    11.    
    12.     MsgBox re(6, 1)
    13.     For i = 1 To UBound(arr3)
    14.         For ii = 1 To 8
    15.             Cells(i, ii) = re(i, 1)
    16.         Next
    17.     Next
    18. End Sub

     

    VBA只能动态修改数组最后一维的大小

    Sub text()
    Dim arr(), i As Integer, j As Integer
    Dim brr
    i = Sheet2.Range("k65536").End(xlUp).Row
    brr = Sheet2.Range("a1:k" & i)
      For i = 2 To UBound(brr)
        If brr(i, 11) = 2 Then
            j = j + 1
            ReDim Preserve arr(1 To 11, 1 To j)
            For r = 1 To 11
                arr(r, j) = brr(i, r)
            Next
        End If
    Next
    Sheets("表2").Range("a18").Resize(UBound(arr, 2), UBound(arr)) = Application.Transpose(arr)
    End Sub

     

     

     

     

    dim arr(1 to 3 ) as string

    dim arr() as variant

     

     

    redim arr(1)

    arr=Array("a","b","c")

     

    动态数组

    k=0

    redim arr(1 to k) 

    k=k+1

     


     

     

    Sub jackma101()
    '尝试每个txt导入为1行,或1个sheet----往数组里append 不会!,只会用cells()=存起来文件名
    
    x1 = input_files1("C:\Users\Administrator\Desktop\test1", "\*.txt")
    'x1 = input_files1("C:\Users\Administrator\Desktop", "\*.txt")
    'debug.print input_files1("C:\Users\Administrator\Desktop", "\*.txt")
    
    
    End Sub
    
    
    
    Function input_files1(PATH1, PATH2)
    '取文件数量
    '取文件名
    Dim arr1()
    
    
    k = 0
    file1 = Dir(PATH1 & PATH2)
    Debug.Print file1
    arr1(k) = file1
    
    
    Do Until Len(file1) = 0
    
    
       file1 = Dir
       k = k + 1
       arr1(k) = file1
          
       Debug.Print file1
       Debug.Print k
       
    Loop
    
    Debug.Print "sum= " & k
    
    End Function
    
    
    
    
    

     

    数组里辅助了

    取出来为啥是空?

    Sub jackma101()
    '尝试每个txt导入为1行,或1个sheet
    
    x1 = input_files1("C:\Users\Administrator\Desktop\test1", "\*.txt")
    'x1 = input_files1("C:\Users\Administrator\Desktop", "\*.txt")
    'debug.print input_files1("C:\Users\Administrator\Desktop", "\*.txt")
    
    
    
    
    
    
    
    
    End Sub
    
    Function input_files1(PATH1, PATH2)
    '取文件数量
    '取文件名
    Dim arr1()
    
    
    file1 = Dir(PATH1 & PATH2)
    k = 0
    
    Debug.Print file1
    Debug.Print k
    
    
    Do Until Len(file1) = 0
       file1 = Dir
       k = k + 1
    
        ReDim arr1(1 To k)
        arr1(k) = file1
        
       Debug.Print "arr(K)=" & arr1(k)
       Debug.Print file1
       Debug.Print k
    
    Loop
    Debug.Print "sum= " & k
    
    
    
    For i = LBound(arr1, 1) To UBound(arr1, 1)
        Debug.Print arr1(i) & "?"
    Next i
    
    
    End Function
    

     

    Sub jackma101()
    '尝试每个txt导入为1行,或1个sheet
    
    x1 = input_files1("C:\Users\Administrator\Desktop\test1", "\*.txt")
    'x1 = input_files1("C:\Users\Administrator\Desktop", "\*.txt")
    'debug.print input_files1("C:\Users\Administrator\Desktop", "\*.txt")
    
    
    
    
    
    
    
    
    End Sub
    
    Function input_files1(PATH1, PATH2)
    '取文件数量
    '取文件名
    Dim arr1()
    
    
    file1 = Dir(PATH1 & PATH2)
    k = 0
    
    Debug.Print file1
    Debug.Print k
    
    
    Do Until Len(file1) = 0
       file1 = Dir
       k = k + 1
    
        ReDim Preserve arr1(1 To k)
        arr1(k) = file1
        
       Debug.Print "arr(K)=" & arr1(k)
       Debug.Print file1
       Debug.Print k
    
    Loop
    Debug.Print "sum= " & k
    
    
    
    For i = LBound(arr1, 1) To UBound(arr1, 1)
        Debug.Print arr1(i) & "?"
    Next i
    
    
    End Function
    

     

     

    Sub jackma101()
    '尝试每个txt导入为1行,或1个sheet
    
    x1 = input_files1("C:\Users\Administrator\Desktop\test1", "\*.txt")
    'x1 = input_files1("C:\Users\Administrator\Desktop", "\*.txt")
    'debug.print input_files1("C:\Users\Administrator\Desktop", "\*.txt")
    
    
    End Sub
    
    Function input_files1(PATH1, PATH2)
    '取文件数量
    '取文件名
    Dim arr1()
    
    
    file1 = Dir(PATH1 & PATH2)
    k = 0
    
    ReDim arr1(1)
    arr1(0) = file1
    
    
    Do Until Len(file1) = 0
       file1 = Dir
       k = k + 1
    
        ReDim Preserve arr1(0 To k)
        arr1(k) = file1
        Debug.Print "arr(K)=" & arr1(k)
    
    Loop
    Debug.Print "sum= " & k
    
    
    
    
    
    For i = LBound(arr1, 1) To UBound(arr1, 1)
        Debug.Print arr1(i)
        
        Open PATH1 & "\" & arr1(i) For Input As #1
        Input #1, str1
    
    '    ActiveSheet.Cells(i, 1).Value = arr1(i)
    '    ActiveSheet.Cells(i, 2).Value = str1
        Close #1
        
        
    Next i
    
    

    3.3 先写入数组array中,再写到其他地方,据说这样能大幅提高速度!

    把需要的筛选的数据,存在数据,然后从数组写到需要的地方,这是个好习惯

    第1版

    
    
    Sub 删除空格4()
    Dim arr1()
    
    
    ReDim arr1(11)                      '必须重新定义,现在不太理解
    j = 0                               'j=1开始就会越界
    For i = 1 To 11 Step 1
       If Not IsEmpty(Cells(i, 1)) Then
          arr1(j) = Cells(i, 1)
          j = j + 1
       End If
    Next i
    
    
    For j = 0 To UBound(arr1())
        Cells(j + 1, 9) = arr1(j)      '单元格得从1开始,arr()得从0开始
    Next j
    
    
    End Sub
    

    第2版重写

    • 要注意的问题
    • 1 定义数组arr1() 实际已经定义了index为0
    • 2 现在还不明白为啥这次redim 需要加 preseve?
    • 3 使用VBA函数,如countA时,不能像在EXCEL表公式里  countA("c:c") 这是countA  一个字符串
    • 必须用 countA(range("c:c"))  这才表示引用的excel对象
    • debug.print用来监测的时候,需要注意,放在循环的位置,尤其是在k=K+1这种变化时,和放在哪个for循环之内外!
    Sub ponyma_array2()
    Dim arr1()  '当数组定义,且默认开始的index为0! preserve时需要有0的index
    'dim arr1 当变量定义
    
    
    k = 1
    m = 1
    
    'Application.WorksheetFunction.CountA (Range("c:c"))
    'Debug.Print Application.WorksheetFunction.CountA("c:c")
    '这种counta只会把"a:a"当成1个字符串,不知道是对象1列,只会统计出1
    
    
    ReDim Preserve arr1(0 To Application.WorksheetFunction.CountA(Range("c:c")))
    ' 下标越界  ReDim Preserve arr1(1 To Application.WorksheetFunction.CountA(Range("c:c")))
    
    
       For i = 1 To Range("c65536").End(xlUp).Row Step 1
           If Cells(i, 3) <> "" Then
         
              Debug.Print Cells(i, 3)
              arr1(k) = Cells(i, 3)
              Debug.Print arr1(k)
              k = k + 1
    '          Debug.Print arr1(k),写在这里问题1:k已经变了,下一个k还没赋值为空,2最后的k越界
    '          循环是很精巧的,放的地方很讲究,放得不对,就错误百出
             
           End If
       Next i
       
       For j = 1 To UBound(arr1, 1)
           Cells(m, 10) = arr1(j)
           m = m + 1
       Next j
    
    End Sub

    第3版

    Option Explicit
    
    Sub ponyma1()
    
    
    Dim arr1()
    Dim k1, k2, k
    Dim i, j
    k1 = WorksheetFunction.CountA(Range("a:a"))
    k2 = Range("a65536").End(xlUp).Row
    Debug.Print "这列非空数据个数k1=" & k1
    Debug.Print "这列最后1个有数据的行数k2=" & k2
    
    
    'arr1(0) = 1
    'ReDim Preserve arr1(1, k)
    '这样会越界,因为你需要preserve数据。但是index系不符合
    '但是,如果不preserve 就无所谓
    '或者虽然 dim arr1() 是动态数据从index0开始,但是arr1()一直为空,preserve也不会出现index越界问题
    
    ReDim Preserve arr1(1 To k1)
    'ReDim Preserve arr1(1, k1) 这样就会越界。。。因为语法是2维数组了!
    'ReDim Preserve arr1(1 to k1) 这样就对的
    
    k = 1
    For i = 1 To k2
       If Cells(i, 1) <> "" Then
          arr1(k) = Cells(i, 1)
          Debug.Print arr1(k)
          k = k + 1
       End If
    Next i
    展开全文
  • VBA关于数组Dim,ReDim Preserve运行速度对比思考如何插入一段漂亮的代码片 以前看教程经常有人说ReDim Preserve动态定义数组运行速度非常慢,特做测试分析是否真的想网友说的ReDim Preserve真的不堪重用 经测试得出...

    VBA关于数组Dim,ReDim Preserve运行速度对比思考

    以前看教程经常有人说ReDim Preserve动态定义数组运行速度非常慢,特做测试分析是否真的想网友说的ReDim Preserve真的不堪重用
    经测试得出一下结论:
    1 、ReDim Preserve的速度快慢对redim的次数比较敏感。
    循环100万次,10万次,1万次,对单元格赋值,dim数组,用字典的count次数定义数组维度,及ReDim Preserve动态定义数组,运行时间如下:
    在这里插入图片描述
    大家会发现动态数组运行起来每增加10倍次数,时间却增加100倍,
    但是如果是for i = 1000000 to 1 step -1时,100W次也就2秒左右,
    综上所述,直接定义一个较大维度的数组写代码比较简单,速度也能接受,但是10W次一次的循环直接ReDim Preserve也可以接受
    先赋值给字典,然后用字典的count计数再定义字典,写起来稍微麻烦,但速度快。
    测试代码如下:

    如何插入一段漂亮的代码片

    博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

    // An highlighted block
    Sub 测试用时()
    Dim n&, i&, sr$, A$, B$, C$, Mypath$, brr()
    Application.ScreenUpdating = False
    Rem 单元格操作用时
    iRow = 10000
    Range("A1:D" & iRow).ClearContents
    t = Timer
    Mypath = "C:\Users\DDN\Desktop\test\*.*"
    For i = 1 To iRow
        Cells(i, 1) = i
        Cells(i, 2) = i * 2
        Cells(i, 3) = i * 4
        Cells(i, 4) = i * 6
    Next
    [G1].Value = Format(Timer - t, "0.00")
    i = 0
    
    
    Rem 数组操作用时定义一个很大维度
    Range("A1:D" & iRow).ClearContents
    t = Timer
    Dim arr(1 To 10000, 1 To 4)
    For i = 1 To iRow
        arr(i, 1) = i '序号
        arr(i, 2) = i * 2
        arr(i, 3) = i * 4
        arr(i, 4) = i * 6
    Next
    Range("A1").Resize(UBound(arr, 1), UBound(arr, 2)) = arr
    [G2].Value = Format(Timer - t, "0.00")
    i = 0
    
    
    Rem 用字典count重定义数组维度
    Range("A1:D" & iRow).ClearContents
    t = Timer
    Set Mydic = CreateObject("Scripting.Dictionary") '创建一个字典放结果
    For i = 1 To iRow
            A = i * 2
            B = i * 4
            C = i * 6
            Mydic(n) = A & "|" & B & "|" & C
    Next
    i = 0
    ReDim myarr(1 To Mydic.Count, 1 To 4)
    For i = 1 To Mydic.Count
        myarr(i, 1) = i
        myarr(i, 2) = Split(Mydic(n), "|")(0)
        myarr(i, 3) = Split(Mydic(n), "|")(1)
        myarr(i, 4) = Split(Mydic(n), "|")(2)
    Next
    Range("A1").Resize(UBound(myarr), UBound(myarr, 2)) = myarr
    [G3].Value = Format(Timer - t, "0.00")
    i = 0
    
    
    Rem ReDim Preserve arr
    Range("A1:D" & iRow).ClearContents
    t = Timer
    For i = 1 To iRow
            ReDim Preserve brr(1 To 4, 1 To i)
            brr(1, i) = i
            brr(2, i) = i * 2
            brr(3, i) = i * 4
            brr(4, i) = i * 6
    Next
    Range("A1").Resize(i, 4) = Application.Transpose(brr)
    [G4].Value = Format(Timer - t, "0.00")
    Application.ScreenUpdating = True
    End Sub
    
    
    
    
    
    
    
    
    
    
    
    VBA关于数组Dim,ReDim Preserve运行速度对比思考
    如何插入一段漂亮的代码片
    以前看教程经常有人说ReDim Preserve动态定义数组运行速度非常慢,特做测试分析是否真的想网友说的ReDim Preserve真的不堪重用
    经测试得出一下结论:
    1 、ReDim Preserve的速度快慢对redim的次数比较敏感。
    循环100万次,10万次,1万次,对单元格赋值,dim数组,用字典的count次数定义数组维度,及ReDim Preserve动态定义数组,运行时间如下:
    在这里插入图片描述
    大家会发现动态数组运行起来每增加10倍次数,时间却增加100倍,
    但是如果是for i = 1000000 to 1 step -1时,100W次也就2秒左右,
    综上所述,直接定义一个较大维度的数组写代码比较简单,速度也能接受,但是10W次一次的循环直接ReDim Preserve也可以接受
    先赋值给字典,然后用字典的count计数再定义字典,写起来稍微麻烦,但速度快。
    测试代码如下:
    
    如何插入一段漂亮的代码片
    去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.
    
    // An highlighted block
    Sub 测试用时()
    Dim n&, i&, sr$, A$, B$, C$, Mypath$, brr()
    Application.ScreenUpdating = False
    Rem 单元格操作用时
    iRow = 10000
    Range("A1:D" & iRow).ClearContents
    t = Timer
    Mypath = "C:\Users\DDN\Desktop\test\*.*"
    For i = 1 To iRow
        Cells(i, 1) = i
        Cells(i, 2) = i * 2
        Cells(i, 3) = i * 4
        Cells(i, 4) = i * 6
    Next
    [G1].Value = Format(Timer - t, "0.00")
    i = 0
    
    
    Rem 数组操作用时定义一个很大维度
    Range("A1:D" & iRow).ClearContents
    t = Timer
    Dim arr(1 To 10000, 1 To 4)
    For i = 1 To iRow
        arr(i, 1) = i '序号
        arr(i, 2) = i * 2
        arr(i, 3) = i * 4
        arr(i, 4) = i * 6
    Next
    Range("A1").Resize(UBound(arr, 1), UBound(arr, 2)) = arr
    [G2].Value = Format(Timer - t, "0.00")
    i = 0
    
    
    Rem 用字典count重定义数组维度
    Range("A1:D" & iRow).ClearContents
    t = Timer
    Set Mydic = CreateObject("Scripting.Dictionary") '创建一个字典放结果
    For i = 1 To iRow
            A = i * 2
            B = i * 4
            C = i * 6
            Mydic(n) = A & "|" & B & "|" & C
    Next
    i = 0
    ReDim myarr(1 To Mydic.Count, 1 To 4)
    For i = 1 To Mydic.Count
        myarr(i, 1) = i
        myarr(i, 2) = Split(Mydic(n), "|")(0)
        myarr(i, 3) = Split(Mydic(n), "|")(1)
        myarr(i, 4) = Split(Mydic(n), "|")(2)
    Next
    Range("A1").Resize(UBound(myarr), UBound(myarr, 2)) = myarr
    [G3].Value = Format(Timer - t, "0.00")
    i = 0
    
    
    Rem ReDim Preserve arr
    Range("A1:D" & iRow).ClearContents
    t = Timer
    For i = 1 To iRow
            ReDim Preserve brr(1 To 4, 1 To i)
            brr(1, i) = i
            brr(2, i) = i * 2
            brr(3, i) = i * 4
            brr(4, i) = i * 6
    Next
    Range("A1").Resize(i, 4) = Application.Transpose(brr)
    [G4].Value = Format(Timer - t, "0.00")
    Application.ScreenUpdating = True
    End Sub
    
    
    
    
    
    
    
    
    
    
    
    Markdown 1794 字数 100 行数 当前行 13, 当前列 0 HTML 1685 字数 77 段落
    ×
    拖拽到此处
    图片将通过Fatkun完成下载
    
    展开全文
  • redim时只有最后1维可变化,redim不太适合和循环搭配,即使用 redim preserve也不行! 你装数据时一般都会有一个充当计数器的变量,这个变量最后的值就是数组中装入值的数量 一般是声明一个足够大的静态数组,或二次...

    1总结

    1.1 如何避免出错

    • 如果是想生成一个二维数组,最后用静态声明,或则二次声明redim 一个足够大的动态数组

     

    1.2 出错的原因是什么?

    • redim时只有最后1维可变化,redim不太适合和循环搭配,即使用 redim preserve也不行!
    • 你装数据时一般都会有一个充当计数器的变量,这个变量最后的值就是数组中装入值的数量
    • 一般是声明一个足够大的静态数组,或二次声明一个足够大的动态数组,
    • 动态的二维数组用redim 修改大小,切记第一维在第一次扩容的时候就定死了,以后只能修改第二维。
    • 再次扩容第二维的时候,记得加 preserve关键字,否则数组中的原有数据就会丢失。
    • 但是用 redim preserve 扩容的时候,又要注意,维度的数只能增加不能减少,所以不适合 for i=1 to 3 for j=1 to 3 这种循环套循环,因为j这个最后一维总是在循环从小变大,也会有变小重置的时候,就会出问题

     

    1.3 下面是详细的试错过程

     

     

    2 如果二维数组定义为静态数组,生成数组和生成后打印数组内容,都很方便

    Sub test901()
    '如果二维数组,定义为静态数组,生成数组 和 生成后打印数组内容,都很方便
    Dim arr1(3, 3)
    
    For I = 0 To 3
       For J = 0 To 3
           arr1(I, J) = I * J
           Debug.Print "arr1(" & I & "," & J & ")= " & arr1(I, J) & "  ";
       Next
       Debug.Print
    Next
    Debug.Print
    
    
    For I = LBound(arr1) To UBound(arr1)
        For J = LBound(arr1, 2) To UBound(arr1, 2)
            Debug.Print "arr1(" & I & "," & J & ")= " & arr1(I, J) & "  ";
        Next
        Debug.Print
    Next
    Debug.Print
    
    End Sub
    

     

     

     

    3  如果定义二维数组,是动态数组,但redim时,一次定位到足够大/或准确大小

     

    
    Sub test902()
    '如果定义二维数组,是动态数组,但redim时,一次定位到足够大/或准确大小,也没问题,比较清晰
    
    Dim arr2()
    ReDim arr2(3, 3)
    For I = 0 To 3
       For J = 0 To 3
           arr2(I, J) = I * J
           Debug.Print "arr2(" & I & "," & J & ")= " & arr2(I, J) & "  ";
       Next
       Debug.Print
    Next
    Debug.Print
    
    
    For I = LBound(arr2) To UBound(arr2)
        For J = LBound(arr2, 2) To UBound(arr2, 2)
            Debug.Print "arr2(" & I & "," & J & ")= " & arr2(I, J) & "  ";
        Next
        Debug.Print
    Next
    Debug.Print
    
    
    End Sub
    
    

     

    4 如果定义一个二维数组为动态数组,但又在循环时赋值,redim不适合这么动态变量 redim,容易出现下面的问题

    • 动态数组用redim,比如redim arr4(i,j)
    • 因为 i ,j  都在循环就会各种出问题
    • 用 redim arr4(i,j) 必出现越界问题,  因为非最后一维,i  这一维在redim 时是不能变得
    • 用 redim preserve 也容易出现越界问题,(因为 redim preserve 需要后面得数组空间比之前的大,而循环时很容易出现变小不匹配)
    
    Sub test903()
    '如果定义一个二维数组为动态数组,但又在循环时赋值,redim不适合这么动态变量 redim,容易出现下面的问题
    
    
    Dim arr4()
    For I = 0 To 3
       For J = 0 To 3
    '        ReDim Preserve arr4(I, J)
            ReDim arr4(I, J)
            arr4(I, J) = I * J
            Debug.Print "arr4(" & I & "," & J & ")= " & arr4(I, J) & " ";
       Next J
       Debug.Print
    Next I
    Debug.Print
    
    
    For I = LBound(arr4) To UBound(arr4)
        For J = LBound(arr4, 2) To UBound(arr4, 2)
            Debug.Print "arr4(" & I & "," & J & ")= " & arr4(I, J) & " ";
        Next
        Debug.Print
    Next
    
    
    End Sub

     

     

    5  为什么 动态redim 二维数组会有问题?原因是

    • 需要理解arr4(1 To 3, 1 To J)中arr(1 to 4, ) 其实是固定数组,一次性一步!把维度展开了,而不是逐步展开
    • 动态数组,redim时,数组的非最后1维不能变化,变了直接报错越界
    • 动态数组,redim时,数组的最后1维也只能从小变大,如循环后又从大变小会出问题,会把之前内容redim后抹掉
    • --------所以循环不太适合redim
    • 但这时候preserve也不行,还是因为如果最后一维因为循环从大到小后,会导致preserve出错(因为preserve必须后面得包含前面的,不能变小)

     

    • 本质在于 redim 和循环 不匹配的问题!
    • 对比
    • 为什么生成数组,同时debug.print 数组内容没问题,但是数组生成完成后,显示数组内容反而有错?
    • 就是因为 for j = 1 to 3 这个二维数组的第2维的循环,redim从1到3,再次从1到3。导致之前的数组的元素被抹掉!
    Sub test603()
    '二维数组,动态redim
    '需要理解arr4(1 To 3, 1 To J)中arr(1 to 4, ) 其实是固定数组,一次性一步!把维度展开了,而不是逐步展开
    
    
    
    Dim arr4()
    For I = 1 To 3
       For J = 1 To 3
    '      ReDim Preserve arr4(I, J)              '错在没注意起始下标应该从1开始
    '      ReDim Preserve arr4(1 To I, 1 To J)    '越界错误,因为preserve了,但是j又减小这种循环不适合
    '      ReDim arr4(1 To I, 1 To J)             '虽然不pre不会越界,但之前的值会被抹去
            ReDim Preserve arr4(1 To 3, 1 To J)   'vba的二维数组,只支持最后1维变大小,其他维不能变否则显示越界,j作为维度之一,只能单向变大,不应该变小的'
            arr4(I, J) = I * J                     '可在这里设置断点,添加监视变量,监视arr4
       Next J
    Next I
    
    
    For I = LBound(arr4) To UBound(arr4)
        For J = LBound(arr4, 2) To UBound(arr4, 2)
            Debug.Print "arr4(" & I & "," & J & ")= " & arr4(I, J) & " ";
        Next
        Debug.Print
    Next
    Debug.Print
    
    
    '总结
    '数组的非最后1维不能变化,变了直接报错越界
    '数组的最后1维也只能从小变大,如循环后,又从大变小会出问题,会把之前内容redim后抹掉
    '但preserve也不行,还是因为如果最后一维因为循环从大到小后,会导致preserve出错(因为preserve必须后面得包含前面的,不能变小)
    
    
    
    End Sub

     

     

     

     

    展开全文
  • VBA学习笔记之随机数&数组redim

    千次阅读 2019-09-26 00:36:27
    关于二维数组Redim Preserve: 如果使用了Preserve关键字,就只能重定义数组最末维的大小,且根本不能改变维数的数目。 具体参考 1 如果使用了 Preserve 关键字,就只能重定义数组最末维的大小,且根本不能...

    发现更简单的:

    a=Application.RandBetween(-10, 10)

    直接生成-10到10之间的随机整数

    关于二维数组Redim Preserve:

    如果使用了 Preserve 关键字,就只能重定义数组最末维的大小,且根本不能改变维数的数目。

    具体参考

     1 如果使用了 Preserve 关键字,就只能重定义数组最末维的大小,且根本不能改变维数的数目。例如,如果数组就是一维的,则可以重定义该维的大小,因为它是最末维,也是仅有的一维。不过,如果数组是二维或更多维时,则只有改变其最末维才能同时仍保留数组中的内容。下面的示例介绍了如何在为已有的动态数组增加其最末维大小的同时而不清除其中所含的任何数据。
     2 
     3 ReDim X(10, 10, 10)
     4 . . .
     5 ReDim Preserve X(10, 10, 15)
     6 
     7 同样地,在使用 Preserve 时,只能通过改变上界来改变数组的大小;改变下界则会导致错误。
     8 
     9 如果将数组改小,则被删除的元素中的数据就会丢失。如果按地址将数组传递给某个过程,那么不要在该过程内重定义该数组的各维的大小。
    10 
    11 在初始化变量时,数值变量被初始化为 0,变长的字符串被初始化为一个零长度的字符串 (""),而定长的字符串则用 0 填充。Variant 变量被初始化为 Empty。用户自定义类型的变量的每个元素作为各自独立的变量进行初始化。在使用引用对象的变量之前,必须使用 Set 语句将一个已有的对象赋给该变量。在被赋值之前,所声明的对象变量有一个特定值 Nothing,这个值表示该变量没有指向任何对象的实例。
    12 
    13 小心 如果 ReDim 语句所使用的变量在模块级别或过程级别不存在,则该语句就相当于一个声明语句。如果此后在一个更广的范围内又创建了同名的变量,即使使用了 Option ExplicitReDim 也将使用后声明的这个变量,且不会导致编译错误。为了避免这种冲突,就不应把 ReDim 作为声明语句使用,而只应作为重定义数组大小的语句。
    14 
    15 注意 要改变 Variant 所包含的数组的大小,必须在试图改变其数组大小之前显式声明该 Variant 变量。

     

    本来下面的例子想用Redim Preserve,后来意识到根本用不到,就当顺便学习下二维数组的redim了(/ □ \)

    '生成随机数
    Sub test() Dim a(10, 2)'本来想这样写  Dim a(),然后for循环里redim preserve a(i,2),发现不太对,a(i,1)怎么办? For i = 1 To 10 upperbound = 1 lowerbound = 100 a(i, 1) = Int((upperbound - lowerbound + 1) * Rnd + lowerbound) '@1 a(i, 2) = Application.RandBetween(1, 100) '@2 Cells(i, 1) = a(i, 1) Cells(i, 4) = a(i, 2) Next End Sub '可以看到@1和@2代码效果完全一样

      效果图:

     

     

     

     

     

     

     

     

    以下来自:http://blog.csdn.net/iamlaosong/article/details/38434179


     

    语法:Rnd[(number)]
      如果 number 的值是 Randomize 生成
      小于 0 ,每次都使用 number 作为随机数种子得到的相同结果。
      大于 0 ,以上一个随机数为种子产生下一个随机数。
      等于 0 ,产生与最近生成的随机数相同的随机数。
      省略, 以上一个随机数为种子产生下一个随机数(同大于0)。

    说明:
      Rnd 函数返回小于 1 但大于或等于 0 的值。
      number 的值决定了 Rnd 生成随机数的方式。
      对最初给定的种子都会生成相同的数列,因为每一次调用 Rnd 函数都用数列中的前一个数作为下一个数的种子。
      在调用 Rnd 之前,先使用无参数的 Randomize 语句初始化随机数生成器(若带参数,则产生由参数对应的一个特定序列的随机数),该生成器具有根据系统计时器得到的种子。如果不使用Randomize 语句,那么每次执行程序时产生的随机数序列是相同的。

      Rnd 后面跟一个负数时,同样的参数可以得到完全相同的两个序列,例如,rnd -1执行后用rnd取1000个随机数,然后再执行rnd -1,然后再用rnd取1000个随机数,这1000个随机数和前面1000个完全相同。为了得到不同的序列,可以用不同的负数,也可以在rnd -1后面执行Randomize number。注意,要得到相同的序列,两次Randomize后面的number必须相同。这种方法用途之一就是用于加密和解密。

      为了生成某个范围内的随机整数,可使用以下公式:
      Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
      这里,upperbound 是随机数范围的上限,而 lowerbound 则是随机数范围的下限。
      注意:若想得到重复的随机数序列,在使用具有数值参数的 Randomize 之前直接调用具有负参数值的 Rnd。使用具有同样 number 值的 Randomize 是不会得到重复的随机数序列的。

     

    ' 产生20个1-100之间的不重复随机数  
    Public Sub RndNumberNoRepeat1()  
          
        Dim RndNumber, temp(20), i, k, Maxrec As Integer  
          
        Randomize (Timer)           '初始化随机数生成器  
        Maxrec = 100  
          
          
        ' 从A21开始输出随机数  
        k = 0  
        Do While k < 20  
            RndNumber = Int(Maxrec * Rnd) + 1  
            temp(k) = RndNumber  
            Cells(k + 21, 1) = RndNumber  
            For i = 0 To k - 1  
                If temp(i) = RndNumber Then Exit For  
            Next i  
            If i = k Then k = i + 1  
            'MsgBox "随机数:" & RndNumber  
        Loop  
        
    End Sub  
    

      


     

     

    转载于:https://www.cnblogs.com/gilgamesh-hjb/p/7308692.html

    展开全文
  • eDim Preserve file_info(1 To i, 1 To 2) As String file_info(i, 1) = Filename file_info(i, 2) = Folderpath红色地方改成 ReDim Preserve file_info(1 To 2, 1 To i) As String file_info(...
  • 教程书上写到,当使用Redim去为动态数组指定上下界和纬度的时候如果不加Preserve参数,则重新定以后数组元素原来的值会被重置清空为empty。对此笔者特做了一个案例进行验证,代码如下: 第一次Redim,对动态...
  • VBA基础打卡

    2017-11-13 23:19:30
    vba
  • VB中preserve的用法

    万次阅读 2010-10-10 10:49:00
    <br />可以使用 ReDim 语句反复地改变数组的元素以及维数的数目,但是不能在将一个数组定义为某种数据类型之后,再使用 ReDim 将该数组改为其它数据类型,除非是 Variant 所包含的数组。如果该数组确实是包含...
  • 大家好,我们今日继续讲解VBA代码解决方案的第61讲内容:在VBA中如何使用动态数组,以及利用动态数组去除重复值的方法。在上一讲中我们讲了使用数组函数将单元格中的文本进行分隔后写入到工作表中的方法,那么问题...
  • Redim preserve

    2012-11-20 11:06:19
    数组是包含相同数据类型的一组变量的集合,对数组中的单个变量引用通过数组索引下标进行。在内存中表现为一个连续的内存块,必须用Global或Dim语句来定义。...除了以上固定数组外,VBA还有一种功能强...
  • 在数组里使用redim缩小了数组的长度,那么多余的数据是被删除了么?删除的数据放在了哪里?
  • VBA动态数组

    千次阅读 2018-03-04 21:36:04
    VBA没有像VC那样专门封装好的动态数组,如果想使用动态数组,可以用如下两步方法实现: 1、首先定义一个没有指定大小的数组,不需要给数组标明上界和下界,直接定义即可例如本人在模块定义了一个全局变量字符串数组...
  • VBA - Redim an Array

    千次阅读 2013-02-05 14:30:29
    转载自:http://www.dailydoseofexcel.com/archives/2004/06/28/redim-an-array/   Array variables can be static or dynamic. That’s determined by the Dim statement. If you specify dimensions when you...
  • 数组转置必须在同过程或同函数内redim 否则报无效 redim; 起始标必须为1,不能大于1也不能小于1,否则报类型不匹配错误; 数组不改变值的情况下只能增加列的数,如果要增加行,只能先转置,再增加,然后转置还原...
  • VB中dim与redim的区别?

    万次阅读 2018-11-02 08:23:22
    dim:定义一个固定维数的数组,如dim arr(100)。...在redim使用过程中,如果要保留数组中的数据,需要使用Preserve关键字,如果不加该关键字,会清空原来的数据。 参阅百度百科: ReDim 为数组变量重新分配...
  • & sKey & "*" Then countResult = countResult + 1 ReDim Preserve arrResult(1 To countResult) arrResult(countResult) = sData End If Next sData Me.ListBox1.List = arrResult End Sub Private Sub ListBox1_...
  • VBA数组

    千次阅读 2019-05-03 01:49:57
    VBA数组详解
  • Vba菜鸟教程

    万次阅读 多人点赞 2020-05-02 18:21:15
    文章目录Vba菜鸟教程编辑器宏vba基本语法运算符变量语句简写语句sub语句调用语句退出语句分支语句循环语句判断语句公式与函数在单元格输入公式利用单元格公式返回值调用工作表函数利用vba函数自定义函数操作对象操作...
  • vbavba语言基础

    2019-09-03 23:20:31
    (1)VBA允许使用未定义的变量,默认是变体变量 (2)在模块通用说明部分,加入Option Explicit语句可以强迫用户进行变量定义 (3)变量定义语句及变量作用域 一般变量作用域的原则是,那部分定义就在那部分起作用...
  • 'Excel连接驱动 ... if aaa>=Cint(yuhui(1,fori)) and aaa (yuhui(1,fori+1)) then aaay=yuhui(2,fori) end if ...redim Preserve 保留原有数据,重定义数组(一维数组)
  • VBA常用代码合集

    千次阅读 多人点赞 2020-12-19 11:13:11
    VBA常用代码模版Tp0️⃣—零零散散小功能(持续更新)Tp1️⃣—输出活动页面筛选后的行数Tp2️⃣—创建数组存放数据Tp2-1 静态数组Tp2-2 动态数组Tp3️⃣ 创建字典存放数据Tp4️⃣ 优化代码运行速度 Tp0️⃣—零零散...
  • VBA基础知识

    千次阅读 2019-11-12 14:18:36
    VBA入门学习笔记本关键词:VB、VBA、Microsoft office、excel、access、PowerPoint1.VBA的基本概念2 数据类型2.1 VBA基本数据类型2.2 VBA自定义的数据类型3 VBA常量3.1 VBA系统定义常量3.2 VBA固有常量3.2 VBA符号...
  • VBA笔记——collection方法

    千次阅读 2019-12-28 19:40:53
    文章目录 一、定义 二、成员 三、特点 四、读取集合元素 五、删除集合元素 1、三种方法删除集合元素 六、和普通数组相比集合的特点 七、和字典方法比较 1、集合添加时增加检索...VBA中集合collection方法的基础知识
  • VBA-自定义实用函数

    2017-07-02 22:14:00
      总结自定义VBA函数,补充《基于Office_VBA的数据处理、挖掘、建模及可视化的自动化框架设计》方案中相关函数,方便查找和应用。 目录概览  1)数组写入其他工作簿中(注:说明文档中未修改)  2)自动当前工作...
  • VBA操作TXT文档

    千次阅读 2019-05-22 17:09:49
    成果物是EXCEL文件,所以本次想通过VBA语言来进行编写处理; VBA基础: 1、变量的定义:  参考: https://blog.csdn.net/bangemantou/article/details/70183048 2、函数的定义与调用:  代开VBA编辑...
  • VBA宏命令制作坐标图

    2021-06-08 22:21:10
    VBA制作坐标图 word、ppt经常要制作图形,例如坐标图,有许多纵横线,有时需要批量制作,手工极不方便,线间距也不好调节,还有设置网格线的粗细、箭头、颜色等等,这时用VBA就可以发挥优势。 一、要求: 每间隔5格...
  • VBA基础知识整理

    万次阅读 多人点赞 2017-12-16 17:05:54
    最近由于项目的需要,需要在Excel自定义一些函数,来完成特殊的处理,为了完成工作,就囫囵吞枣的写了一些代码,现在闲暇下来,就好好的学习一下,VBA的基础知识。1.变量 1.Dim <<variable_name>> As ...
  • VBA程序如下: Sub test1() Dim w As Worksheet Set w = Worksheets("测试数据") Dim i As Integer, j As Integer, num As Integer, col As Integer Dim r As Range, rr As Range ' rr是需要复制的单元格 ...
  • vba读取csv文件,根据csv文件不同,会有不同格式: 1. 单纯的逗号分割,但是数字或备注字段中包含逗号,取入时,字段会被拆分 2. 以逗号分割,但是,每个字段都有引号 vba读取入csv后的格式,基本都是字符...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 660
精华内容 264
关键字:

preserveredimvba