Макрос Excel для поиска нескольких URL-адресов в одном столбце

У меня есть рабочий лист (Sheet2), содержащий 27 столбцов, первая строка - это заголовки столбцов, которые составляют A-Z и NUM, всего 27 столбцов. В каждом столбце есть очень длинный список запрещенных URL-адресов, отсортированных по букве столбца, а последний (27-й) столбец предназначен для URL-адресов, начинающихся с числа. Длина столбцов составляет от 300 до 600 тысяч ячеек.

Я искал макрос-скрипт, который проверяет все недавно добавленные URL-адреса в столбце A Sheet1, чтобы выяснить, существуют ли они в Sheet2, в результате чего каждый URL-адрес помечается как «уже существует» или «должен быть добавлен», что-то вроде :

Лист1

Col(A)          Col(B)
badsite1.com    already exist
badsite2.com    already exist
badsite3.com    to be added
badsite4.con    to be added
badsite5.com    already exist

Соответственно, "подлежащие добавлению" URL-адреса будут добавлены в Sheet2 после запуска другого онлайн-теста для этого URL-адреса.

Удивительно, но я нашел следующий скрипт (пропустил его источник), который делает именно то, что я, после внесения некоторых незначительных изменений:

Sub x()

Dim rFind As Range, sFind As Range, sAddr As String, ws As Worksheet, rng As Range, ms     As Worksheet
Application.ScreenUpdating = 0
Set ws = Sheets("Sheet2")
Set ms = Sheets("Sheet1")
ms.Range("B2:B" & Rows.Count).ClearContents
Set rng = ms.Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row)

For Each sFind In rng
    With ws.UsedRange
        Set rFind = .Find(sFind, .Cells(.Cells.Count), xlValues, xlPart)
        If Not rFind Is Nothing Then
            sAddr = rFind.Address
            Do
                sFind.Offset(, 1) = rFind.Address
                sFind.Font.Color = -16776961
                Set rFind = .FindNext(rFind)
            Loop While rFind.Address <> sAddr
            sAddr = ""
            Else
            sFind.Offset(, 1) = "No Found"
            sFind.Offset(, 1).Font.Color = -16776961
        End If
    End With
Next
Set ms = Nothing
Set ws = Nothing
Set rng = Nothing
Set rFind = Nothing
Application.ScreenUpdating = True
End Sub 

Запуск этого скрипта просто фантастический с небольшим списком URL-адресов (например, 5-10). С более длинным списком в Sheet1 col-A и ОГРОМНЫМИ списками в Sheet2, как у меня, этот скрипт представляет собой "черепаху", и ему потребовалось более часа, чтобы изучить список из 167 URL-адресов !!

Можно ли сделать этот сценарий "кроликом"? :)

Высоко признателен за любую предложенную помощь в этом отношении.

Как обычно .. заранее спасибо.


person Josef Miller    schedule 15.04.2013    source источник
comment
Насколько я понял, я бы использовал тот же сценарий, но без .FindNext См. Раздел 4 в этой ссылке siddharthrout.com/2011/07/14/find-and-findnext-in-excel-vba EDIT: Если вы все еще застряли, возможно, я смогу увидеть образец и тогда мы сможем взять это оттуда?   -  person Siddharth Rout    schedule 15.04.2013
comment
Вас интересует только то, найдено ли оно в Sheet1? Или важен последний адрес ячейки? Потому что, если URL-адрес существует несколько раз, он проходит через все и дает вам только последний адрес. Исходя из этого, я могу предположить ...   -  person glh    schedule 15.04.2013
comment
Также у вас есть формулы?   -  person glh    schedule 15.04.2013
comment
Фактически, Sheet1 предназначен только для того, чтобы иметь новый список URL-адресов и отображать результат процесса поиска рядом с каждым URL-адресом, как в приведенном выше примере. Поэтому мне интересно узнать, существует ли URL-адрес в SHEET2 или нет. Все URL-адреса в Sheet2 уникальны; ноль дубликатов. Таким образом, как только URL-адрес найден, он будет найден один раз. Sheet2 не имеет никаких формул, только данные, и Sheet1 не имеет. Мне интересно узнать о вашем предложении, расставленном точками glb :). Я также читаю, чтобы понять, что предложил Сиддхарт Рут, большое спасибо вам обоим за ваш бесценный вклад.   -  person Josef Miller    schedule 15.04.2013


Ответы (1)


Попробуйте это - протестировано в Excel 2010:

Sub x()

