Các hàm xử lý mảng trong bộ nhớ - Tốc độ nhanh!
Có phiên bản mới đây.
+ Hàm DeleteElementArray2D đã sửa lỗi liên quan đế khai báo phần tử thấp trong mảng. Phiên bản cũ chỉ chạy đúng nếu phần tử thấp từ 0.
+ Thêm hàm DeleteElementArray1D. Hàm này để xoá các phần tử của mảng 1 chiều.
+ Thêm hàm ConvertArray1DTo2D. Hàm này để chuyển đổi từ mảng 1 chiều sang 2 chiều. Mục đích sử dụng hàm này để điền mảng 1 chiều vào một cột trong bảng tính Excel.
Tất cả các hàm trên đều sử dụng kỹ thuật dịch chuyển các byte trong bộ nhớ, không dùng vòng lặp nên tốc độ nhanh!
(*) Lưu ý thêm:
+ Các phần tử của mảng phải là kiểu VARIANT
+ Đọc kỹ các comment trong mỗi hàm để nắm được quy tắc cũng như mục đích sử dụng hàm.
+ Download file đính kèm để chạy các thủ tục test.
+ Hiện nay tôi chạy trên Windows 6, Excel 2013 64-bit thì bị lỗi. Nhờ các bạn test trên Excel 2010 64-bit xem có lỗi không?
[GPECODE=vb]
Option Explicit
#If VBA7 Then 'Office 64-bit
Private Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef source As Any, ByVal Length As Long)
Private Declare PtrSafe Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (dst As Any, ByVal iLen&)
#Else ' Office 32-bit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef source As Any, ByVal Length As Long)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (dst As Any, ByVal iLen&)
#End If
Function DeleteElementArray2D(ByVal arrSource As Variant, ByVal lIndexBegin As Long, ByVal lIndexEnd As Long, Optional ByVal bEraseSource As Boolean = True) As Variant
'Programming by: Nguyen Duy Tuan -
www.bluesofts.net
'arrSource: is array 2D. Elements of array with VARIANT TYPE
'Return: an array after deleting element from lIndexBegin to lIndexEnd. Elements of array with VARIANT TYPE
Dim I As Long, ilowArrayD1 As Integer, ilowArrayD2 As Integer
ilowArrayD1 = LBound(arrSource, 1)
ilowArrayD2 = LBound(arrSource, 2)
ReDim out(ilowArrayD1 To UBound(arrSource, 1) - (lIndexEnd - lIndexBegin + 1), ilowArrayD2 To UBound(arrSource, 2)) As Variant
For I = LBound(arrSource, 2) To UBound(arrSource, 2) 'Copy columns
CopyMemory ByVal VarPtr(out(ilowArrayD1, I)), ByVal VarPtr(arrSource(ilowArrayD1, I)), 16 * ((lIndexBegin - ilowArrayD1))
Next I
For I = LBound(arrSource, 2) To UBound(arrSource, 2)
CopyMemory ByVal VarPtr(out(lIndexBegin, I)), ByVal VarPtr(arrSource(lIndexEnd + 1, I)), 16 * (UBound(arrSource) - lIndexEnd)
Next I
'Return array after deleting
DeleteElementArray2D = out
If bEraseSource Then
'Erase source array in memory
For I = LBound(arrSource, 2) To UBound(arrSource, 2)
ZeroMemory ByVal VarPtr(arrSource(ilowArrayD1, I)), 16 * (UBound(arrSource) - ilowArrayD1 + 1)
Next I
Erase arrSource
End If
End Function
Function DeleteElementArray1D(ByVal arrSource As Variant, ByVal lIndexBegin As Long, ByVal lIndexEnd As Long, Optional ByVal bEraseSource As Boolean = True) As Variant
'Programming by: Nguyen Duy Tuan -
www.bluesofts.net
'arrSource: is array 1D. Elements of array with VARIANT TYPE
'Return: an array 1D after deleting element from lIndexBegin to lIndexEnd. Elements of array with VARIANT TYPE
Dim I As Long, ilowArray As Integer
ilowArray = LBound(arrSource)
ReDim out(ilowArray To UBound(arrSource) - (lIndexEnd - lIndexBegin + 1)) As Variant
CopyMemory ByVal VarPtr(out(ilowArray)), ByVal VarPtr(arrSource(ilowArray)), 16 * ((lIndexBegin - ilowArray))
CopyMemory ByVal VarPtr(out(lIndexBegin)), ByVal VarPtr(arrSource(lIndexEnd + 1)), 16 * (UBound(arrSource) - lIndexEnd)
'Return array after deleting
DeleteElementArray1D = out
If bEraseSource Then
'Erase source array in memory
ZeroMemory ByVal VarPtr(arrSource(ilowArray)), 16 * (UBound(arrSource) - ilowArray + 1)
Erase arrSource
End If
End Function
Function ConvertArray1DTo2D(ByVal arrSource As Variant, Optional ByVal bEraseSource As Boolean = True) As Variant
'Programming by: Nguyen Duy Tuan -
www.bluesofts.net
'arrSource: is array 1D. Elements of array with VARIANT TYPE
'Return: an array 2D. Elements of array with VARIANT TYPE
'Use this function to fill array 1D to range in 1 column
Dim I As Long, ilowArray As Integer
ilowArray = LBound(arrSource, 1)
ReDim out(ilowArray To UBound(arrSource, 1), 1 To 1) As Variant
CopyMemory ByVal VarPtr(out(ilowArray, 1)), ByVal VarPtr(arrSource(ilowArray)), 16 * (UBound(arrSource) - ilowArray + 1)
ConvertArray1DTo2D = out
If bEraseSource Then
'Erase source array in memory
ZeroMemory ByVal VarPtr(arrSource(ilowArray)), 16 * (UBound(arrSource) - ilowArray + 1)
Erase arrSource
End If
End Function
[/GPECODE]