Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.04.2012, 17:16   #1
Vja4eslav
Пользователь
 
Регистрация: 13.08.2011
Сообщений: 90
Вопрос Как считать в массив и найти дубли

Добрый всем день!
Написал макрос, который ищет: есть ли дубли в стобце и заливает цветом ячейки с дублями. Если количество строк небольшое (до 1000), то время выполнения программы устраивает, а если строк несколько десятков тысяч, то время очень не устраивает. Предполагаю, что надо диапазон считать в массив и в нём уже перебирать.Т.к. VBA осваиваю самостоятельно, методом тыка, то нужных знаний не хватает, если кто- то может помочь, то очень вас прошу.
Код, который я написал вот он:

Sub Найти_дубли()
Dim i As Long, ii As Long, sch As Long, ARange As Range, a As Range, oRow As Long, str As Long
Application.ScreenUpdating = False
Tm = Timer
For str = 65536 To 5 Step -1
If Cells(str, 3).Value <> vbNullString Then str = str: Exit For
Next
Set ARange = Range(Cells(5, 3), Cells(str, 3))
For Each a In ARange
a = Application.WorksheetFunction.Trim( a)
Next
ARange.Interior.ColorIndex = xlNone

''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''
i = 5
Do
ii = i + 1
Do
If Cells(ii, 3).Interior.ColorIndex = 3 Then GoTo dalee
If Cells(i, 3).Value = Cells(ii, 3).Value Then
Cells(i, 3).Interior.ColorIndex = 3
Cells(ii, 3).Interior.ColorIndex = 3
End If
dalee:
ii = ii + 1
Loop While ii <= str
Application.StatusBar = "Обрабатывается " & i - 4 & " строка из " & str - 4
i = i + 1
Loop While i <= str
''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''


pipec:
With Application
.ScreenUpdating = False
.StatusBar = False
End With
MsgBox (Timer - Tm)
End Sub
Vja4eslav вне форума Ответить с цитированием
Старый 30.04.2012, 17:50   #2
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

Попробуйте так:
Код:
Sub Найти_дубли2()
Dim x, i As Long, s As String
Application.ScreenUpdating = False
With Range("C5", Cells(Rows.Count, 3).End(xlUp))
    .Interior.ColorIndex = xlNone
    x = .Value
End With
On Error Resume Next
With New Collection
    For i = 1 To UBound(x)
        s = Trim(x(i, 1))
        If IsEmpty(.Item(s)) Then
            .Add 1, s
        Else
            Cells(i + 4, 3).Interior.ColorIndex = 3
        End If
    Next i
End With
Application.ScreenUpdating = True
End Sub
или вот так по-модному
Код:
Sub ertert()
Dim x, i As Long: Application.ScreenUpdating = 0
With Range("C5", Cells(Rows.Count, 3).End(xlUp))
    .Interior.ColorIndex = xlNone
    x = Application.Trim(.Value)
End With
With CreateObject("System.Collections.ArrayList")
    For i = 1 To UBound(x)
        If Not .Contains(x(i, 1)) Then
            .Add x(i, 1)
        Else
            Cells(i + 4, 3).Interior.ColorIndex = 3
        End If
    Next
End With: Application.ScreenUpdating = 1
End Sub

Последний раз редактировалось nilem; 30.04.2012 в 18:00.
nilem вне форума Ответить с цитированием
Старый 30.04.2012, 18:07   #3
Vja4eslav
Пользователь
 
Регистрация: 13.08.2011
Сообщений: 90
По умолчанию

Спасибо, nilem! А как подправить Ваш код, чтобы он закрашивал обе одинаковые ячейки ?
Vja4eslav вне форума Ответить с цитированием
Старый 30.04.2012, 18:19   #4
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

наверное, так
Код:
Sub Найти_дубли3()
Dim x, i As Long, k As Long, s As String
Application.ScreenUpdating = False
With Range("C5", Cells(Rows.Count, 3).End(xlUp))
    .Interior.ColorIndex = xlNone
    x = .Value
End With
On Error Resume Next
With New Collection
    For i = 1 To UBound(x)
        s = Trim(x(i, 1))
        If IsEmpty(.Item(s)) Then
            .Add i, s
        Else
            Cells(i + 4, 3).Interior.ColorIndex = 3
            k = .Item(s)
            Cells(k + 4, 3).Interior.ColorIndex = 3
        End If
    Next i