Dim rFind As Range, sFind As Range, sAddr As String, ws As Worksheet
Dim rng As Range, ms As Worksheet, s As String
Application.ScreenUpdating = False
'stop calculation
Application.Calculation = xlCalculationManual
Set ws = Sheets("Sheet2")
Set ms = Sheets("Sheet1")
ms.Range("B2:B" & ms.Rows.Count).ClearContents
ms.Range("A2:B" & ms.Rows.Count).Font.Color = 0
Set rng = ms.Range("A2:A" & ms.Cells(ms.Rows.Count, 1).End(xlUp).Row)

For Each sFind In rng
    'get first character of url
    s = Left(sFind, 1)
    'resort to column aa if not a a to z
    If Asc(UCase(s)) < 65 Or Asc(UCase(s)) > 90 Then s = "AA"
    'only look in appropriate column
    Set rFind = ws.Columns(s).Find(sFind, , xlValues, xlPart, xlByRows, xlPrevious)
    If Not rFind Is Nothing Then
        'only look once and save that cell ref
        sFind.Offset(, 1) = rFind.Address
        sFind.Font.Color = -16776961
    Else
        'if not found put default string
        sFind.Offset(, 1) = "No Found"
        sFind.Offset(, 1).Font.Color = -16776961
    End If
Next
Set ms = Nothing
Set ws = Nothing
Set rng = Nothing
Set rFind = Nothing
'enable calculation
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

введите описание изображения здесь

Без VBA - проверено в Excel 2010:

=IFERROR(VLOOKUP(A2, INDIRECT("Sheet2!" & IF(OR(CODE(UPPER(LEFT(A2, 1)))<65,
    CODE(UPPER(LEFT(A2, 1)))>90), "AA:AA", LEFT(A2, 1)&":"& LEFT(A2, 1))), 1, FALSE), 
    "Not Found")
person glh    schedule 15.04.2013
comment
Я исправил несколько ошибок, и теперь я добавил несколько замечаний - person glh; 15.04.2013
comment
Спасибо, glh, за оперативную помощь. Фактически, как только он запускается, он останавливается с предупреждением, что ошибка компиляции: подпрограмма или функция не определена, выделяя верхнюю часть в коде If (верхняя часть (и)). Какие-либо предложения? - person Josef Miller; 15.04.2013
comment
Ucase() я думаю. Думаю, я был на полпути между Oracle sql и vba;) - person glh; 15.04.2013
comment
Genius glh, теперь это настоящий кролик. Просто протестировал его на 186 новых URL-адресов, и это заняло почти одну минуту, потрясающе. Большое спасибо, glh за ваше время и усилия, потраченные на такой шедевр. - person Josef Miller; 15.04.2013
comment
Добро пожаловать. Только помните, что в черепахе против зайца черепаха выиграла! ...;) - person glh; 15.04.2013
comment
Уважаемый Glh, поскольку я использую ваш код уже несколько дней, я заметил, что в столбцах Sheet2 выполняется поиск до тех пор, пока строка 276759 и значения (URL-адреса), начиная с строки или (ячейки) с номером 276760, не считаются несуществующими и, соответственно, не найдены отображается, несмотря на то, что они существуют, поскольку в одном столбце может быть больше 600 000 записей. Какие-либо предложения? Большое спасибо.. - person Josef Miller; 26.04.2013
comment
Вы используете решение VBA или не VBA? - person glh; 27.04.2013
comment
Я не вижу причин для его неудачи. Вы уверены, что их не существует? - person glh; 27.04.2013
comment
Я использую ваш шедевральный код, который является решением VBA. Я бы предварительно предложил вам создать тестовый Sheet2 с 27 столбцами, в одном из них будет более 300000 записей, и попытаться проверить наличие, скажем, 10 записей в этом длинном столбце, которые находятся перед номером записи 276759, скопировав их в Sheet1 и запустив код. А затем еще 10 записей, начиная с 276760, где выполняется то же тестирование. Ваши результаты покажут, если я что-то не так делаю со своим листом. Мои наилучшие пожелания и благодарность. - person Josef Miller; 27.04.2013
comment
Я скопировал ваш обновленный код в ответ и запустил его. Удивительно, но он остановился для отладки на: Set rFind = ws.Range (s &: & s) .Find (sFind, ws.Range (s & 1), xlValues, xlParts, xlByRows, xlPrevious). Затем я сравнил его с вашим кодом на картинке, который, к сожалению, мне не удалось прокрутить вправо, и обнаружил, что эта строка отличается от строки в коде ответа. Не могли бы вы обновить эту спорную строчку, чтобы я мог обновить свою? Весьма признателен. - person Josef Miller; 27.04.2013
comment
Более чем фантастический glh, действительно фантастический. Я очень благодарен. Примите мои наилучшие пожелания. - person Josef Miller; 28.04.2013