Удаление столбцов / строк, когда не содержит значений из списков переменных

#excel #vba

#excel #vba

Вопрос:

Я новичок в VBA… Я пытаюсь удалить все столбцы из файла Sheet1: «Template» ROW1 / headers, который не соответствует ни одному из значений ячеек в varList:»ColumnsList» (то есть в Sheet3).

Как мне выбрать заголовки или как мне выбрать диапазон строк 1 для поиска?

Кроме того, у меня есть ошибка времени выполнения 5 в этой строке: недопустимый вызов процедуры или аргумент.

Если пересекаются (rng.Ячейки (1, i).Весь столбец, rngF) Тогда ничего

Любая добрая душа, которая поможет мне с этим, пожалуйста?

Кроме того, мне нужно сделать то же самое, но со строками из листа 1: «Шаблон». Мне нужно удалить любую строку, которая не СОДЕРЖИТ значения ячейки из списка переменных: «Агенты» (то есть в Sheet2).

Не могли бы вы мне помочь?

Заранее большое спасибо!!!

 Option Compare Text
Sub ModifyTICBData()

Dim varList As Variant
    Dim lngarrCounter As Long
    Dim rngFound As Range, rngToDelete As Range
    Dim strFirstAddress As String

    'Application.ScreenUpdating = False

    varList = VBA.Array("ColumnsList") 'I want to keep columns with these values, NOT DELETE THEM

    For lngarrCounter = LBound(varList) To UBound(varList)

        With Sheets("Template").UsedRange
            Set rngFound = .Find( _
                                What:=varList(lngarrCounter), _
                                Lookat:=xlWhole, _
                                SearchOrder:=xlByColumns, _
                                SearchDirection:=xlNext, _
                                MatchCase:=True)

            If Not rngFound Is Nothing Then
                strFirstAddress = rngFound.Address

                If rngToDelete Is Nothing Then
                    Set rngToDelete = rngFound
                Else
                    If Application.Intersect(rngToDelete, rngFound.EntireColumn) Is Nothing Then
                        Set rngToDelete = Application.Union(rngToDelete, rngFound)
                    End If
                End If

                Set rngFound = .FindNext(After:=rngFound)

                Do Until rngFound.Address = strFirstAddress
                    If Application.Intersect(rngToDelete, rngFound.EntireColumn) Is Nothing Then
                        Set rngToDelete = Application.Union(rngToDelete, rngFound)
                    End If
                    Set rngFound = .FindNext(After:=rngFound)
                Loop
            End If
        End With
    Next lngarrCounter

    Dim rngDel As Range
Set rngDel = NotIntersectRng(Sheets("Template").UsedRange, rngToDelete)
If Not rngDel Is Nothing Then rngDel.EntireColumn.delete

    'Application.ScreenUpdating = True
End Sub

Private Function NotIntersectRng(rng As Range, rngF As Range) As Range
  Dim rngNI As Range, i As Long, j As Long
  For i = 1 To rng.Columns.Count
    **If Intersect(rng.Cells(1, i).EntireColumn, rngF) Is Nothing Then**
        If rngNI Is Nothing Then
            Set rngNI = rng.Cells(1, i)
        Else
            Set rngNI = Union(rngNI, rng.Cells(1, i))
        End If
    End If
  Next i
  If Not rngNI Is Nothing Then Set NotIntersectRng = rngNI
End Function
  

Комментарии:

1. Добро пожаловать в SO . Из кода я могу сделать вывод, что первая ячейка набора данных на листе Template — это ячейка A1 . Когда вы выбираете A1 , удерживаете CTRL и нажимаете A , выбирается ли весь набор данных (диапазон, подлежащий обработке)? Можете ли вы сказать мне местоположение ColumnsList и Agents ; Я знаю рабочие листы, но мне нужен их адрес первой ячейки или адрес диапазона; или они называются диапазонами или заполнителями для списка строк, которые вы хотите добавить вручную? Вы используете Option Compare Text значение A=a , но затем вы используете MatchCase = True значение A<>a , теперь это так, или это правильно?

2. Уважаемый, мистер @VBasic2008, большое вам спасибо!! Однако есть проблема: мне нужно переместить мою первую строку в строку 3 в шаблоне листа. Кроме того, если возможно, мне также нужно проверить первый столбец. Моим первым столбцом всегда должен быть столбец A3 = «Room» (иногда он находится в 1-м столбце из предоставленной таблицы, но иногда он находится в 4-м). Еще раз, 100 раз спасибо!!

Ответ №1:

Удалите столбцы, затем строки