End With
Application.ScreenUpdating = True
End Sub
nilem вне форума Ответить с цитированием
Старый 30.04.2012, 18:42   #5
Vja4eslav
Пользователь
 
Регистрация: 13.08.2011
Сообщений: 90
По умолчанию

Спасибо ! Способ, который "по-модному" мне больше понравился из-за отсутствия On Error Resume Next, если Вас не затруднит, немогли бы Вы, пожалуйста, в нём дописать закраску обеих ячеек ?
Vja4eslav вне форума Ответить с цитированием
Старый 30.04.2012, 19:46   #6
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

Дело в том, что у ArrayList есть только ключи, айтемз нет (в этом случае нужны коллекции типа SortedList), поэтому давайте возьмем словарь (тоже пока еще в моде)
Код:
Sub ertert2()
Dim x, i As Long, k As Long: Application.ScreenUpdating = 0
With Range("C5", Cells(Rows.Count, 3).End(xlUp))
    .Interior.ColorIndex = xlNone
    x = Application.Trim(.Value)
End With
With CreateObject("Scripting.Dictionary")
    For i = 1 To UBound(x)
        If Not .Exists(x(i, 1)) Then
            .Item(x(i, 1)) = i
        Else
            Cells(i + 4, 3).Interior.ColorIndex = 3
            k = .Item(x(i, 1))
            Cells(k + 4, 3).Interior.ColorIndex = 3
        End If
    Next
End With: Application.ScreenUpdating = 1
End Sub
nilem вне форума Ответить с цитированием
Старый 30.04.2012, 19:49   #7
Vja4eslav
Пользователь
 
Регистрация: 13.08.2011
Сообщений: 90
По умолчанию

Очень Вам благодарен, nilem !!!
Vja4eslav вне форума Ответить с цитированием
Старый 30.04.2012, 20:11   #8
Vja4eslav
Пользователь
 
Регистрация: 13.08.2011
Сообщений: 90
По умолчанию

Опасаюсь показаться наглым и навязчивым. Уважаемый nilem, моих знаний не хватает, чтобы подправить Ваш последний код так, чтобы он не окрашивал пустые ячейки. Понимаю, что всякому терпению есть предел, но если Вас не очень затруднит, не могли бы Вы, пожалуйста, дописать это в коде ?
Vja4eslav вне форума Ответить с цитированием
Старый 30.04.2012, 20:18   #9
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

да ладно
Код:
Sub ertert3()
Dim x, i As Long, k As Long: Application.ScreenUpdating = 0
With Range("C5", Cells(Rows.Count, 3).End(xlUp))
    .Interior.ColorIndex = xlNone
    x = Application.Trim(.Value)
End With
With CreateObject("Scripting.Dictionary")
    .CompareMode = 1
    For i = 1 To UBound(x)
        If Len(x(i, 1)) Then
            If Not .Exists(x(i, 1)) Then
                .Item(x(i, 1)) = i
            Else
                Cells(i + 4, 3).Interior.ColorIndex = 3
                k = .Item(x(i, 1))
                Cells(k + 4, 3).Interior.ColorIndex = 3
            End If
        End If
    Next
End With: Application.ScreenUpdating = 1
End Sub
nilem вне форума Ответить с цитированием
Старый 30.04.2012, 20:26   #10
Vja4eslav
Пользователь
 
Регистрация: 13.08.2011
Сообщений: 90
По умолчанию

Большое спасибо! Поздравляю Вас с наступающими праздниками!
Vja4eslav вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
не могу считать двумерный массив=((( pinch000 Общие вопросы C/C++ 15 02.01.2012 14:35
как считать из файла в массив по символьно? casper1991 Visual C++ 1 12.04.2011 20:39
Как считать массив из файла? Ronin021992 Общие вопросы C/C++ 4 16.12.2009 20:44
как отсортировать массив под данный отрезок и как минимум и максимум из него найти SIEGER Паскаль, Turbo Pascal, PascalABC.NET 1 20.11.2008 08:58
как считать имена файлов из директории и поддерикторий в массив, ХЭЛП uraveselov Microsoft Office Excel 2 10.04.2008 09:50