2015-06-08 3 views
1

Я пытаюсь подсчитать количество вхождений определенной строки в отфильтрованных данных. Я могу сделать это, используя формулу в ячейке, но когда я совмещаю это с другими макросами в своей книге, все это зависает.Excel в CountIF в отфильтрованных данных

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

=SUMPRODUCT(SUBTOTAL(3,OFFSET('2015 Master'!H:H,ROW('2015 Master'!H:H)-MIN(ROW('2015 Master'!H:H)),,1)),ISNUMBER(SEARCH("*Temp*",'2015 Master'!H:H))+0) 

В основном я хочу, чтобы подсчитать количество раз «Temp» происходит в колонке H, но только в отфильтрованных данных.

Благодарим за помощь!

Сложение:

Вот код, который я написал для макросъемки до сих пор. Он фильтрует данные на другом листе, затем обновляет сводную таблицу с диапазоном дат. Я хотел бы добавить вычисления подсчета в конец этого кода и вернуть счет в ячейку на листе «Отчетность».

Sub Button1_Click() «Обновить сводную таблицу и все вычисления в активном листе

ActiveWorkbook.RefreshAll 

'Gather the start and end times from the active sheet 

dStart = Cells(2, 5).Value 
dEnd = Cells(3, 5).Value 

'Change the active sheet to the alarms database, clear all filters and then filter for the defined date range and filter for only GMP alarms 

Sheets("2015 Master").Select 

If ActiveWorkbook.ActiveSheet.FilterMode Or ActiveWorkbook.ActiveSheet.AutoFilterMode Then 
ActiveWorkbook.ActiveSheet.ShowAllData 
End If 

ActiveSheet.ListObjects("Table44").Range.AutoFilter Field _ 
    :=3, Criteria1:=">=" & dStart, Operator:=xlAnd, Criteria2:= _ 
    "<=" & dEnd 

Range("Table44[[#Headers],[GMP or non-GMP]]").Select 
ActiveSheet.ListObjects("Table44").Range.AutoFilter Field:=2, Criteria1:= _ 
    "GMP" 
'Change the active sheet to the Reporting sheet 

Sheets("Reporting").Select 

'Within the alarms pivot table clear the label filters then filter for the date range and GMP alarms 

ActiveSheet.PivotTables("PivotTable1").PivotFields("Active Time"). _ 
    ClearLabelFilters 
ActiveSheet.PivotTables("PivotTable1").PivotFields("Active Time").PivotFilters. _ 
    Add Type:=xlDateBetween, Value1:=dStart, Value2:=dEnd 
ActiveSheet.PivotTables("PivotTable1").PivotFields("GMP or non-GMP"). _ 
    CurrentPage = "GMP" 
End Sub 
+0

Как этот гипотетический макрос VBA должен знать, фильтруются ли данные или нет? Просьба уточнить. С наилучшими пожеланиями, –

+0

См. Мое дополнение в вопросе –

+0

Этот код отлично работает. Я просто хочу добавить к нему. Я хочу подсчитать количество раз, когда «temp» появляется в данных, которые фильтруются на листе «Мастер 2015» в столбце H. Это где он фильтруется: ActiveSheet.ListObjects («Таблица 44»). Поле Range.AutoFilter _ : = 3, Criteria1: = "> =" & dStart, Operator: = xlAnd, Criteria2: = _ "<=" & dEnd Диапазон ("Таблица44 [[# Заголовки], [GMP или не-GMP ]]). Выберите ActiveSheet.ListObjects («Таблица 44»). Range.AutoFilter Field: = 2, Criteria1: = _ «GMP» –

ответ

0

Документы, касающиеся осветленной теме вопроса (т.е." В основном я хочу, чтобы подсчитать количество раз „Temp“ происходит в столбец H ... "), решение VBA может быть показано в следующем фрагменте кода. Предполагая, что образец данных, введенных в колонке "H":

Н

Temp Directory on C: Drive 
Temp Directory 
Project Directory 
Output Temp Directory 
Start Directory 
Temp obj 

применять VBA макросов:

Sub CountTempDemo() 
Dim i As Integer 
Dim count As Integer 
Dim startRow As Integer 
Dim lastRow As Integer 
Dim s As String 

startRow = 2 'or use your "filtered range" 
lastRow = Cells(Rows.count, "H").End(xlUp).Row 'or use your "filtered range" 
count = 0 
For i = 2 To lastRow 
    If InStr(Cells(i, 8).Value, "Temp") > 0 Then 
     count = count + 1 
    End If 
Next 
End Sub 

где count значение 4 представляет ряд "Temp" вхождений в указанный диапазон «H».

Надеюсь, это поможет. С наилучшими пожеланиями,

0

Чтобы перебрать колонку и найти только видимую (нефильтрованную) клетку, один из способов заключаются в следующем:

Set h = ... Columns ("H"); 
Set r = h.SpecialCells(xlCellTypeVisible) 
' now r is a composite range of potentially discontiguous cells 
' -- it is composed of zero or more areas 
'but only the visible cells; all hidden cells are skipped 
Set ar = r.Areas 
for ac = 1 to ar.Count 
    Set rSub = ar(ac) 
    'rSub is a contiguous range 
    'you can use a standard formula, e.g. Application.WorksheetFunction.CountIf(...) 
    'or loop over individual elements 
    'and count what you like 
next 

предостережения: если какие-либо строки (или столбец) скрыты вручную (не из фильтрации) подсчет с использованием этого метода будет рассматривать их как отфильтрованные (т. е. скрытые/невидимые).


Update: Ответ на комментарий

Диапазон действительно очень общее назначение понятие агрегации клеток в группировку или собирающий объект (Range). Несмотря на то, что мы обычно рассматриваем диапазон как прямоугольник или прямоугольник ячеек (т. Е. Смежные ячейки), диапазон может фактически собирать несмежные ячейки.

Одним из примеров является выбор пользователем нескольких несмежных ячеек, строк и/или столбцов. Тогда, например, ActiveSheet.Selection будет единственным диапазоном, отражающим эти несмежные ячейки. То же самое может произойти с возвратным значением от SpecialCells.

Итак, объектная модель Excel говорит, что в целом диапазон может состоять из областей, где каждый сам район также представлен диапазоном, но на этот раз он понимается как непрерывный диапазон. Единственный способ определить, является ли Range смежным или нет, если вы создали его как прямоугольник или прямоугольник, или, если Areas.Count = 1.

Один из способов исследования немного больше может заключаться в том, чтобы выбрать некоторые неудобные ячейки, затем введите макрос и используйте отладчик для наблюдения Selection.

+0

Привет, спасибо, я только вернусь к этому и надеялся, что вы сможете объяснить «ar = r.Areas», что делает эта линия? Я также пытался использовать rSub в моем CountIF, и у меня есть некоторые трудности. Это то, что у меня есть: tempcount = Application.WorksheetFunction.CountIf (Range ("rsub"), "* Temp *") Любая помощь будет оценена. –

+0

Попробуйте передать rSub функции как переменной, а не как строку. (например, без кавычек). Я не думаю, что вам понадобится Range(). –

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