Описание

  • Удаляет столбцы, которые в первой строке не содержат значений из списка. Затем удаляет строки, которые в первом столбце не содержат значений из другого списка.

Поток

  • Записывает значения из диапазона A2 до последней ячейки в Sheet3 Cols массив.
  • Записывает значения из диапазона A2 до последней ячейки в Sheet2 Agents массив.
  • Использование CurrentRegion определяет DataSet Range ( rng ) .
  • Перебирает ячейки ( cel ) в первой строке, начиная со 2-го столбца, и сравнивает их значения со значениями из Cols массива. Если не найдено, добавляет ячейки в Delete Range ( rngDel ).
  • Окончательно удаляет все столбцы «собранных» ячеек.
  • Перебирает ячейки ( cel ) в первом столбце, начиная со 2-й строки, и сравнивает их значения со значениями из Agents массива. Если не найдено, добавляет ячейки в Delete Range ( rngDel ).
  • Окончательно удаляет все строки «собранных» ячеек.
  • Информирует пользователя об успехе или отсутствии действий.

Код

 Option Explicit

Sub ModifyTICBData()

    ' Define workbook ('wb').
    Dim wb As Workbook
    Set wb = ThisWorkbook
    
    ' Define Columns List ('Cols').
    Dim ws As Worksheet
    Set ws = wb.Worksheets("Sheet3")
    Dim rng As Range
    Set rng = ws.Cells(ws.Rows.Count, "A").End(xlUp)
    Dim Cols As Variant
    Cols = ws.Range("A2", rng).Value
    
    ' Define Agents List ('Agents').
    Set ws = wb.Worksheets("Sheet2")
    Set rng = ws.Cells(ws.Rows.Count, "A").End(xlUp)
    Dim Agents As Variant
    Agents = ws.Range("A2", rng).Value
    
    ' Define DataSet Range ('rng').
    Set rng = wb.Worksheets("Template").Range("A1").CurrentRegion
    
    Application.ScreenUpdating = False
    
    ' Define Delete Range ('rngDel') for Columns.
    Dim rngDel As Range
    Dim cel As Range
    For Each cel In rng.Rows(1).Resize(, rng.Columns.Count - 1) _
                               .Offset(, 1).Cells
        If IsError(Application.Match(cel.Value, Cols, 0)) Then
            collectCells rngDel, cel
        End If
    Next cel
    ' Delete Columns.
    Dim AlreadyDeleted As Boolean
    If Not rngDel Is Nothing Then
        rngDel.EntireColumn.Delete
    Else
        AlreadyDeleted = True
    End If
    
    ' Define Delete Range ('rngDel') for Agents.
    Set rngDel = Nothing
    For Each cel In rng.Columns("A").Resize(rng.Rows.Count - 1) _
                                    .Offset(1).Cells
        If IsError(Application.Match(cel.Value, Agents, 0)) Then
            collectCells rngDel, cel
        End If
    Next cel
    ' Delete Agents (Rows).
    If Not rngDel Is Nothing Then
        rngDel.EntireRow.Delete
        AlreadyDeleted = False
    End If
    
    Application.ScreenUpdating = True

    ' Inform user
    If Not AlreadyDeleted Then
        MsgBox "The data was succesfully deleted.", vbInformation, "Success"
    Else
        MsgBox "The data had already been deleted.", vbExclamation, "No Action"
    End If
    
End Sub

Sub collectCells(ByRef CollectRange As Range, CollectCell As Range)
    If Not CollectCell Is Nothing Then
        If Not CollectRange Is Nothing Then
            Set CollectRange = Union(CollectRange, CollectCell)
        Else
            Set CollectRange = CollectCell
        End If
    End If
End Sub
  

Комментарии:

1. Это работает!!! Я просто адаптировал для каждого cel в rng. Столбцы («A») в столбец J, и это идеально. Отличные пояснения!! Большое вам спасибо!!!

2. Уважаемый, г-н @VBasic2008, однако возникает проблема, когда я копирую данные (только значения) в Excel, где у меня есть макрос. Четыре первых столбца следует удалить, так как первый столбец, который я хочу сохранить, называется «Room», но он оставляет один столбец раньше. Итак, мой столбец «Room», который должен быть A1, на самом деле равен B1). Есть ли что-нибудь, что я могу адаптировать, чтобы предотвратить это? Еще раз, 100 раз спасибо!!

3. Кроме того, к сожалению, мне приходится перемещать заголовки в строку 3. Я не могу его адаптировать… Я получаю сообщение об ошибке. Смещение (, 1).Ячейки