Как я могу удалить столбцы без определенных заголовков? - PullRequest
0 голосов
/ 18 января 2019

Я пишу макрос VBA для Excel, чтобы удалить столбцы, для которых у меня нет определенных заголовков. Я подошел ближе, но столкнулся со странной проблемой, связанной со способом удаления столбцов.

Я использую простой вложенный IF. Странно, что когда я запускаю свой код, он удаляет только ДРУГОЙ столбец, которого нет в моем списке. Я должен запустить макрос 4 или 5 раз, чтобы получить желаемый результат. Этот код предназначен для того, чтобы быть частью более крупного макроса и для других пользователей, поэтому ключ к правильной работе с первого раза является ключевым.

Sub DeleteColumns()
Set MR = Range("A1:W1")
For Each cell In MR
    If cell.Value <> "Cartons" Then
        If cell.Value <> "ShipVia" Then
            If cell.Value <> "Name" Then
                If cell.Value <> "Address" Then
                    If cell.Value <> "City" Then
                        If cell.Value <> "State" Then
                            If cell.Value <> "Zip" Then
                                cell.EntireColumn.Delete
                            End If
                        End If
                    End If
                End If
            End If
        End If
    End If
    Next
End Sub

Ответы [ 2 ]

0 голосов
/ 19 января 2019

@ urdearboy абсолютно прав в своем диагнозе проблемы. Вот мое решение как вариация на тему Select Case, которая оказывается компактной и очень описательной (читабельной).

Sub DeleteColumns()
    Dim LastCol As Long
    Dim i As Long

    LastCol = ActiveSheet.Range("A1:W1").Cells.Count
    i = 1
    Do
        Select Case ActiveSheet.Cells(1, i)
        Case "Cartons", "ShipVia", "Name", "Address", "City", "State", "Zip"
            i = i + 1 ' this column is to remain; examine the next column
        Case Else
            ActiveSheet.Cells(1, i).EntireColumn.Delete
            LastCol = LastCol - 1 ' as you delete columns the right margin moves in
            ' do not increment "i" because the next column moves in place automatically
        End Select
    Loop Until i > LastCol
End Sub

Надеюсь, это поможет проиллюстрировать "механику" удаления столбцов.

Для большей эффективности в коде (в свете вышесказанного) нам нужно начинать справа, поэтому требуется только одна «позиционная» переменная:

Sub DeleteColumns()
    Dim i As Long

    i= ActiveSheet.Range("A1:W1").Cells.Count
    Do
        Select Case ActiveSheet.Cells(1, i)
        Case Is <> "Cartons", "ShipVia", "Name", "Address", "City", "State", "Zip"
            ActiveSheet.Cells(1, i).EntireColumn.Delete
        End Select
        i = i - 1 
    Loop While i > 0
End Sub

И, конечно, это можно легко обобщить для ситуаций, когда, например, диапазон не начинается в столбце «А» и т. Д.

0 голосов
/ 18 января 2019

Ваша проблема

Проблема, с которой вы сталкиваетесь, связана с тем, что вы удаляете столбцы внутри диапазона цикла.Когда вы удаляете столбец, диапазон, который вы циклически изменяете, приводит к пропуску столбцов (в соответствии с вашими результатами).Чтобы бороться с этим, вы можете использовать метод Union, который позволяет удалять столбцы вне цикла, чтобы вы не столкнулись с сообщенной проблемой.В нижнем решении показано, как исправить сообщенную проблему, если вы решите удалить столбцы внутри цикла.


Выберите вариант

Select Case.Выполните цикл по диапазону, и если ячейка отсутствует в списке в первом случае, она будет помечена для удаления во втором случае (Case Else).

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

Sub DeleteColumns()

Dim iCell As Range, DeleteMe As Range

For Each iCell In Range("A1:W1")
    Select Case iCell
        Case "Cartons", "ShipVia", "Name", "Address", "City", "State", "Zip"
            'Do Nothing
        Case Else
            If Not DeleteMe Is Nothing Then
                Set DeleteMe = Union(DeleteMe, iCell)
            Else
                Set DeleteMe = iCell
            End If
    End Select
Next iCell

If Not DeleteMe Is Nothing Then DeleteMe.EntireColumn.Delete

End Sub

Массив

Вы можететакже цикл через массив.Обратите внимание, что цикл столбца движется в обратном направлении, чтобы остановить смещение соответствующего диапазона внутри цикла (ваша первоначальная проблема).Для этого вам нужно сбросить цикл For Each и переключиться на For j = # - #, чтобы вы могли использовать свойство Step -1

Sub Array_Method()

Dim Arr: Arr = Array("Cartons", "ShipVia", "Name", "Address", "City", "State", "Zip")
Dim i As Long, j As Long

For j = 23 To 1 Step -1
    For i = UBound(Arr) To LBound(Arr)
        If Arr(i) = Cells(1, j) Then
            Cells(1, j).EntireColumn.Delete
        End If
    Next i
Next j

End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...