pitbull писал(а):Берешь и обнуляешь (делаешь Empty) ненужный элемент. Потом в цикле, начиная с порядкового номера этого эл-та в цикле делаешь следующее
a(12)=0
for i=12 to 34
a(i)=a(i+1)
a(i+1)=0
next i
вот, кажись, все
ZOD писал(а):А нельзя ли поконкретнее, как использовать CopyMemory, а то я в этом деле не очень разбираюсь.
Public Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" _
(ByVal pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Long)
Public Type SAFEARRAYBOUND
DSize As Long
DLbound As Long
End Type
Public Type SAFEARRAY
cDims As Integer
fFeat As Integer
ESize As Long
cLocks As Long
pvData As Long
Bounds As SAFEARRAYBOUND
End Type
Public Function AnyPtr(ByRef vVar As Variant) As Long
CopyMem VarPtr(AnyPtr), VarPtr(vVar) + 1, 1
If AnyPtr = 64 Or AnyPtr = 96 Then CopyMem VarPtr(AnyPtr), VarPtr(vVar) + 8, 4
End Function
Public Sub MyReDim(ByRef vArr as Variant, ByRef vTrashIndex as Long)
Dim lESize as Byte
CopyMem VarPtr(lASA), VarPtr(vArr) + 1, 1
If lASA = 96 Then
CopyMem VarPtr(lESize), VarPtr(vArr), 1
Select Case lESize
Case 17
lESize=1
Case 2
lESize=2
Case 3, 4, 8
lESize=4
Case 5-7
lESize=8
End Select
CopyMem VarPtr(vArr(vTrashIndex-LBound(vArr))), VarPtr(vArr(vTrashIndex-LBound(vArr))+1), lESize*(UBound(vArr)-vTrashIndex)
ReDim Preserve vArr(LBound(vArr) to (UBound(vArr)-lBound(vArr)))
Else
Exit Sub
End IF
End Sub
Public Sub MyReDimEx(ByRef vArr as Variant, ByRef vTrashIndex as Long)
Dim lSF as SAFEARRAY, lASA as Long
CopyMem VarPtr(lASA), VarPtr(vVar) + 1, 1
If lASA = 96 Then
CopyMem VarPtr(lASA), VarPtr(vVar) + 8, 4
CopyMem VarPtr(lSA), lSA, 24
With lSA.Bounds
CopyMem lSA.pvData+lSA.ESize*(vTrashIndex-.DLBound), lSA.pvData+lSA.ESize*(vTrashIndex-.DLBound+1), lSA.ESize*(.DSize-vTrashIndex+.DLBound-1)
ReDim Preserve vArr(.DLBound to (.DSize-1))
End With
Else
Exit Sub
End IF
Enf Sub
'Теперь в зависимости от обстоятельств
MyReDim Arr, TrashIndex
'или
MyReDimEx Arr, TrashIndex
alibek писал(а):Если массив имеет числовой тип (Integer, Long, Single, Double, Currency, Date, Boolean, Byte), то как советовал GSerg (сделать CopyMemory из D(i) в D(i-1), а затем ReDim Preserve). А если массив строковый или пользовательского типа, то только поштучным перетаскиванием элементов массива (a-la pitbull)
pitbull писал(а):Вот это прикольноЯ ведь и писал пример в надежде на то, что кто-то знает как делать это все через CopyMemory, и увидев мой пример решит показать свой. Ну вот теперь умней малек стал.
![]()
![]()
kif писал(а):Если массив пользовательского типа, то лучше добавить еще признак удаления и использовать его. Быстрее будет, чем реально удалить элемент. Особенно для массивов большого объема.
MOV писал(а):А все-таки. Почему не использовать объект коллекцию, там ведь удаление происходит просто по индексу, насколько помню (по аналогии с элементами листбокса) обычным Remove, помоему. Или Collection ест больше памяти и едленне пашет? (я думаю и то и другое, зато удобнее немного ).
Сейчас этот форум просматривают: Google-бот, Yandex-бот и гости: 20