Что я делаю не так? Удаление дубликатов с помощью Excel VBA

Просто добавьте что-то примечательное здесь.


myQueue.hpp:

template <class T> 
class QueueA {
    int size;
    ...
public:
    template <class T> T dequeue() {
       // implementation here
    }

    bool isEmpty();

    ...
}    

myQueue можно определить методы шаблонного класса, которые просто прекрасны в файле реализации. cpp:

// implementation of regular methods goes like this:
template <class T> bool QueueA<T>::isEmpty() {
    return this->size == 0;
}


main()
{
    QueueA<char> Q;

    ...
}
0
задан urdearboy 13 July 2018 в 17:26
поделиться

5 ответов

Почему бы не использовать встроенную команду:

Worksheets("Sheet1").Range("$A:$A").RemoveDuplicates Columns:=1, Header:=xlYes

Range.RemoveDuplicates Method (Excel)

0
ответ дан Konstantin 17 August 2018 в 12:21
поделиться

Каждый первый j-цикл начинается с сравнения строки с самим собой, поскольку вы начинаете с j = i. Разница между значением и самим всегда равна нулю. (Он также сравнивает строку 2 с самим собой как последний шаг.)

Однако, если вы переключитесь:

For i = lrow To 2 Step -1
For j = i To 2 Step -1

на:

For i = lrow To 3 Step -1
For j = i - 1 To 2 Step -1`

код будет сравнивать все различные строки без самовыравнивания.

Еще одна точка (которую @Proger_Cbsk ответ вспомнил), заключается в том, что сравнение с просто вычитание .Cells(i, "B").Value - .Cells(j, "B").Value < 100 иногда приводит к неожиданным результатам.

Например, предположим .Cells(i, "B").Value = 1 и .Cells(j, "B").Value = 250. Мы можем сказать, просто глядя, что существует разница не менее 100, поэтому вы ожидаете, что эта часть выражения будет оцениваться как False. Однако из прямой подстановки вы получаете выражение: 1 - 250 < 100. Начиная с 1 - 250 = -249, и с -249 < 100 выражение действительно оценило бы True.

Однако, если вы должны были изменить .Cells(i, "B").Value - .Cells(j, "B").Value < 100 на Abs(.Cells(i, "B").Value - .Cells(j, "B").Value) < 100, выражение теперь будет смотреть, разница больше или меньше 100, вместо того, чтобы смотреть, если результат вычитания больше или меньше 100.

0
ответ дан Mistella 17 August 2018 в 12:21
поделиться

Не

If .Cells(i, "A").Value = .Cells(j, "A").Value And .Cells(i, "B").Value - .Cells(j, "B").Value < 100 Then

Здесь во второй части инструкции вы просто сравниваете .Cells(j, "B").Value с константой 100!

Но

If .Cells(i, "A").Value = .Cells(j, "A").Value And Abs(.Cells(i, "B").Value - .Cells(j, "B").Value) < 100 Then

Abs () может помочь, иначе сохраните только ()

3
ответ дан Proger_Cbsk 17 August 2018 в 12:21
поделиться
  • 1
    Я согласен с использованием Abs(), поскольку в противном случае сравнение иногда терпит неудачу (т. Е. Поиск разницы больше 10: 4-50>10 будет оцениваться как false как 4-50 = & gt; - 45, что менее 10). Однако сравнение является , фактически выполняющим вычитание. – Mistella 13 July 2018 в 17:44
  • 2

Что-то вроде этого должно работать для вас:

Sub tgr()

    Dim ws As Worksheet
    Dim rDel As Range
    Dim rData As Range
    Dim ACell As Range
    Dim hUnq As Object

    Set ws = ActiveWorkbook.Sheets("Sheet1")
    Set hUnq = CreateObject("Scripting.Dictionary")


    Set rData = ws.Range("A2", ws.Cells(ws.Rows.Count, "A").End(xlUp))
    If rData.Row = 1 Then Exit Sub  'No data

    For Each ACell In rData.Cells
        If Not hUnq.Exists(ACell.Value) Then
            'New Unique ACell value
            hUnq.Add ACell.Value, ACell.Value
        Else
            'Duplicate ACell value
            If Abs(ws.Cells(ACell.Row, "B").Value - ws.Cells(ACell.Row - 1, "B").Value) < 100 Then
                If rDel Is Nothing Then Set rDel = ACell Else Set rDel = Union(rDel, ACell)
            End If
        End If
    Next ACell

    If Not rDel Is Nothing Then rDel.EntireRow.Delete

End Sub
1
ответ дан tigeravatar 17 August 2018 в 12:21
поделиться

Придерживаясь формата вашего кода, вы можете сделать это, используя один цикл For.

For i = lrow To 3 Step -1
    If .Cells(i, "A") = .Cells(i - 1, "A") And (.Cells(i, "B") - .Cells(i - 1, "B")) < 100 Then
        .Cells(i, "A").EntireRow.Delete
    End If
Next i
1
ответ дан urdearboy 17 August 2018 в 12:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: