Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - VBA

Страница: 1 |

 

  Вопрос: обработка столбцов (Excel+VBA) Добавлено: 20.12.06 11:44  

Автор вопроса:  mih999
Всем здрасьте!
Случился затык на такой проблеме.
Нужно обработать 2 ("А" и "В") столбца данных по следующему алгоритму.
1. Выявить только в столбце В соседние повторяющиеся значения.
2. Удалить теперь уже сразу в обоих столбцах ячейки, образующие пару из повторного значения в столбце В и соседней с ней ячейки в столбце А.
Например: в столбце В повторяются значения в ячейках В3 и В4, значит надо удалить ячейки А4:В4.
Здесь дело в том, что нельзя искать повторяющиеся значения сразу по обоим столбцам, т.к. в столбце А они нужны.
Вот таким кодом я вроде решаю пункт 1-й.
Dim B As Variant
    B = cellValue
    For Each B In Range("B2:B400")
    If B(1) = B(2) Then
    B(2).Select
    Selection.ClearContents
    End If
    Next

Помогите, плиз, чего дальше писать.

Ответить

  Ответы Всего ответов: 15  

Номер ответа: 1
Автор ответа:
 mih999



Вопросов: 1
Ответов: 8
 Профиль | | #1 Добавлено: 20.12.06 12:36
Все, не надо. Сам дошел.
Dim B As Variant
    B = cellValue
    For Each B In Range("B2:B400";)
    If B(1) = B(2) Then
    Rows(B(2).Row).Delete
    End If
    Next

Правда, это если всего ряда не жалко.

Ответить

Номер ответа: 2
Автор ответа:
 mih999



Вопросов: 1
Ответов: 8
 Профиль | | #2 Добавлено: 20.12.06 19:41
Народ, и все таки нужна помощь. Зря я тут раскричался, что решил.
Во-первых, выложенный код пропускает многократные повторы. Т.е., когда одно значение встречается в столбце больше 2-х раз подряд.
Во-вторых, надо таки разбираться как удалить только 2 ячейки, а не всю строку.
Я чего-то уже голову сломал, никак не выходит, особенно удручает то, что "во-первых" я указал.

Ответить

Номер ответа: 3
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #3
Добавлено: 21.12.06 23:17
Попробуйте так:

    Set rr = Range("A2:B4000";)
    For i = rr.Rows.Count To 1 Step -1
        If rr.Cells(i, 2) = rr.Cells(i - 1, 2) Then
            Range(Cells(i, 1), Cells(i, 2)).Delete Shift:=xlUp
        End If
    Next i

Ответить

Номер ответа: 4
Автор ответа:
 mih999



Вопросов: 1
Ответов: 8
 Профиль | | #4 Добавлено: 22.12.06 23:27
2GenyaA
Спасибо. Сейчас вот увидел ответ, опробовал. Действительно решает обе мои проблемы. Я чуть подправил, добавил условие, чтоб сравнивал только заполненные ячейки(>0) и вообще все супер. Скажу честно, сам я такой код пока написать еще не в силах. Может, если не очень нагло с моей стороны, сделаете вариант на основе while? Мне представляется, что изначально этот цикл было бы правильнее использовать, т.к. он по описанию как раз работает до тех пор, пока он True. Или в моем случае до тех пор, пока есть совпадающие ячейки. Как считаете?

Ответить

Номер ответа: 5
Автор ответа:
 night-roll



Вопросов: 36
Ответов: 326
 Профиль | | #5 Добавлено: 23.12.06 03:57
т.к. он по описанию как раз работает до тех пор, пока он True.
это не совсем так, т.к. мы не знаем изначально сколько повторов значения ячеки из столбца В, поэтому вариант выше и предлагает выбор из всего диапазона.

Ответить

Номер ответа: 6
Автор ответа:
 mih999



Вопросов: 1
Ответов: 8
 Профиль | | #6 Добавлено: 24.12.06 17:14
Night-roll
Спасибо и Вам за регирование на мои просьбы. Только ответа не понял. Вот читаю описание while из Гарнаева "Оператор повтора While в отличие от For выполняется не заданное число раз, а пока выполняется условие". По моему текущему пониманию, я это разумею так, что пока В1=В2=В3 и т.д. он удаляет все В2-Вn, которые идут после В1 и равны ему. Как только новая ячейка В2 (вставшая на место удаленных) становится не равна В1, цикл должен перейти к сравнению В2 и В3. В этом варианте нам не надо знать сколько повторов ячейки идет в этом столбце. А может быть цикл будет прогонять сразу весь столбец, потом возвращаться к началу, прогонять опять и так до тех пор, пока не останется повторяющихся ячеек? Допускаю, что я в корне все неправильно понимаю из прочитанного в этом самоучителе. Просто хотелось написать максимально корректный и правильный код. Так все таки, while можно использовать в моем варианте?

