2016-05-31 2 views
1

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

Вот что я пытаюсь сделать:

  1. Поиск ячейки с определенным сроком
  2. Если найдено, скопировать всю строку, что клетка находится в и вставить его в ряд над ним ,
  3. Если не нашли, ничего не делать и продолжать с кодом

Вот мой код:

Sub Test() 
' 
' Test Macro 
' 
' Keyboard Shortcut: Ctrl+b 
' 

    Range("A5").Select 
    Cells.Find(What:="PL 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _ 
     :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _ 
     False, SearchFormat:=False).Activate 
    If Not IsEmpty(ActiveCell.Value) Then 
     ActiveCell.Rows("1:1").EntireRow.Select 
     Selection.Copy 
     Range("A5").Select 
     ActiveSheet.Paste 
    End If 
    Range("A5").Select 
    Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, LookAt _ 
     :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _ 
     False, SearchFormat:=False).Activate 
    If Not IsEmpty(ActiveCell.Value) Then 
     ActiveCell.Rows("1:1").EntireRow.Select 
     Selection.Copy 
     Range("A6").Select 
     ActiveSheet.Paste 
    End If 
    Range("A5").Select 
    Cells.Find(What:="PL 3", After:=ActiveCell, LookIn:=xlFormulas, LookAt _ 
     :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _ 
     False, SearchFormat:=False).Activate 
    If Not IsEmpty(ActiveCell.Value) Then 
     ActiveCell.Rows("1:1").EntireRow.Select 
     Selection.Copy 
     Range("A7").Select 
     ActiveSheet.Paste 
    End If 
End Sub 

Мой код работает только тогда, когда обнаруживается значение. Если он не нашел, что это работает в ошибку ниже: enter image description here

+2

«Это не работает, очевидно». Вы должны сказать нам, что он делает, над какими конкретными данными и тем, что вы ожидаете от этого. Вы не только хотите, чтобы SO отлаживал это для вас, вы просите отладки сделать слепо, даже не зная, как выглядят ваши исходные данные. –

+1

Кроме того, это было спрошено сотни раз на SO. Хорошо, что вы должны написать свой собственный код, но зачем изобретать колесо? – findwindow

+0

@findwindow у вас есть ссылка? Я не могу найти его. –

ответ

3

Cells.Find является функцией который возвращает ссылку на объект Range; когда он ничего не найдет, ссылка будет Nothing. И вы не можете назвать .Activate на Nothing:

Этот метод не возвращает ничего, если совпадение не найдено. Метод Find не влияет на выбор или активную ячейку. (MSDN)

Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, LookAt _ 
    :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _ 
    False, SearchFormat:=False).Activate 

Вы должны переписать код и избежать .select и .Activate и избегать работы с ActiveCell и неявно с ActiveSheet (что вы делаете, не квалифицируя Cells вызов правильная справочная таблица).

Ваше форматирование делает его трудно читать код, по нескольким причинам:

  • Аргументы уточняются на разных линиях
  • продолжений линии в настоящее время palced в произвольных местах
  • Вложенные вызовы членов Арен» т выстроились

Сравните:

Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, _ 
      LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _ 
      MatchCase:=False, SearchFormat:=False) _ 
    .Activate 

Это просто читаемость.Проблема в том, что вы в основном предположите, что .Find возвращает действительную ссылку на объект. Не думайте, явно проверить:

Set result = Cells.Find(...) 
If Not result Is Nothing Then result.Activate 

Но на самом деле, вы должны выяснить способ избежать .select и .Activate.

+1

Ничего себе. Отличный ответ. Это именно то, что я искал. Теперь я понимаю, где я ошибался намного лучше. –

+0

Итак, почему. Выберите и. Активируйте плохо? –

+0

Потому что они делают ваш код чрезвычайно хрупким, труднее следовать и бесполезно медленно. См. [Этот вопрос] (http://stackoverflow.com/q/10714251/1188513) для * how *, чтобы избежать их, и [эта статья MSDN] (https://msdn.microsoft.com/en-us/library /aa139976(v=office.10).aspx), а также [это сообщение в блоге] (http://www.businessprogrammer.com/power-excel-vba-secret-avoid-using-select/) и [это Управление запись в блоге о лучших практиках VBA] (https://blogs.office.com/2009/03/12/excel-vba-performance-coding-best-practices/), для * why *. –

3

Вы можете попробовать что-то вроде этого вместо (непроверенные):

Sub HideAndSeek() 

    Dim foundCell As Range 

    For i = 1 To 3 
     Set foundCell = Cells.Find(What:="PL " & i, LookIn:=xlFormulas, LookAt:=xlPart) 
     If Not foundCell Is Nothing Then 
      Intersect(foundCell.EntireRow, ActiveSheet.UsedRange).Offset(-1, 0).Value = _ 
       Intersect(foundCell.EntireRow, ActiveSheet.UsedRange).Value 
     End If 
     Set foundCell = Nothing 
    Next 

End Sub 

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

Другая часть этого ответа проверяет, что ячейка была найдена - для этого мы проверяем, что диапазон был фактически установлен (что означает, что он не Nothing) с использованием

If Not foundRange Is Nothing 
+0

Спасибо за то, что так полезно @Macro Man! Я попробую это. Я думаю, что для других людей было бы трудно понять, в чем проблема, так что это помогает кому-то вроде вас. –

+0

У меня проблемы с пониманием вашего кода. Почему вы использовали Intersect()? В чем преимущество этого простого копирования и вставки? –

+0

'Intersect()' find возвращает раздел, где 2 диапазона перекрываются (или _intersect_). В общем, лучше прямо записать значение диапазона в другой диапазон, а не копировать/вставлять (чистить и меньше накладных расходов). Вместо того, чтобы делать это для строки _entire_, которая является излишней, я просто использовал 'Intersect', чтобы найти, где вся строка и используемый диапазон перекрываются, а затем записывают это значение в ту же область, но одну строку выше, используя' Offset (-1, 0) ' –

Смежные вопросы