-1

I am importing a range as a 2D Variant into VBA and to declare an array as Variant by `Dim matrix().

I now want to loop through the rows and delete rows where the 2nd column = "even" or the 5th row ends with "_tom". Dataset below

My main issue is that I do not know how to delete that rows?

1,  odd,    3,  27, today
2,  even,   6,  21, today_tom
3,  odd,    9,  28, today
4,  even,   12, 30, today
5,  odd,    15, 17, today_tom
6,  even,   18, 17, today
7,  odd,    21, 18, today
8,  even,   24, 9 , today_tom
9,  odd,    27, 24, today_tom
10, even,   30, 9,  today
11, odd,    33, 11, today
12, even,   36, 22, today
13, odd,    39, 8 , today
14, even,   42, 1 , today
15, odd,    45, 4 , today

Current code:

Sub test()
    Dim matrix As Variant
    matrix = Range("A1:E15")
    Dim r As Long

    For r = LBound(matrix, 1) To UBound(matrix, 1)
        If matrix(r, 2).Value = "even" Then
            'delete
        End If
        If Right(matrix(r, 2).Value, 4) = "_tom" Then
            'delete
        End If
    Next r

End Sub

T.M.
  • 9,436
  • 3
  • 33
  • 57
Sam Harper
  • 61
  • 1
  • 3
  • 10
  • 1
    So you need a loop. Have you tried any code yet? You'll need to loop from `LBound(matrix, 1)` to `Ubound(matrix, 1)`. – BigBen Jan 10 '20 at 16:34
  • Added code, but it doesnt work – Sam Harper Jan 10 '20 at 16:46
  • Voted to reopen based on your provided code. You can't "delete" an element of the array. Maybe you want to read any lines to keep into a new array? – BigBen Jan 10 '20 at 16:58
  • Thanks. So you think it would be best to make another Array and only feed in if those conditions are true? Mkaes more sense - will pot solution ASAIC – Sam Harper Jan 10 '20 at 17:28
  • Well only feed in if those conditions are false, but that is one option yes. – BigBen Jan 10 '20 at 17:30
  • @BigBen - FYI a workaround demonstrating a way to "delete" array elements :-) – T.M. Jan 11 '20 at 18:55

1 Answers1

2

Delete array elements via Application.Index()

Yes, it's possible to "delete" array elements by a workaround via the Application.Index function enriched by several array arguments:


Sub Restructure()
' Site: https://stackoverflow.com/questions/59685516/vba-run-through-a-2d-variant-array-deleting-columns
    Dim matrix As Variant
    matrix = Sheet1.Range("A1:E15")
    '========================================================
    'Maintain only array rows <> "even" or ending with "_tom"
    '--------------------------------------------------------
    matrix = Application.Index(matrix, getRowNo(matrix), Array(1, 2, 3, 4, 5))

''optional: write to any target range    
'           Sheet1.Range("G1").Resize(UBound(matrix), UBound(matrix, 2)) = matrix
End Sub

Helper function getRowNo()

Function getRowNo(arr) As Variant()
' Note: receives last column values of array two as 1-dim 1based array
' Purp: returns 2-dim 1-based array with row numbers if conditions met
    Dim i As Long, ii As Long, tmp()
    ReDim tmp(1 To 1, 1 To UBound(arr))     ' provide for temporary array
    For i = LBound(arr) To UBound(arr)
        If arr(i, 2) = "even" Or Right(arr(i, 5), 4) = "_tom" Then
        ' do nothing
        Else
            ii = ii + 1                     ' increment temp counter
            tmp(1, ii) = i                  ' enter row number of original column data
        End If
    Next i
    ReDim Preserve tmp(1 To 1, 1 To ii)     ' correct last dimension
    getRowNo = Application.Transpose(tmp)   ' return 2-dim array with rownumbers to be preserved
End Function

Example Result

example sheet Further hint

It's not possible to reference an array element by a .Value property, only by indices (e.g. matrix(1,1))

T.M.
  • 9,436
  • 3
  • 33
  • 57