2015-06-18 3 views
1

У меня есть столбец А и столбца B. В колонке А, Я (начиная с А2) значения, которые выходят из 1-150 (так, заканчивающийся в A151)Используя VBA, чтобы получить пороговое значение

В колонке B, у меня есть значения. Я хочу получить первое значение, превышающее значение в ячейке Z2, и выписать соответствующее значение в столбце A в ячейке B153 для столбца B. Последняя часть сложна. Я хочу записать это значение только в том случае, если следующие 4 значения также превышают значение в Z2. Возможно ли это сделать?

Если это, у меня есть то же самое в столбцах C-Y enter image description here

Лучшее объяснение:

Я хочу перебрать столбцов B-Y Внутренний контур из клеток 2-151.

Если B2> Z2, но также следующие 4 последовательных ячейки (B3-B6)> Z2, затем скопируйте A2 в B153 и перейдите к следующему столбцу. Если B2> Z2, но следующие 4 не все> Z2, повторите процесс с B3. Если B2 < Z2, перейдите к B3.

Если ничего не точная копия N/A для B153

Можно ли это сделать?

Моя первая попытка:

=INDEX($A$2:$A$151,SUMPRODUCT(MATCH(1,--(B$2:B$151>$Z$2),0)),1) 

Это занимает первое значение, хотя. Я пытаюсь придумать умный способ получить первое значение, только если второе значение также соответствует критериям. Оттуда я уверен, что можно расширить до 3, 4, 5 и т.д.

+2

