Извлечь 5-значное число из одного столбца в другой

Мне нужна помощь в извлечении 5-значных чисел только из одного столбца в другой в Excel 2010. Эти числа могут быть в любой позиции строки (в начале строки, в любом месте в середине или в конце). Они могут быть заключены в скобки или кавычки, например:

(15478) or "15478" or '15478' or [15478]

Мне нужно игнорировать любые числа, которые содержат менее 5 цифр и включают числа, начинающиеся с 1 или более начальных нулей (например, 00052, 00278 и т. д.), и убедиться, что начальные нули копируются в следующий столбец. Может ли кто-нибудь помочь мне с созданием формулы или UDF?


person Annette O.    schedule 09.03.2015    source источник
comment
я помогу, потому что я знаю, как раздражает это делать в Excel, мне просто нужно знать - будет ли в строке больше 1? это не было ясно   -  person Steven Martin    schedule 10.03.2015
comment
Я думаю, что ответ @Steven Martin работает нормально.   -  person shA.t    schedule 10.03.2015
comment
Только один — мы пытаемся скопировать номера сотрудников из поля «Описание», которое содержит другую информацию, такую ​​​​как имена, должности, местоположения и т. Д., В отдельный столбец.   -  person Annette O.    schedule 10.03.2015
comment
Только один — мы пытаемся скопировать номера сотрудников из поля «Описание», которое содержит другую информацию, такую ​​​​как имена, должности, местоположения и т. Д., В отдельный столбец.   -  person Annette O.    schedule 10.03.2015


Ответы (3)


Вот альтернатива на основе формулы, которая извлечет первое 5-значное число, найденное в ячейке A1. В большинстве ситуаций я предпочитаю достаточно простые решения формул, а не VBA, поскольку формулы более переносимы. Эта формула является формулой массива и поэтому должна быть введена с помощью Ctrl+Shift+Enter. Идея состоит в том, чтобы разбить строку на все возможные фрагменты из 5 символов, проверить каждый из них и вернуть первое совпадение.

=MID(A1,MIN(ЕСЛИ(НЕ(ЕОШИБКА(("1"&MID(A1,СТРОКА(ДВССЫЛ("R1C[1]:R"&(LEN(A1)-4)&"C[1)", ЛОЖЬ)),5)&".1")*1))*ЕОШИБКА(СРЕДН(A1,СТРОКА(ДВССЫЛ("R1C[1]:R"&(LEN(A1)-4)&"C[1] ",ЛОЖЬ))+5,1)*1)*ЕОШИБКА(СРЕДН(A1,СТРОКА(ДВССЫЛ("R1C[1]:R"&(ДЛСТР(A1)-4)&"C[1]",ЛОЖЬ) ))-1,1)*1),СТРОКА(ДВССЫЛ("R1C[1]:R"&(LEN(A1)-4)&"C[1]",FALSE)),9999999999)),5)

Давайте разберем это. Во-первых, у нас есть выражение, которое я использовал дважды, чтобы вернуть массив чисел от 1 до 4 меньше, чем длина исходного текста. Итак, если у вас есть строка длиной 10, следующее вернет {1,2,3,4,5,6}. В дальнейшем приведенная ниже формула будет называться rowlist. Я использовал нотацию R1C1, чтобы избежать возможных циклических ссылок.

ROW(INDIRECT("R1C[1]:R"&(LEN(A1)-4)&"C[1]",FALSE))

Далее мы будем использовать этот массив, чтобы разделить текст на массив из 5 фрагментов букв и протестировать каждый фрагмент. Выполняемый тест состоит в том, чтобы добавить «1» и «.1», а затем убедиться, что фрагмент является числовым. Добавление и добавление исключают возможность использования пробелов или десятичных знаков. Затем мы можем проверить символ до и символ после, чтобы убедиться, что они не являются числами. В дальнейшем приведенная ниже формула будет называться isnumarray.

NOT(ISERROR(("1"&MID(A1,rowlist,5)&".1")*1))
*ISERROR(MID(A1,rowlist+5,1)*1)
*ISERROR(MID(A1,rowlist-1,1)*1)

Далее нам нужно найти первое действительное 5-значное число в строке, возвращая текущий индекс из дубликата формулы rowlist и возвращая большое число для несоответствий. Затем мы можем использовать функцию MIN, чтобы получить это первое совпадение. В дальнейшем нижеследующее будет называться мининдекс.

MIN(IF(isnumarray,rowlist,9999999999))

Наконец, нам нужно получить числовую строку, начинающуюся с индекса, возвращаемого функцией MIN.

