Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Delete/Insert Columns With Filter on in Excel 2000 and Older

Status
Not open for further replies.

idbr

MIS
May 1, 2003
247
GB
Hi,

Have just changed jobs and gone from E2002 to E2000. One of the more annoying aspects is that you can't delete or insert columns with a filter on, this code allows you to do both.

You just need to select a single cell in the column you wish to delete/position you want to insert.

I know most people won't be working for dinosaur companies with old technology :), but hopefully this will help someone...

Regards, Iain

Code:
Public Sub Delete_While_Filtered()

Dim rngFilter As Range

Dim arrCriteria
Dim arrFilter1
Dim arrFilter2
Dim arrFilterOperator

Dim strColLett As String
Dim strLastCol As String

Dim i As Integer
Dim x As Integer
Dim c As Integer
Dim a As Integer
Dim intNumCols As Integer

Set rngFilter = ActiveCell.CurrentRegion

i = 1
x = 0

'Are filters on?
If ActiveSheet.AutoFilterMode = False Then Exit Sub

'------------------------------------------------------
'if the column being deleted is the active column we'll
'need to take this into account later...
'------------------------------------------------------

c = ActiveCell.Column

'Are any filters applied?
For i = 1 To rngFilter.Worksheet.AutoFilter.Filters.Count

    If rngFilter.Worksheet.AutoFilter.Filters(i).On = True Then
    
        x = x + 1
        
    Else
    
    End If
    
Next i

'Reset the counter for use later
i = 1

'Are filters active?
If x > 0 Then
    
    '------------------------------------------------
    'Loop through the filters, appending the criteria
    '------------------------------------------------
    
    Do Until i = rngFilter.Worksheet.AutoFilter.Filters.Count + 1
        
        'Is the filter on?
        If rngFilter.Worksheet.AutoFilter.Filters(i).On = True Then
            
            '----------------------------------
            'Add the column number to the array
            '----------------------------------
            
            'First check to see if this is the column to be deleted
            'If so, exit the array filling section as we don't need
            'to preserve the filter criteria
            
            If i = c Then GoTo tagSkipActiveColumn
            
            '-----------------------------------------------------------
            'set the column value for the array, because when the active
            'column is deleted, the columns to the right will decrease
            'in number by 1
            '-----------------------------------------------------------
            
            If i < c Then 'before the active column
             
                a = i
                
            Else 'after the active column
            
                a = i - 1
                
            End If
             
            'Check to see if it's first time around
            If Not IsArray(arrCriteria) Then
             
                ReDim arrCriteria(0)
                arrCriteria(UBound(arrCriteria)) = a
             
            Else
             
                ReDim Preserve arrCriteria(UBound(arrCriteria) + 1)
                arrCriteria(UBound(arrCriteria)) = a
                
            End If
             
            '------------------------------------
            'Redimension the three criteria arrays
            '------------------------------------
             
            'Check to see if it's first time around
            If Not IsArray(arrFilter1) Then
                
                'It is, instantiate the array
                ReDim arrFilter1(0)
             
            Else
                
                'It's not, just add a new element
                ReDim Preserve arrFilter1(UBound(arrFilter1) + 1)
                
            End If
             
             
            'Ditto
            If Not IsArray(arrFilter2) Then
             
                ReDim arrFilter2(0)
             
            Else
             
                ReDim Preserve arrFilter2(UBound(arrFilter2) + 1)

            End If
             
            'Ditto
            If Not IsArray(arrFilterOperator) Then
             
                ReDim arrFilterOperator(0)
             
            Else
             
                ReDim Preserve arrFilterOperator(UBound(arrFilterOperator) + 1)
               
            End If
            
            
             'Is there an operator?
             If (rngFilter.Worksheet.AutoFilter.Filters(i).Operator = xlOr Or rngFilter.Worksheet.AutoFilter.Filters(i).Operator = xlAnd) Then
     
                'If so, add both criteria values to the array
                arrFilterOperator(UBound(arrFilterOperator)) = rngFilter.Worksheet.AutoFilter.Filters(i).Operator
                arrFilter1(UBound(arrFilter1)) = rngFilter.Worksheet.AutoFilter.Filters(i).Criteria1
                arrFilter2(UBound(arrFilter2)) = rngFilter.Worksheet.AutoFilter.Filters(i).Criteria2
                 
             Else
     
                'Just add Criteria1
                arrFilterOperator(UBound(arrFilterOperator)) = Null
                arrFilter1(UBound(arrFilter1)) = rngFilter.Worksheet.AutoFilter.Filters(i).Criteria1
                arrFilter2(UBound(arrFilter2)) = Null


             End If
         
        Else
            
        End If
        