Ответить

Номер ответа: 7
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #7
Добавлено: 24.12.06 23:41
Думаю, Вам следует уточнить, что Вы имеете в виду, говоря - "удалить повторяющиеся ячейки". Судя по вопросам, которые Вы задаете, что-то подсказывает мне, что Вы подразумеваете под этой фразой на самом деле "удалить неуникальные ячейки" (оставить уникальные). Во всяком случае Ваш вопрос "А может быть цикл будет прогонять сразу весь столбец, потом возвращаться к началу, прогонять опять и так до тех пор, пока не останется повторяющихся ячеек?" имеет смысл в случае задачи, требующей оставить в столбце только уникальные (по значению) ячейки.

Если же задача стоит в том, чтобы оставить только уникальные ячейки, и при этом желательно использовать структуру While, то так и нужно ставить задачу.

Так о чем идет речь - об удалении повторяющихся или о том, что нужно оставить только уникальные?

Ответить

Номер ответа: 8
Автор ответа:
 mih999



Вопросов: 1
Ответов: 8
 Профиль | | #8 Добавлено: 25.12.06 17:54
GenyaA, здравствуйте!
Уточняю. Удалить из столбца В нужно только те ячейки, которые: а) имеют одинаковые значения, б) являются соседними. Т.е., когда выполняются одновременно оба условия. Если ячейки имеют одинаковые значения, но стоят, например, через одну, то ни одну такую ячейку удалять не надо. Поэтому, Вы неправильно догадались насчет неуникальных ячеек. Те данные, которые я хочу обрабатывать обязательно будут содержать повторяющиеся значения, главное, чтоб они не шли подряд. Плюс к этому, столбец А обрабатывать этим циклом нельзя, т.к. там есть свои повторяющиеся значения, но там они все нужны (подряд или неподряд). Посмотрите еще разок мой корневой пост, я там вроде весь механизм описал. А насчет while, так это как бы тоже вопрос, на который я сам не могу ответить. Является ли более корректным с точки зрения правильности написания кода использование именно while? Или и так все отлично?

Ответить

Номер ответа: 9
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #9
Добавлено: 25.12.06 18:09
В таком случае использовать While не имеет большого смысла, т.к. для решения задачи достаточно просто просмотреть все элементы столбца по порядку всего один раз, сравнивая их с предыдущим или следующим и в зависимости от результата сравнения - удалять или нет, и переходить к следующему элементу. Нет необходимости в том, чтобы проверять каждый элемент с каждым во всем столбце (или во всей оставшейся или уже просмотренной части его).

Конечно, можно заменить структуру For на While, но, как мне кажется, это только усложнит решение, т.к. придется отдельно прописать операцию изменения счетчика и проверку критерия окончания цикла. Как раз эти два действия подразумевает в себе самой структура цикла For.

Ответить

Номер ответа: 10
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #10
Добавлено: 25.12.06 18:14
Кстати в моем варианте решения будет корректней написать вместо:

    For i = rr.Rows.Count To 1 Step -1


вот это:

    For i = rr.Rows.Count To 2 Step -1


Иначе, в случае, если проверяемая область начинается с первой строки листа, то при i=1 Cells(i - 1, 2) вызовет ошибку в следствие попытки проверить нулевую строку (1-1=0), которой, очевидно, нет на листе.

Ответить

Номер ответа: 11
Автор ответа:
 mih999



Вопросов: 1
Ответов: 8
 Профиль | | #11 Добавлено: 25.12.06 18:16
GenyaA, спасибо еще раз! Собственно, я и пытался понять, какой код будет легче и проще для выполнения. Теперь можно успокоиться на этот счет.

Ответить

Номер ответа: 12
Автор ответа:
 mih999



Вопросов: 1
Ответов: 8
 Профиль | | #12 Добавлено: 25.12.06 18:20
Пока отвечал, появилось новое сообщение. А как можно увидеть эту ошибку? Есть ли в VBA какие-то способы выведения ошибок куда-нибудь в лог? У меня, кстати, ничего не ругалось, когда использовал первоначальный вариант.

Ответить

Номер ответа: 13
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #13
Добавлено: 25.12.06 18:50
Измените начало моего кода на это:
       Set rr = Range("A1:B4000";)

и посмотрите, что получится.

Ответить

Номер ответа: 14
Автор ответа:
 mih999



Вопросов: 1
Ответов: 8
 Профиль | | #14 Добавлено: 25.12.06 20:20
Ну да, есть эффект. В этом случае VBA находит ошибку в этой строке:
If rr.Cells(i, 2) > 0 And rr.Cells(i, 2) = rr.Cells(i - 1, 2) Then

А это, насколько я понимаю, и есть обращение к нулевой строке. Точнее, к первой и нулевой.

Ответить

Номер ответа: 15
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #15
Добавлено: 25.12.06 23:09
да, верно.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам