Удаление экземпляров символов с использованием массивов и циклов

У меня есть столбец, где почти каждая ячейка состоит из комбинации цифр и букв и символов ("ТС-403" или "ТСМ-7600"). Я хочу, чтобы каждый символ, который не является целым числом, был удален/заменен пустой строкой, чтобы у меня остались только числа ("403").

Я придумал два подхода:

Я думаю, что лучше всего создать массив целых чисел с числами 0-9, а затем выполнить итерацию по ячейкам с помощью цикла for, где, если строка в ячейке содержит символ, которого нет в массиве, тогда этот символ (не вся ячейка) должна быть стерта.

Sub fixRequestNmrs()

Dim intArr() as Integer
ReDim intArr(1 to 10)

    For i = 0 to 9
    intArr(i) = i
    Next i


Dim bRange as Range
Set bRange = Sheets(1).Columns(2)

For Each cell in bRange.Cells
if cell.Value 
// if cell includes char that is not in the intArr, 
// then that char should be deleted/replaced.
...

End Sub()

Возможно, второй подход проще: использовать функцию Split(), поскольку за «-» всегда следуют числа, а затем заменить первую подстроку на «». Я очень смущен тем, как использовать функцию Split() в сочетании с диапазоном и функцией замены...

For Each cell in bRange.Cells
Cells.Split(?, "-")
...

Если бы я использовал первый подход, я бы использовал ключи scripting.dictionary или arraylist для хранения чисел от 0 до 9. Это позволило бы мне проверить, является ли символ числом, используя метод .exists или .Contains. соответственно.

freeflow 20.11.2022 12:52
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
2
1
68
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Преобразование цифр в целое с помощью оператора Like

Функция

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Returns an integer composed from the digits of a string.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function DigitsToInteger(ByVal SearchString As String) As Long

    Dim ResultString As String
    Dim Char As String
    Dim n As Long
    
    For n = 1 To Len(SearchString)
        Char = Mid(SearchString, n, 1)
        If Char Like "[0-9]" Then ResultString = ResultString & Char
    Next n
    
    If Len(ResultString) = 0 Then Exit Function

    DigitsToInteger = CLng(ResultString)

End Function

Пример рабочего листа

Sub DigitsToIntegerTEST()

    Const FIRST_ROW As Long = 2

    ' Read: Reference the (single-column) range.
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
    
    Dim LastRow As Long: LastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
    If LastRow < FIRST_ROW Then Exit Sub ' no data
    
    Dim rg As Range: Set rg = ws.Range("B2", ws.Cells(LastRow, "B"))
    Dim rCount As Long: rCount = rg.Rows.Count
    
    ' Read: Return the values from the range in an array.
    
    Dim Data() As Variant
    
    If rCount = 1 Then
        ReDim Data(1 To 1, 1 To 1): Data(1, 1) = rg.Value
    Else
        Data = rg.Value
    End If
    
    ' Modify: Use the function to replace the values with integers.
    
    Dim r As Long
    
    For r = 1 To rCount
        Data(r, 1) = DigitsToInteger(CStr(Data(r, 1)))
    Next r
    
    ' Write: Return the modifed values in the range.
    
    rg.Value = Data
    ' To test the results in the column adjacent to the right, instead use:
    'rg.Offset(, 1).Value = Data

End Sub

В VBA (простой)

Sub DigitsToIntegerSimpleTest()
    Const S As String = "TSM-7600sdf"
    Debug.Print DigitsToInteger(S) ' Result 7600
End Sub

В Excel

=DigitsToInteger(A1)

Полезный подход + :) ... К вашему сведению, вам может быть интересна моя альтернатива через хитрое совпадение @VBasic

T.M. 20.11.2022 20:32

Если у вас есть функция CONCAT, вы можете сделать это с помощью относительно простой формулы — VBA не требуется:

=CONCAT(IFERROR(--MID(A1,SEQUENCE(LEN(A1)),1),""))

Если вы предпочитаете решение, отличное от VBA, в более ранней версии Excel, доступна более сложная формула, но мне придется вернуться к своим файлам, чтобы найти ее.

Элегантный и полезный способ +:)

T.M. 20.11.2022 20:33

Сложная функция GetVal()

Следующая функция

  • переводит строку в массив из одного символа arr с помощью функции справки String2Arr()
  • изолирует их в числовые (код категории 6) или нечисловые категории (другие) с помощью хитрого выполнения Application.Match (здесь без третьего аргумента, который в основном используется для точного поиска, и путем сравнения двух массивов)
  • находит начальную позицию в исходной строке через Instr()
  • возвращает значение правой подстроки через Val() (~> см. примечание).
Function GetVal(ByVal s As String) As Double
    Dim arr:      arr = String2Arr(s):      Debug.Print Join(arr, "|")
    Dim chars:    chars = Split(" ,',+,-,.,0,A", ",")
    Dim catCodes: catCodes = Application.Match(arr, chars)  'No 3rd zero-argument!!
    Dim tmp$:     tmp = Join(catCodes, ""): Debug.Print Join(catCodes, "|")
    Dim pos&:     pos = InStr(tmp, 6)   ' Pos 6: Digits; pos 1-5,7: other symbols/chars
    GetVal = Val(Mid(s, pos))           ' calculate value of right substring
End Function

Ноты

Функция Val может преобразовать (под)строку с начальными цифрами в число, даже если за ней следуют нечисловые символы.

Функция помощи String2Arr()

Разбивает строку на один массив символов:

Function String2Arr(ByVal s As String)
    s = StrConv(s, vbUnicode)
    String2Arr = Split(s, vbNullChar, Len(s) \ 2)
End Function

Пример вызова

    Dim s As String
    s = "aA+*&$%(y#,'/\)!-12034.56blabla"
    Debug.Print GetVal(s)          ' ~~> 12034.56

Другие вопросы по теме