tagSkipActiveColumn:
        
        i = i + 1
    
    Loop
    
    '----------------------------------------------------------------------------
    'Gone through all of the filters, now take them all off and delete the column
    '----------------------------------------------------------------------------
    
    ActiveSheet.AutoFilterMode = False
    
    strColLett = Mid(ActiveCell.Address, 2, InStr(2, ActiveCell.Address, "$") - 2)
    
    ActiveSheet.Columns(strColLett & ":" & strColLett).Delete
    
    '--------------------------------------------------
    'Now reapply all of the filters that were on before
    '--------------------------------------------------
    
    'first turn the filters back on for all of the columns on the sheet
    'throws an error otherwise as it gets a bit confused by columns being
    'missing
    
        'Set the number of columns in the active region
    intNumCols = ActiveCell.CurrentRegion.Columns.Count
    
    'Convert the column number to a letter to be able to select the range
    strLastCol = ConvertColumnNumberToLetter(intNumCols)
    
    Range("A1:" & strLastCol & "1").Select
    Selection.AutoFilter
        
    i = 0
    
    For i = 0 To UBound(arrCriteria)
    
    'first check for an operator
    If IsNull(arrFilterOperator(i)) Then
    
    Cells(1, arrCriteria(i)).AutoFilter _
                                Field:=arrCriteria(i), _
                                Criteria1:=arrFilter1(i)
                                
    Else
    'We have an operator so need to add two criteria values
    Cells(1, arrCriteria(i)).AutoFilter _
                                arrCriteria(i), _
                                Criteria1:=arrFilter1(i), _
                                Operator:=arrFilterOperator(i), _
                                Criteria2:=arrFilter2(i)
                                                         
    End If
    
    Next i
    
Else
    
    'Just take off the filters, delete and re-apply
    ActiveSheet.AutoFilterMode = False
    
    strColLett = Mid(ActiveCell.Address, 2, InStr(2, ActiveCell.Address, "$") - 2)
    
    ActiveSheet.Columns(strColLett & ":" & strColLett).Select
    Selection.Delete
    
    intNumCols = ActiveCell.CurrentRegion.Columns.Count

    strLastCol = ConvertColumnNumberToLetter(intNumCols)
    
    Range("A1:" & strLastCol & "1").Select
    
    Selection.AutoFilter

End If

End Sub

Public Sub Insert_While_Filtered()

Dim rngFilter As Range

Dim arrCriteria
Dim arrFilter1
Dim arrFilter2
Dim arrFilterOperator

Dim strColLett As String
Dim strLastCol As String

Dim i As Integer
Dim x As Integer
Dim c As Integer
Dim a As Integer
Dim intNumCols As Integer

Dim blnCurrentCol As Boolean

Set rngFilter = ActiveCell.CurrentRegion

i = 1
x = 0

'Are filters on?
If ActiveSheet.AutoFilterMode = False Then Exit Sub

'---------------------------------------------------------
'We need to take the insertion point into account later...
'---------------------------------------------------------

c = ActiveCell.Column

'Are any filters applied?
For i = 1 To rngFilter.Worksheet.AutoFilter.Filters.Count

    If rngFilter.Worksheet.AutoFilter.Filters(i).On = True Then
    
        x = x + 1
        
    Else
    
    End If
    
Next i

'Reset the counter for use later
i = 1