[Вы пробовали что-нибудь?] (Http://whathaveyoutried.com) Пожалуйста, опубликуйте ваше решение – Barranka

+0

@Barranka Я отправил то, что я пробовал. Простой код в другой ячейке на листе – Jack

+0

Еще один способ подумать об этом с помощью VBA - это прокрутить каждый столбец. Начните с B2. Если B2-B6 все больше Z2, верните A2. Если нет, перейдите к B3 и повторите. После того, как значение найдено, опубликуйте в B153 и перейдите к следующему столбцу, остановившись в столбце Y. Я могу думать о том, как это можно сделать, просто борясь за то, что работает. – Jack

ответ

1

Что-то вроде этого:

Sub OutputEnergy()  
'y = Columns to check: 2-25 
'x = Rows to check: 2-152 
'z = check the next 4 cells 
Dim x, y, z, check 
'Clear the range where we store the #N/A or Energy Outputs 
Range("B153:Y153") = vbNullString 
For y = 2 To 25 
    For x = 2 To 152 
     If Cells(x, y) > Range("Z2") Then 'If value is greater than Z2 
      check = True     'Let's check the next 4 
      For z = 1 To 4     'If any of them fail 
       If Cells(x + z, y) < Range("Z2") Then 
        check = False   'The check fails 
        Exit For 
       End If 
      Next z 
      If check = True Then   'If the check doesn't fail 
       Cells(153, y) = Cells(x, 1) 'Set cell 153 to the energy level 
       Exit For 
      End If 
     End If 
    Next x         'If no energy level was set - #N/A 
    If Cells(153, y) = vbNullString Then Cells(153, y) = "#N/A" 
Next y 
End Sub 

Edit: В функции:

Функция Использование:

=OutputEnergy(Range, Threshold, [Number of cells to check], [Using Headers?])

В принципе, дайте ему диапазон для проверки, дайте ему порог.

Количество ячеек для проверки после этого по умолчанию 4.

Чтобы получить «Энергия» он получает номер строки (При использовании заголовков, он вычитает 1)

Function OutputEnergy(TheRange As Range, Threshold As Variant, Optional NextCells As Integer = 4, Optional OffsetForHeader As Boolean = True) As Variant  
Dim c, x, check 
For Each c In TheRange 
    If c.Value > Threshold Then 
     check = True 
     For x = 1 To NextCells 
      If c.Offset(x, 0) < Threshold Then 
       check = False 
       Exit For 
      End If 
     Next x 
     If check = True Then 
      OutputEnergy = IIf(OffsetForHeader, c.Row - 1, c.Row) 
      Exit Function 
     End If 
    End If 
Next c 
OutputEnergy = CVErr(xlErrNA) 
End Function 

Edit снова - для вывода всех листов:

OutputEnergyToSheet принимает лист в качестве параметра:

Sub OutputEnergyToSheet(TheSheet As String) 
'y = Columns to check: 2-25 
'x = Rows to check: 2-152 
'z = check the next 4 cells 
Dim x, y, z, check 
'Clear the range where we store the #N/A or Energy Outputs 
With Sheets(TheSheet) 
    .Range("B153:Y153") = vbNullString 
    For y = 2 To 25 
     For x = 2 To 152 
      If .Cells(x, y) > .Range("Z2") Then 'If value is greater than Z2 
       check = True     'Let's check the next 4 
       For z = 1 To 5     'If any of them fail 
        If .Cells(x + z, y) < .Range("Z2") Then 
         check = False   'The check fails 
         Exit For 
        End If 
       Next z 
       If check = True Then     'If the check doesn't fail 
        .Cells(153, y) = Int(.Cells(x, 1)) 'Set cell 153 to the energy level 
        Exit For 
       End If 
      End If 
     Next x         'If no energy level was set - #N/A 
     If .Cells(153, y) = vbNullString Then .Cells(153, y) = "#N/A" 
    Next y 
End With 
End Sub 

OutputEnergyToAllSheets петли через каждый лист и называет новый подраздел:

Sub OutputEnergyToAllSheets() 
Dim w 
For Each w In ThisWorkbook.Worksheets 
    If Not InStr(w.Name, "Total") > 0 And Not InStr(w.Name, "eV") > 0 Then 
     OutputEnergyToSheet w.Name 
    End If 
Next w 
End Sub 
+0

Он должен работать, изменяя это значение. Единственная проблема с этим циклом заключается в том, что вы попадаете в нижнюю часть и запускаете пустые ячейки. Я не уверен, как вы хотите справляться с этими случаями. Я предполагаю, что это должно потерпеть неудачу, и я верю, что это произойдет. – user1274820

+0

Есть ли способ для этого прорезать все листы, кроме тех, у кого есть «Total» или «eV» где-то в названии? – Jack

+0

Я никогда не указывал листы, чтобы вы могли выбрать каждый лист и снова запустить макрос - если диапазоны должны быть изменены, это будет немного сложнее. Его можно переписать для использования последней строки и различных диапазонов. Если макеты идентичны, вы можете использовать «Для каждого w в этой книге. Рабочие места If Not InStr (w.Name,« Total »)> 0 и Not InStr (w.Name,« eV »)> 0 Затем n.Выберите Call OutputEnergy Next w' – user1274820

2

Ваша текущая формула может работать для случая с одним значением, но я думаю, что было бы немного неуклюже пытаться масштабировать.Пару быстрых способов сделать это с помощью формулы являются:

=MIN(IF(COUNTIF(INDIRECT("B"&ROW(2:147)&":B"&ROW(6:151)),">"&Z2)=5,$A2:$A147,1E9)) 

И:

=MIN(IF((B2:B147>Z2)*(B3:B148>Z2)*(B4:B149>Z2)*(B5:B150>Z2)*(B6:B151>Z2),$A2:$A147,1E9)) 

Лично я считаю, что последний легче читать и перетащить через таблицу (хотя прежний может быть изменен, чтобы перетащить так же легко). Последний также позволяет избежать изменчивой функции INDIRECT. Первая функция принимает 5 диапазонов ячеек за раз и подсчитывает количество ячеек, которые соответствуют критериям. Если наш счет равен 5, у нас есть совпадение. Этот метод является предпочтительным, если вы ищете более широкий набор совпадений. Вторая формула просто проходит через диапазон, проверяя в основном r на r + 4, где r - текущая строка. Оба являются формулами массива, которые следует вводить с помощью CTRL + SHIFT + ENTER вместо просто ENTER.

2

Существует много способов решить эту проблему, но, на мой взгляд, вам нужна вложенная петля в пользовательской функции.

Мы можем ...

function get_Energy_Row(cellSearch as Range, staticValue as Single) 

    Dim cell1 as Single 

    get_Energy_Row = "N/A" 

    j = 1 
    col = cellSearch.Columns.Count 

    Do 
     cell1 = cellSearch(j, col) 

     If cell1 <= staticValue Then 
      'do nothing, function already set to "N/A" 
     Else 

      For i = 1 to 4 
       If cellSearch(i + j, col) > staticValue Then 
        get_Energy_Row = cellSearch(j,1) 
       Else 
        'do nothing, function already set to "N/A" 
       End If 
      Next i 
     End If 

     j = j + 1 

    Loop Until j >= cellSearch.Rows.Count - 3 Or get_Energy_Row <> "N/A" 

End Function 

Затем вызовите ваш UDF в клетке C153 так:

=get_Energy_Row($A2:B151,$Z$2), где вы охватывают первый столбец.

Обратите внимание на знаки доллара, это будет гарантировать, что ваш статическая проверка всегда будет Z2

Логика в том, что я по умолчанию в ячейку «N/A» до тех пор, пока не найдет критерии, которые переписывает «N/A» , и в этом случае цикл прерывается.

+0

Да, я просто запустил ее - думаю, должна быть хотя бы одна ошибка. – Jack

+1

Исправлено это, для чего это стоит. –