Привет,
Я знаю вот эту формулу
=MODE(!B:B)
дает вам наиболее повторяющиеся значения в столбце B, но я хочу подсчитывать только цветные ячейки. Это вообще возможно?
Спасибо.
Обновлено:
вот так выглядит мой модуль:
Function GetInfo(TopObj As Variant, PropertySpec As Variant) As Variant
Dim PropArr As Variant ' array returned by Split of object tree
Dim ItemSpec As Variant ' item in collection
Dim Obj As Object ' generic Object to hold
'the top-level object (ws,wb,range, or app)
Dim Ndx As Long ' loop counter
Dim Pos1 As Integer ' used to find the Item specified in collection objects
Dim Pos2 As Integer ' used to find the Item specified in collection objects
Dim TempObj As Object
'
' split the object/property spec
'
PropArr = Split(PropertySpec, ".")
'
' If Rng is an object, then it must be a Range. That's the only
' type of object you pass from a cell.
'
If IsObject(TopObj) Then
Set Obj = TopObj
Else
'
' Otherwise, it better be one of the following strings. Else,
' blow up the user.
'
Select Case UCase(TopObj)
Case "APP", "APPLICATION"
Set Obj = Application
Case "WB", "TWB", "THISWORKBOOK", "WORKBOOK"
Set Obj = ThisWorkbook
Case "WS", "TWS", "THISWORKSHEET", "WORKSHEET"
Set Obj = Application.Caller.Parent
Case Else
GetInfo = CVErr(xlErrValue)
End Select
End If
For Ndx = LBound(PropArr) To UBound(PropArr) - 1
'
' this block of code is for handling items of a collection
'
Pos1 = InStr(1, PropArr(Ndx), "(")
If Pos1 > 0 Then
'
' if we've found the open paren, we're dealing with an
' item of a collection. now, find the closing paren.
'
Pos2 = InStr(1, PropArr(Ndx), ")")
ItemSpec = Mid(PropArr(Ndx), Pos1 + 1, Pos2 - Pos1 - 1)
If IsNumeric(ItemSpec) Then
' numeric -- going by index number
ItemSpec = CLng(ItemSpec)
Else
' string -- going by key name, so get rid of any quotes.
ItemSpec = Replace(ItemSpec, """", "")
End If
'
' call the Item method of the collection object.
'
Set Obj = CallByName(Obj, Mid(PropArr(Ndx), 1, Pos1 - 1), _
VbGet, ItemSpec)
Else
'
' we're not dealing with collections. just get the object.
'
Set Obj = CallByName(Obj, PropArr(Ndx), VbGet)
End If
Next Ndx
'
' get the final property (typically 'name' or 'value' of the object tree)
'
If IsObject(Obj) Then
GetInfo = CallByName(Obj, PropArr(UBound(PropArr)), VbGet)
End If
End Function
Public Function getArrayInfo(rng As Range, atr As String) As Variant
Dim temp As Excel.Range
Dim out() As Variant
Dim i As Long
i = 1
ReDim out(1 To rng.Rows.Count, 1 To 1)
Set temp = Intersect(rng, ActiveSheet.UsedRange)
For Each Item In temp.Cells
out(i, 1) = GetInfo(Item, atr)
i = i + 1
Next Item
getArrayInfo = out
End Function
Я рекомендую использовать этот замечательный макрос Чипа Пирсона для получения различной информации о ячейке, включая цвет: cpearson.com/excel/GetInfo.htm
Спасибо, но я не пытаюсь просто получить цвет ячейки, а получить данные из ячейки с определенным цветом.
после того, как вы импортировали функцию getInfo в свой модуль, теперь вам нужно добавить в модуль дополнительную функцию для работы с формулами массива. Добавьте это после функции getInfo:
Public Function getArrayInfo(rng As Range, atr As String) As Variant
Dim temp As Excel.Range
Dim out() As Variant
Dim i As Long
i = 1
ReDim out(1 To rng.Rows.Count, 1 To 1)
Set temp = Intersect(rng, ActiveSheet.UsedRange)
For Each item In temp.Cells
out(i, 1) = GetInfo(item, atr)
i = i + 1
Next item
getArrayInfo = out
End Function
Затем на вашем листе вы получаете режим с:
=MODE(IF(getArrayInfo(data,"Interior.Color")=24,data))
где data
— ваш столбец данных. Не забудьте ввести его как формулу массива с Ctrl+Shift+Enter
Здесь я протестировал его с этим набором данных:
Это решение предполагает, что вы можете немного изменить свои данные, в частности, добавив вспомогательный столбец и преобразовав диапазон в таблицу, но оно намного проще, работает быстрее и не требует VBA.
1. Перейти к Formulas > Defined Names > Name Manager
2. Нажмите на New
, назовите его как хотите, я выбрал «bg» и в «Относится к:» введите:
=GET.CELL(63,INDIRECT("rc[-1]",FALSE))
Затем нажмите «ОК» и закройте диспетчер имен.
3. Выберите таблицу данных и перейдите к Insert > Tables > Table
, вы увидите диалоговое окно, чтобы подтвердить диапазон, который вы хотите выбрать, проверьте, есть ли в вашей таблице заголовки, и нажмите «ОК», теперь ваши данные должны иметь форматирование таблицы. Это легко распознать, потому что теперь у вас должна быть стрелка фильтра рядом с заголовком таблицы.
4. добавьте новый заголовок справа от столбца данных, затем введите color
в заголовок. В первой записи данных в этом новом столбце введите формулу =bg
(или то, что вы выбрали для имени своего пользовательского именованного диапазона на шаге 1). Нажмите «Ввод», и он должен автоматически заполнить одну и ту же формулу для всего столбца:
5. Теперь, наконец, у вас есть вспомогательный столбец, который считывает colorIndex для каждой соответствующей записи, поэтому вы можете прочитать, какой colorIndex вы хотите проанализировать, и ваша формула проста:
{=MODE.SNGL(IF(Table1[COLOR]=ColorIndex,Table1[INPUT]))}
где colorIndex
— это номер цвета, который вы хотите проанализировать, например, в моей таблице желтый — это 6, а красный — 3. Не забудьте ввести его как формулу массива с Ctrl+Shift+Enter
Здесь вы можете видеть, что я рассчитал соответствующий режим для всех цветов в моей таблице данных, с дополнительным преимуществом, поскольку данные отформатированы в виде таблицы, наши формулы будут автоматически обновляться при добавлении новой записи.
Извините, я получаю ошибку #NAME. =MODE(IF(GetInfo(Stats!B:B,"Interior.Color")<>"xlNone",Stats!B:B))
неважно, ошибка исправлена, но как мне установить цвет ячейки, из которого она должна выбирать данные?
Сначала вам нужно знать индекс цвета, который вы хотите проанализировать, узнать это можно просто с помощью GetInfo(cell,"Interior.Color")
, а затем в моей исходной формуле вместо вычисления неравенства <>"xlNone"
сделать равенство именно этому индексу цвета
Цветовой индекс 24, так что должно быть что-то вроде =MODE(IF(GetInfo(Stats!B:B,"Interior.Color")<>"24",Stats!B:B))
верно?
нет, вместо неравенства <>
должно быть равенство =
. Я отредактирую свой ответ с примером.
Извините, я не могу его сбросить. Я пробовал =MODE(IF(GetInfo(Stats!B:B,"Interior.Color") = "24",Stats!B:B))
, но получаю ошибку #Value
@CainNuke, вы правы, я допустил ошибку с логикой ArrayFormula, прочитайте мой отредактированный ответ и соответствующим образом обновите свой модуль.
Извините, но я все еще не могу заставить его работать. Я получаю ошибку #Value. Вторую функцию нужно добавить в тот же модуль, что и первую функцию, или в отдельный модуль?
@CainNuke Вторая функция должна быть в том же модуле под первым. Если вам не нравится реализация VBA, я отредактировал свой ответ, включив в него решение, отличное от VBA, учитывая, что вам разрешено немного изменять таблицу исходных данных.
Я в порядке с VBA, но я просто не могу понять, почему он не работает. Может быть, моя версия Excel? У меня есть 2 функции в одном модуле, но я все равно получаю сообщение об ошибке. Не могли бы вы прислать мне свой первый тестовый файл? Так что я могу посмотреть и посмотреть, как это работает напрямую.
Я отредактировал свой первый пост, чтобы показать вам, что именно у меня есть в моем модуле.
Давайте продолжим обсуждение в чате.
Проверьте этот вопрос; stackoverflow.com/questions/24382561/…