相信大家都知道在VB中是不提供直接删除数组中某个元素的函数的,这样就得自己编写函数,很多朋友都是使用循环的方式来实现的,这样效率太低了,刚好这几天刚到新公司上班,还没安排任务下来,无聊就写了这个程序主要是为了在VB中提高效率,程序运行一次没问题,但是郁闷的是运行第二次会出问题,由于上班时间没得多的调试时间。大家可以一起研究改善一下。和文章“快速复制数组”------http://community.csdn.net/Expert/topic/5461/5461836.xml?temp=.1506464出现的问题差不多,希望感兴趣有时间的朋友看看把问题找到好方便大家。Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private strSave() As String
Private strView() As StringPrivate Sub cmdDelete_Click()
    Dim lng1 As Long, lng2 As Long
'    lng1 = VarPtr(strSave(0))
'    CopyMemory lng2, lng1, 4
'    ReDim strView(UBound(strSave) - 1)
'    CopyMemory ByVal VarPtr(strView(0)), ByVal lng2, 4 * (CInt(textIndex.Text))
'    lng1 = VarPtr(strSave(CInt(textIndex.Text) + 1))
'    CopyMemory lng2, lng1, 4
'    CopyMemory ByVal VarPtr(strView(textIndex.Text)), ByVal lng2, 4 * (UBound(strSave) - CInt(textIndex.Text) + 1)
      Call DeleteArrayDataByIndex(strSave, CInt(textIndex.Text))
End SubPrivate Sub cmdExit_Click()
    Unload Me
End SubPrivate Sub cmdSave_Click()
    cmdSave.Enabled = False
    strSave = Split(textSave.Text, ",")
    cmdSave.Enabled = True
    Randomize
    textIndex.Text = CStr(Int((UBound(strSave) * Rnd) + 1))
End SubPrivate Sub cmdView_Click()
    Dim strTmp As String, i As Integer
    For i = LBound(strView) To UBound(strView)
        strTmp = strTmp & strView(i) & ","
    Next
    textView.Text = Left(strTmp, Len(strTmp) - 1)
End SubPrivate Sub CopyStringArray(strSourceArray() As String, strDestArray() As String)
    Dim lng1 As Long, lng2 As Long
    If IsStringArrayIsInitialize(strSourceArray) Then
        lng1 = VarPtr(strSourceArray(0))
        CopyMemory lng2, lng1, 4
        ReDim strDestArray(UBound(strSourceArray))
        CopyMemory ByVal VarPtr(strDestArray(0)), ByVal lng2, 4 * (UBound(strSourceArray) + 1) 'LenB(strSourceArray(0)) * (UBound(strSourceArray) + 1)
    End If
End SubPrivate Function DeleteArrayDataByIndex(objArray() As String, ByVal index As Integer)
    Dim lng1 As Long, lng2 As Long, intCount As Integer, intMin As Integer
    intMin = LBound(objArray)
    intCount = UBound(objArray)
    If index > intCount Then Exit Function
    If index <> intMin And index <> intCount Then
        lng1 = VarPtr(strSave(intMin))
        CopyMemory lng2, lng1, 4
        ReDim strView(UBound(strSave) - 1)
        CopyMemory ByVal VarPtr(strView(0)), ByVal lng2, 4 * (index)
        lng1 = VarPtr(strSave(index + 1))
        CopyMemory lng2, lng1, 4
        CopyMemory ByVal VarPtr(strView(textIndex.Text)), ByVal lng2, 4 * (UBound(strSave) - index + 1)
    Else
        If index = intMin Then
            lng1 = VarPtr(strSave(intMin + 1))
            CopyMemory lng2, lng1, 4
            ReDim strView(intCount - 1)
            CopyMemory ByVal VarPtr(strView(intMin)), ByVal lng2, 4 * (intCount)
        Else
            lng1 = VarPtr(strSave(intMin))
            CopyMemory lng2, lng1, 4
            ReDim strView(intCount - 1)
            CopyMemory ByVal VarPtr(strView(intMin)), ByVal lng2, 4 * (intCount)
        End If
    End If
End Function

解决方案 »

  1.   

    http://www.cnblogs.com/rainstormmaster/archive/2006/01/09/313880.html
      

  2.   

    1、CopyMemory lng2, lng1, 4与lng2=lng1有区别吗?是不是LZ认为CopyMemory调用比VB的赋值语句还快?2、这种复制方式对String数组是不适用的,String数组中保存的并不是实际的String数据,而只是一个String指针,数据是另辟内存块保存的,当复制一个string数组的所有String指针给另一String数组后,会出现混乱,这个新数组VB并不知情,它需依靠旧数组维护数据,当旧数组重置后,新数组的所有指针将无效,当VB试图访问它时,肯定会出错崩溃!不光如此,VB结束时,会释放资源,两个数组不管先释放谁,后一个都必然出错!所以,这种复制String数组方式,是很危险的,实用价值有限,而且在VB退出前,必须恢复旧指针,不然VB没法正常退出。3、LZ很迷信API,其实循环也并不慢,请看看下面的贴子:
    http://community.csdn.net/Expert/topic/5454/5454094.xml?temp=7.691592E-02附上一个利用VB函数删除String数组元素的简易方法:
    strSave(textIndex.Text) = "<#del#>" '这个值可随意,只要在数组中不可能出现它就可以了。
    strView = Filter(strSave, "<#del#>", False)