Как проверить наличие двух разных значений и удалить текст, где найдено одно из этих значений? - PullRequest
0 голосов
/ 23 января 2019

Я хочу найти «Ext» и «/» в столбце данных и удалить весь текст после и включая эти символы. Если он не находит эти символы в моих данных, выйдите из подпункта

Я могу сделать их отдельно, но я определенно слишком усложнил, должен быть более простой способ

Столбец данных также будет содержать пробелы, поэтому я должен избегать пустых ячеек и проверять весь диапазон данных

код

Sub DeleteAfterText()
    Dim rngFoundCell As Range
    Set rngFoundCell = Sheets("User Load").Range("E1:E3000").Find(What:="Ext")
    'This is checking to see if the range contains EXT, if not it exits the sub'
    If rngFoundCell Is Nothing Then 'If no cell in the range has an ' then exist sub
        Exit Sub
    Else
        Worksheets("User Load").Range("E1000").Select 'Start from bottom'
        Selection.End(xlUp).Select  'This selects the bottom to the top'
        Do Until ActiveCell.Value = "Phone Number"    'This does the change until it reaches the header name'
            If ActiveCell.Value = "" Then     'If the cell is blank it skips it as there is no action after the then'
            Else
                ActiveCell = Split(ActiveCell.Value, "Ext")(0)
                'ActiveCell = Split(ActiveCell.Value, "/")(0)
            End If
            ActiveCell.Offset(-1, 0).Select
        Loop    
    End If
End Sub

Sub DeleteAfterText2()
    Dim rngFoundCell As Range
    Set rngFoundCell = Sheets("User Load").Range("E1:E3000").Find(What:="/")
    'This is checking to see if the range contains EXT, if not it exits the sub'
    If rngFoundCell Is Nothing Then 'If no cell in the range has an ' then exist sub
    Exit Sub
    Else
        Worksheets("User Load").Range("E1000").Select 'Start from bottom'
        Selection.End(xlUp).Select  'This selects the bottom to the top'
        Do Until ActiveCell.Value = "Phone Number"    'This does the change until it reaches the header name'
            If ActiveCell.Value = "" Then     'If the cell is blank it skips it as there is no action after the then'
            Else
                ActiveCell = Split(ActiveCell.Value, "/")(0)
            End If
            ActiveCell.Offset(-1, 0).Select
        Loop    
    End If
End Sub

Ответы [ 3 ]

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

Я собираюсь дать вам два ответа по цене одного. :)

В своей основе базовая логика, которую необходимо выяснить, если подстрока существует в данной строке, является стандартной частью VBA в функции InStr . Используя это, вы можете разбить свою логику, чтобы проверить значение ячейки и (условно) удалить остаток строки в функцию, подобную этой:

Private Function DeleteTextAfter(ByVal contents As String, _
                                 ByVal token As String) As String
    '--- searches the given string contents and if it finds the given token
    '    it deletes the token and all following characters
    DeleteTextAfter = contents

    Dim pos1 As Long
    pos1 = InStr(1, contents, token, vbTextCompare)
    If pos1 > 0 Then
        DeleteTextAfter = Left(contents, pos1 - 1)
    End If
End Function

Обратите внимание, что при использовании функции, созданной выше, нам не нужно вообще использовать Range.Find.

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

Dim thisWB As Workbook
Dim userLoadWS As Worksheet
Set thisWB = ThisWorkbook
Set userLoadWS = thisWB.Sheets("User Load")

Dim searchRange As Range
Set searchRange = userLoadWS.Range("E1:E3000")

Теперь цикл проходит через каждую ячейку и получает (потенциально) обновленное значение.

Dim cell As Variant
For Each cell In searchRange
    If Not cell.value = vbNullString Then
        Debug.Print cell.Address & " = " & cell.value
        cell.value = DeleteTextAfter(cell.value, "Ext")
        cell.value = DeleteTextAfter(cell.value, "/")
    End If
Next cell

Итак, все ваше решение выглядит так:

Option Explicit