MID(A1,minindex,5)
person Mark Balhoff    schedule 10.03.2015
comment
Ваша формула также возвращает первые пять цифр шестизначного числа. - person Ron Rosenfeld; 10.03.2015
comment
@RonRosenfeld Я понял, что его не беспокоит слишком много цифр (только слишком мало), потому что мне нужно игнорировать любые числа, которые состоят менее чем из 5 цифр, и включают числа, начинающиеся с 1 или более ведущих нулей (например, 00052, 00278 и т. д.). .) и убедитесь, что ведущие нули копируются в следующий столбец. - person Mark Balhoff; 10.03.2015
comment
И я предположил, что пятизначное число было пятизначным числом, а не частью более длинной цепочки чисел. ИЛИ может случиться так, что в его данных никогда не будет более пяти цифр подряд, и в этом случае это не имеет значения. Если ваше предположение верно, существует решение без массива. - person Ron Rosenfeld; 10.03.2015
comment
@RonRosenfeld Да, ОП должен уточнить. Но в вашем последнем утверждении заключается то, что я прочитал в его явном вызове из менее чем 5 цифр, несмотря на то, что это менее очевидная путаница, чем более 5 цифр. Если ему действительно нужно то, что вы предлагаете, изменение моей формулы будет минимальным. Только еще одно условие. - person Mark Balhoff; 10.03.2015
comment
@RonRosenfeld исправил это (при условии, что OP этого хочет). - person Mark Balhoff; 10.03.2015
comment
Я бы также добавил, что мне нужно извлечь 5 цифр, которые собираются вместе, поэтому в строке клерка Марка Джонса 2007 года 45238 мне нужна часть 45238, а не 2007 и 4 - person Annette O.; 10.03.2015
comment
Спасибо! Я попробовал формулу, учитывая, что мои данные начинаются с позиции D2: = MID (D2, MIN (IF (NOT (ISERROR ((1 & MID (D2, ROW) (ДВССЫЛ (R1C [1]): R & (LEN (D2) -4) &C[1],ЛОЖЬ)),5)&.1)*1))*ЕОШИБКА(СРЕДН(D2,СТРОКА(ДВССЫЛ(R1C[1]):R&(ДЛСТР(A1)-4)&C[1],ЛОЖЬ ))+5,1)*1)*ISERROR(MID(D2,СТРОКА(ДВССЫЛ(R1C[1]:R&(LEN(D2)-4)&C[1],FALSE))-1,1)*1 ),СТРОКА(ДВССЫЛ(R1C[1]:R&(LEN(D2)-4)&C[1],FALSE)),9999999999)),5) Я получаю #ЗНАЧ! вывод в следующем столбце.. Что-то я сделал не так? - person Annette O.; 10.03.2015
comment
@Annette Вы нажимали ctrl+shift+enter при выходе из ячейки с формулой, а не просто ввод? Какое значение в D2? - person Mark Balhoff; 10.03.2015
comment
Привет! Я не очень разбираюсь в формулах - заранее извиняюсь. Данные в столбце d, и мне нужны мои числа в столбце E. Поэтому я нажал на E2 и вставил формулу в строку формул вверху и горячий ввод. Затем щелкнул E2 и перетащил его примерно на 20 строк вниз. Первая запись (D2) имеет строку Copyright 2007 и не должна иметь никакого значения в E2. У Next One есть Brenda ANGELES 63215 - я ожидаю увидеть 63215 на E2.... - person Annette O.; 10.03.2015
comment
@АннетО. Вы пропустили перевод A1 --› D2. Вы видите Лена (A1-4) в формуле, которую вы разместили ?? Это должен быть Лен(D2-4). Измените это, и формула будет работать. - person Mark Balhoff; 10.03.2015
comment
@АннетО. =MID(D2,MIN(IF(NOT(ISERROR(("1"&MID(D2,ROW(INDIRECT("R1C[1]:R"&(LEN(D2)-4)&"C[1]",FALSE)),5)&".1")*1))*ISERROR(MID(D2,ROW(INDIRECT("R1C[1]:R"&(LEN(D2)-4)&"C[1]",FALSE))+5,1)*1)*ISERROR(MID(D2,ROW(INDIRECT("R1C[1]:R"&(LEN(D2)-4)&"C[1]",FALSE))-1,1)*1),ROW(INDIRECT("R1C[1]:R"&(LEN(D2)-4)&"C[1]",FALSE)),9999999999)),5) - person Mark Balhoff; 10.03.2015
comment
Спасибо! Пропустил это .. все еще получаю #VALUE! во всех ячейках столбца E... Вот небольшой набор данных, из которых я пытаюсь получить числа: - person Annette O.; 10.03.2015
comment
cccccc cccccccccc (19416) ddddddddd dddd 32554 eeeeeee (51503) eeeeeee (15139) fff ffffff 0123 ggggg hhhhhh (52416) hhhhhhh hhhhhhhh (52407) kkkkkk kkkkkk 37410 kkkkkk kkkkk (MG23) rrrrr rrrrr 49933 lllll lllll x5236 vvvvv vvvvv (55266) zzzzz zzzz (45828) гггг гггг 37995 - person Annette O.; 10.03.2015
comment
мой последний комментарий вышел в виде одной длинной строки. По большей части каждая запись заканчивается числом, будь то EMPLID, добавочный номер, код местоположения или номер POS.. - person Annette O.; 10.03.2015
comment
@АннетО. Я посмотрю, когда вернусь с обеда. - person Mark Balhoff; 10.03.2015
comment
@АннетО. Если вы не нажмете Ctrl+Shift+Enter после завершения вставки формулы, вы получите #ЗНАЧ. Вы абсолютно уверены, что нажимаете Ctrl+Shift+Enter, чтобы выйти из режима редактирования E2, а не просто Enter??? - person Mark Balhoff; 10.03.2015

