Option Explicit
Public source_array As Variant
Dim r As Long
Dim c As Long
Dim i As Long
Dim TempArray As Variant
Enum ProcessIndex
piDelete = -1
piBlank
piInsert
End Enum
Enum CutAndPasteResult
cpInsert
cpOverWrite
End Enum
Enum RemainOrDelete
rdRemain
rdDelete
End Enum
Public Function RowDelete(row_index As Long) As Variant
RowDelete = RowEdit(row_index, piDelete)
End Function
Public Function RowInsert(ByVal row_index As Long, _
Optional row_shift As Excel.XlDirection = xlDown) As Variant
row_index = row_index + dr(row_shift)
RowInsert = RowEdit(row_index, piInsert, row_shift)
End Function
Public Function RowBlank(row_index As Long) As Variant
If row_index = rMax Then
For c = cMin To cMax
source_array(row_index, c) = vbNullString
Next
RowBlank = source_array
Exit Function
End If
source_array = RowDelete(row_index)
If row_index > UBound(source_array) Then
RowBlank = source_array
Else
RowBlank = RowInsert(row_index)
End If
End Function
Private Function RowEdit(row_index As Long, _
p_index As ProcessIndex, _
Optional row_shift As Excel.XlDirection = xlDown) As Variant
Dim TempMax As Long
TempMax = rMax + p_index + dr(row_shift)
ReDim TempArray(rMin To TempMax, cMin To cMax)
i = rMin
For r = rMin To TempMax
If i = row_index Then
Select Case p_index
Case piDelete
i = i - p_index
Case piInsert
r = r + p_index
End Select
End If
On Error Resume Next
For c = cMin To cMax
TempArray(r, c) = source_array(i, c)
Next
On Error GoTo 0
i = i + 1
Next
RowEdit = TempArray
End Function
Public Function RowCutAndPaste(ByVal source_row_index As Long, _
ByVal destination_row_index As Long, _
Optional cut_or_copy As Excel.XlCutCopyMode = xlCut, _
Optional overwrite_or_insert As CutAndPasteResult = cpOverWrite, _
Optional row_shift As Excel.XlDirection = xlDown) As Variant
Dim arr As Variant
arr = source_row_array(source_row_index)
If overwrite_or_insert = cpInsert Then
source_array = RowInsert(destination_row_index, row_shift)
ElseIf overwrite_or_insert = cpOverWrite Then
row_shift = xlDown
End If
For c = cMin To cMax
source_array(destination_row_index + dr(row_shift), c) = arr(1, c)
Next
If cut_or_copy = xlCut Then
If overwrite_or_insert = cpInsert Then
If source_row_index >= destination_row_index Then
source_row_index = source_row_index + 1
End If
End If
RowCutAndPaste = RowDelete(source_row_index)
Else
RowCutAndPaste = source_array
End If
End Function
Public Function RowExchange(row_index_1 As Long, _
row_index_2 As Long) As Variant
Dim r_low As Long
r_low = WorksheetFunction.Min(row_index_1, row_index_2)
Dim r_high As Long
r_high = WorksheetFunction.Max(row_index_1, row_index_2)
source_array = RowCutAndPaste(r_high, r_low, xlCut, cpInsert, xlDown)
RowExchange = RowCutAndPaste(r_low + 1, r_high, xlCut, cpInsert, xlUp)
End Function
Public Function RowFilter(filt As Variant, _
column_index As Long, _
Optional rf_LookAt As Excel.XlLookAt = xlWhole, _
Optional rf_header As Excel.XlYesNoGuess = xlYes, _
Optional rf_result As RemainOrDelete = RemainOrDelete.rdDelete)
Dim TempArray_Remain As Variant
ReDim TempArray_Remain(rMin To rMax, cMin To cMax)
Dim TempArray_Delete As Variant
ReDim TempArray_Delete(rMin To rMax, cMin To cMax)
Dim StartRowIndex As Long
If rf_header = xlYes Then
For c = cMin To cMax
TempArray_Remain(rMin, c) = source_array(rMin, c)
TempArray_Delete(rMin, c) = source_array(rMin, c)
Next
StartRowIndex = rMin + 1
Else
StartRowIndex = rMin
End If
If rf_LookAt = xlPart Then
filt = "*" & filt & "*"
End If
Dim iR As Long
Dim iD As Long
iR = StartRowIndex
iD = StartRowIndex
For r = StartRowIndex To rMax
If Not source_array(r, column_index) Like filt Then
For c = cMin To cMax
TempArray_Delete(iD, c) = source_array(r, c)
Next
iD = iD + 1
Else
For c = cMin To cMax
TempArray_Remain(iR, c) = source_array(r, c)
Next
iR = iR + 1
End If
Next
Dim TempArray_Result1 As Variant
Dim TempArray_Result2 As Variant
Select Case rf_result
Case RemainOrDelete.rdDelete
TempArray_Result1 = TempArray_Delete
i = iD - 1
Case RemainOrDelete.rdRemain
TempArray_Result1 = TempArray_Remain
i = iR - 1
End Select
ReDim TempArray_Result2(rMin To i, cMin To cMax)
For r = rMin To i
For c = cMin To cMax
TempArray_Result2(r, c) = TempArray_Result1(r, c)
Next
Next
RowFilter = TempArray_Result2
End Function
Public Function RowRegExpFilter(filt_pattern As Variant, _
column_index As Long, _
Optional rf_header As Excel.XlYesNoGuess = xlYes, _
Optional rf_result As RemainOrDelete = RemainOrDelete.rdDelete)
Dim TempArray_Remain As Variant
ReDim TempArray_Remain(rMin To rMax, cMin To cMax)
Dim TempArray_Delete As Variant
ReDim TempArray_Delete(rMin To rMax, cMin To cMax)
Dim StartRowIndex As Long
If rf_header = xlYes Then
For c = cMin To cMax
TempArray_Remain(rMin, c) = source_array(rMin, c)
TempArray_Delete(rMin, c) = source_array(rMin, c)
Next
StartRowIndex = rMin + 1
Else
StartRowIndex = rMin
End If
Dim myReg As Object
Set myReg = CreateObject("VBScript.RegExp")
myReg.IgnoreCase = False
myReg.Pattern = filt_pattern
Dim iR As Long
Dim iD As Long
iR = StartRowIndex
iD = StartRowIndex
For r = StartRowIndex To rMax
If myReg.test(source_array(r, column_index)) = False Then
For c = cMin To cMax
TempArray_Delete(iD, c) = source_array(r, c)
Next
iD = iD + 1
Else
For c = cMin To cMax
TempArray_Remain(iR, c) = source_array(r, c)
Next
iR = iR + 1
End If
Next
Dim TempArray_Result1 As Variant
Dim TempArray_Result2 As Variant
Select Case rf_result
Case RemainOrDelete.rdDelete
TempArray_Result1 = TempArray_Delete
i = iD - 1
Case RemainOrDelete.rdRemain
TempArray_Result1 = TempArray_Remain
i = iR - 1
End Select
ReDim TempArray_Result2(rMin To i, cMin To cMax)
For r = rMin To i
For c = cMin To cMax
TempArray_Result2(r, c) = TempArray_Result1(r, c)
Next
Next
RowRegExpFilter = TempArray_Result2
End Function
Public Function source_row_array(source_row_index) As Variant
ReDim TempArray(1 To 1, cMin To cMax)
For c = cMin To cMax
TempArray(1, c) = source_array(source_row_index, c)
Next
source_row_array = TempArray
End Function
Private Function dr(row_shift As Excel.XlDirection) As Long
If row_shift <> xlToLeft And row_shift <> xlToRight Then
dr = (xlDown - row_shift) / (xlDown - xlUp)
End If
End Function
Private Property Get rMin() As Long
rMin = LBound(source_array, 1)
End Property
Private Property Get rMax() As Long
rMax = UBound(source_array, 1)
End Property
Private Property Get cMin() As Long
cMin = LBound(source_array, 2)
End Property
Private Property Get cMax() As Long
cMax = UBound(source_array, 2)
End Property