Public Sub TestDirectlyFromRange()
    Dim thisWB As Workbook
    Dim userLoadWS As Worksheet
    Set thisWB = ThisWorkbook
    Set userLoadWS = thisWB.Sheets("User Load")

    Dim searchRange As Range
    Set searchRange = userLoadWS.Range("E1:E3000")

    Dim cell As Variant
    For Each cell In searchRange
        If Not cell.value = vbNullString Then
            Debug.Print cell.Address & " = " & cell.value
            cell.value = DeleteTextAfter(cell.value, "Ext")
            cell.value = DeleteTextAfter(cell.value, "/")
        End If
    Next cell
End Sub

Private Function DeleteTextAfter(ByVal contents As String, _
                                 ByVal token As String) As String
    '--- searches the given string contents and if it finds the given token
    '    it deletes the token and all following characters
    DeleteTextAfter = contents

    Dim pos1 As Long
    pos1 = InStr(1, contents, token, vbTextCompare)
    If pos1 > 0 Then
        DeleteTextAfter = Left(contents, pos1 - 1)
    End If
End Function

Но подождите, это еще не все !!

Вы перебираете более 3000 строк данных. Это может стать медленным, если все эти строки заполнены или если вы увеличите количество строк для поиска. Чтобы ускорить поиск, ответ заключается в том, чтобы сначала скопировать данные в диапазоне в массив на основе памяти , изменить любые данные, а затем скопировать результаты обратно. В этом примере используется тот же Function DeleteTextAfter, что и выше, и он работает намного быстрее. Используйте тот, который подходит вам лучше всего.

Public Sub TestRangeInArray()
    Dim thisWB As Workbook
    Dim userLoadWS As Worksheet
    Set thisWB = ThisWorkbook
    Set userLoadWS = thisWB.Sheets("User Load")

    '--- create the range and copy into a memory array
    Dim searchRange As Range
    Dim searchData As Variant
    Set searchRange = userLoadWS.Range("E1:E3000")
    searchData = searchRange.value

    Dim i As Long
    For i = LBound(searchData, 1) To UBound(searchData, 1)
        If Not searchData(i, 1) = vbNullString Then
            searchData(i, 1) = DeleteTextAfter(searchData(i, 1), "Ext")
            searchData(i, 1) = DeleteTextAfter(searchData(i, 1), "/")
        End If
    Next i

    '--- now copy the modified array back to the worksheet range
    searchRange.value = searchData
End Sub
0 голосов
/ 23 января 2019

Этот код должен работать.Это просто читать и легко понять.

    Option Explicit

    'The calling Sub
    Sub main()
        DeleteTextFromColumn ActiveSheet.Range("E1:E3000")
    End Sub

    Sub DeleteTextFromColumn(ByRef inRange As Range)

        Dim cCell As Range
        Dim intPos1 As Integer
        Dim intPos2 As Integer
        Dim strTemp As String
        Dim strOut As String

        'You can specify which column if more than one column is provided to the
        '  subroutine. Ex: Range("E1:F3000")
        For Each cCell In inRange.Columns(1).Cells
            strTemp = cCell.Value
            'gets the position of "ext" (case insensitive)
            intPos1 = InStr(LCase(strTemp), "ext")
            'gets the position of "/"
            intPos2 = InStr(strTemp, "/")

            strOut = strTemp
            If intPos1 > 1 Then
                strOut = Mid(strTemp, 1, intPos1 - 1)
            ElseIf intPos2 > 1 Then
                strOut = Mid(strTemp, 1, intPos2 - 1)
            End If

            'Outputs the results
            cCell.Value = strOut
        Next

    End Sub
0 голосов
/ 23 января 2019

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

Вы можете сделать что-то вроде этого:

Sub Tester()
    Dim theRange As Range
    Set theRange = Sheets("User Load").Range("E1:E3000")
    RemoveTextAfter theRange, "Ext"
    RemoveTextAfter theRange, "/"
End Sub

Sub RemoveTextAfter(rng As Range, findWhat As String)
    Dim f As Range
    If Len(findWhat) = 0 Then Exit Sub
    Set f = rng.Find(What:="Ext", lookat:=xlPart)
    Do While Not f Is Nothing
        f.Value = Split(f.Value, findWhat)(0)
        Set f = rng.Find(What:="Ext", lookat:=xlPart)
    Loop
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...