Следующая определяемая пользователем функция возвращает первое пятизначное число в строке, включая все начальные нули. Если вам нужно определить, есть ли более одного пятизначного числа, изменения тривиальны. Он вернет ошибку #VALUE!, если пятизначных чисел нет.

Option Explicit
Function FiveDigit(S As String, Optional index As Long = 0) As String
    Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
With RE
    .Pattern = "(?:\b|\D)(\d{5})(?:\b|\D)"
    .Global = True
        FiveDigit = .Execute(S)(index).submatches(0)
End With
End Function

Как вы могли заметить из обсуждения между мной и Марком, некоторые из ваших спецификаций неясны. Но если вы хотите исключить десятичные числа, когда десятичная часть состоит из пяти цифр, шаблон регулярного выражения в моем коде выше должен быть изменен:

.Pattern = "(?:\d+\.\d+)|(?:\b|\D)(\d{5})(?:\b|\D)"
person Ron Rosenfeld    schedule 10.03.2015
comment
Обе ваши формулы найдут такие строки, как 0,015 и -1500. Ни то, ни другое недействительно - person Mark Balhoff; 10.03.2015
comment
Это правда. Хороший пикап. Решение с регулярным выражением более надежное и простое. Я удалю формулы. - person Ron Rosenfeld; 10.03.2015
comment
@MarkBalhoff О, и ваши формулы, и мое регулярное выражение вернут 23456 в 1.23456. - person Ron Rosenfeld; 10.03.2015
comment
Хм... правда. Хорошая точка зрения. Напрашивается вопрос: должен ли dfskf .32322 возвращать 32322 или обрабатывать его как 0,32322 и возвращать ошибку? - person Mark Balhoff; 10.03.2015
comment
Я не знаю. Очевидно, мы просто играем, пока не получим разъяснения от ОП. - person Ron Rosenfeld; 10.03.2015
comment
Я не думаю, что у нас есть какие-либо десятичные числа в этом поле, так что это не будет проблемой. EmployeeID — это 5-значные числа, которые нам нужны. Но в данных может быть номер POS, код местоположения или год, созданные в данных, которые я должен игнорировать - это менее 5 цифр. - person Annette O.; 10.03.2015

Я только что написал для вас эту UDF, базовую, но сделаю это...

Он найдет первые 5 последовательных чисел в строке, очень грубая проверка ошибок, поэтому он просто говорит «Ошибка», если что-то не так.

Public Function GET5DIGITS(value As String) As String
    Dim sResult As String
    Dim iLen As Integer
    sResult = ""
    iLen = 0

    For i = 1 To Len(value)       
        If IsNumeric(Mid(value, i, 1)) Then
            sResult = sResult & Mid(value, i, 1)
            iLen = iLen + 1
        Else
            sResult = ""
            iLen = 0
        End If
        If iLen = 5 Then Exit For
    Next

    If iLen = 5 Then
        GET5DIGITS = Format(sResult, "00000")
    Else
        GET5DIGITS = "Error"
    End If
End Function
person Steven Martin    schedule 09.03.2015
comment
Ваш UDF также вернет первые пять цифр шестизначного числа. - person Ron Rosenfeld; 10.03.2015
comment
Да, это так, я написал это, первые 5 последовательных, если ОП ответит на мой вопрос, я могу изменить - person Steven Martin; 10.03.2015
comment
Большое спасибо за помощь! Я бы также добавил, что мне нужно извлечь 5 цифр, которые соединяются без пробелов или других символов между ними, поэтому в строке клерка Марка Джонса 2007 года 45238 мне нужна часть 45238, а не 2007 и 4 - person Annette O.; 10.03.2015