'Are filters active?
If x > 0 Then
    
    '------------------------------------------------
    'Loop through the filters, appending the criteria
    '------------------------------------------------
    
    Do Until i = rngFilter.Worksheet.AutoFilter.Filters.Count + 1
        
        'Is the filter on?
        If rngFilter.Worksheet.AutoFilter.Filters(i).On = True Then
            
            '----------------------------------
            'Add the column number to the array
            '----------------------------------
                       
            '-----------------------------------------------------------
            'set the column value for the array, because when the column
            'is inserted, the columns to the right will increase in
            'number by 1
            '-----------------------------------------------------------
            
            If i < c Then 'at or before the active column
             
                a = i
                
            Else 'after the active column
            
                a = i + 1
                
            End If
             
            'Check to see if it's first time around
            If Not IsArray(arrCriteria) Then
             
                ReDim arrCriteria(0)
                arrCriteria(UBound(arrCriteria)) = a
             
            Else
             
                ReDim Preserve arrCriteria(UBound(arrCriteria) + 1)
                arrCriteria(UBound(arrCriteria)) = a
                
            End If
             
            '------------------------------------
            'Redimension the three criteria arrays
            '------------------------------------
             
            'Check to see if it's first time around
            If Not IsArray(arrFilter1) Then
                
                'It is, instantiate the array
                ReDim arrFilter1(0)
             
            Else
                
                'It's not, just add a new element
                ReDim Preserve arrFilter1(UBound(arrFilter1) + 1)
                
            End If
             
             
            'Ditto
            If Not IsArray(arrFilter2) Then
             
                ReDim arrFilter2(0)
             
            Else
             
                ReDim Preserve arrFilter2(UBound(arrFilter2) + 1)

            End If
             
            'Ditto
            If Not IsArray(arrFilterOperator) Then
             
                ReDim arrFilterOperator(0)
             
            Else
             
                ReDim Preserve arrFilterOperator(UBound(arrFilterOperator) + 1)
               
            End If
            
            
             'Is there an operator?
             If (rngFilter.Worksheet.AutoFilter.Filters(i).Operator = xlOr Or rngFilter.Worksheet.AutoFilter.Filters(i).Operator = xlAnd) Then
     
                'If so, add both criteria values to the array
                arrFilterOperator(UBound(arrFilterOperator)) = rngFilter.Worksheet.AutoFilter.Filters(i).Operator
                arrFilter1(UBound(arrFilter1)) = rngFilter.Worksheet.AutoFilter.Filters(i).Criteria1
                arrFilter2(UBound(arrFilter2)) = rngFilter.Worksheet.AutoFilter.Filters(i).Criteria2
                 
             Else
     
                'Just add Criteria1
                arrFilterOperator(UBound(arrFilterOperator)) = Null
                arrFilter1(UBound(arrFilter1)) = rngFilter.Worksheet.AutoFilter.Filters(i).Criteria1
                arrFilter2(UBound(arrFilter2)) = Null


             End If
         
        Else
            
        End If
        
        i = i + 1
    
    Loop
    
    '----------------------------------------------------------------------------
    'Gone through all of the filters, now take them all off and insert the column
    '----------------------------------------------------------------------------
    
    ActiveSheet.AutoFilterMode = False
    
    strColLett = Mid(ActiveCell.Address, 2, InStr(2, ActiveCell.Address, "$") - 2)
    
    ActiveSheet.Columns(strColLett & ":" & strColLett).Insert shift:=xlShiftToRight
    
    '--------------------------------------------------
    'Now reapply all of the filters that were on before
    '--------------------------------------------------
    
    'first turn the filters back on for all of the columns on the sheet
    'throws an error otherwise as it selects only the columns to the right
    'of the inserted column if a filter is on one of these columns
    
    'Set the number of columns in the active region
    intNumCols = ActiveCell.CurrentRegion.Columns.Count
    
    'Convert the column number to a letter to be able to select the range
    strLastCol = ConvertColumnNumberToLetter(intNumCols)
    
    Range("A1:" & strLastCol & "1").Select
    Selection.AutoFilter
           
    'Reset the counter
    i = 0
    
    'loop until the end of the array
    For i = 0 To UBound(arrCriteria)
    
    'first check for an operator
    If IsNull(arrFilterOperator(i)) Then
    
    Cells(1, arrCriteria(i)).AutoFilter _
                                Field:=arrCriteria(i), _
                                Criteria1:=arrFilter1(i)
                                
    Else
    'We have an operator so need to add two criteria values
    Cells(1, arrCriteria(i)).AutoFilter _
                                arrCriteria(i), _
                                Criteria1:=arrFilter1(i), _
                                Operator:=arrFilterOperator(i), _
                                Criteria2:=arrFilter2(i)
                                                         
    End If
    
    Next i
    
Else
    
    'Just take off the filters, insert and re-apply
    ActiveSheet.AutoFilterMode = False
    
    strColLett = Mid(ActiveCell.Address, 2, InStr(2, ActiveCell.Address, "$") - 2)
    
    ActiveSheet.Columns(strColLett & ":" & strColLett).Insert shift:=xlShiftToRight
    
    intNumCols = ActiveCell.CurrentRegion.Columns.Count

    strLastCol = ConvertColumnNumberToLetter(intNumCols)
    
    Range("A1:" & strLastCol & "1").Select
    
    Selection.AutoFilter

End If

End Sub
This function is called in the routine, so posted for completeness:
Code:
Public Function ConvertColumnNumberToLetter(ByVal ColumnNumber As Integer)

'from [URL unfurl="true"]http://vba-programmer.com/Snippets/Code_Excel/Column_Numbers_to_Letters.html[/URL]

Dim IntegerResult As Integer
Dim FractionalResult As Integer
Dim Remainder As Integer
Dim FirstLetter As String
Dim SecondLetter As String


IntegerResult = ColumnNumber \ 26
FractionalResult = (ColumnNumber / 26) - IntegerResult
Remainder = ColumnNumber Mod 26
If IntegerResult = 0 Then
    FirstLetter = ""
ElseIf IntegerResult = 1 And FractionalResult = 0 Then
    FirstLetter = ""
    ConvertColumnNumberToLetter = "Z"
    Exit Function
ElseIf IntegerResult > 1 And FractionalResult = 0 Then
    FirstLetter = Chr(64 + (IntegerResult - 1))
    ConvertColumnNumberToLetter = FirstLetter & "Z"
    Exit Function
Else
    FirstLetter = Chr(64 + IntegerResult)
End If
SecondLetter = Chr(64 + Remainder)
ConvertColumnNumberToLetter = FirstLetter & SecondLetter
End Function
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top