Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.11.2013, 17:27   #1
s_bag
 
Регистрация: 16.08.2013
Сообщений: 8
По умолчанию Пользовательская функция с необязательными параметрами

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

Function СумЦвет(диапазон As Range, критерий1 As Range, Optional критерий2 As Range = "", _
Optional критерий3 As Range = "") As Double
' Суммирует значения ячеек в "диапазоне",
' цвет которых совпадает с цветом в ячейке одного из "критериев"
Application.Volatile True
Dim i As Range
For Each i In диапазон
If i.Interior.Color = критерий1.Interior.Color Or _
i.Interior.Color = критерий2.Interior.Color Or _
i.Interior.Color = критерий3.Interior.Color Then
СумЦвет = СумЦвет + i
End If
Next
End Function
Вложения
Тип файла: zip Необязательный параметр в функции VBA.zip (13.6 Кб, 11 просмотров)
s_bag вне форума Ответить с цитированием
Старый 07.11.2013, 17:29   #2
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

если есть критерий2 то
если есть критерий3 то
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 07.11.2013, 17:48   #3
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Универсальный вариант функции (количество параметров не ограничено):

Код:
Function СумЦвет(диапазон As Range, ParamArray критерии() As Variant) As Double
    ' Суммирует значения ячеек в "диапазоне",
    ' цвет которых совпадает с цветом в ячейке одного из "критериев"
    Application.Volatile True
    Dim res As Boolean, cell As Range
    For Each cell In диапазон.Cells
        res = False
        For Each ra In критерии
            res = res Or ra.Interior.Color = cell.Interior.Color
        Next
        If res Then СумЦвет = СумЦвет + Val(Replace(cell, ",", "."))
    Next cell
End Function
Пример использования в формуле:
Код:
=СумЦвет(D1:D15;F3;I5;L11;N7)
EducatedFool вне форума Ответить с цитированием
Старый 07.11.2013, 17:48   #4
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Например так (побыстрее):
Код:
Function СумЦвет2(диапазон As Range, критерий1, Optional критерий2, _
                  Optional критерий3) As Double
' Суммирует значения ячеек в "диапазоне",
' цвет которых совпадает с цветом в ячейке одного из "критериев"
    Application.Volatile True
    Dim i As Range
    On Error Resume Next
    критерий1 = критерий1.Interior.Color
    критерий2 = критерий2.Interior.Color
    критерий3 = критерий3.Interior.Color
    On Error GoTo 0
    If IsMissing(критерий2) Then критерий2 = -1
    If IsMissing(критерий3) Then критерий3 = -1
    For Each i In диапазон
        Select Case i.Interior.Color
        Case Is = критерий1: СумЦвет2 = СумЦвет2 + i
        Case Is = критерий2: СумЦвет2 = СумЦвет2 + i
        Case Is = критерий3: СумЦвет2 = СумЦвет2 + i
        End Select
    Next

End Function
Но конечно возможны и другие варианты.
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 07.11.2013, 18:07   #5
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Ещё идея быстрого алгоритма для случая "много цветов и ячеек" (и для paramarray() тоже):
в начале кода собираем в словарь цвета критериев (именно значение цвета), затем в цикле по ячейкам каждую проверяем на наличие в словаре её цвета.
Так избавимся от лишних циклов в цикле и лишних проверок.
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 07.11.2013, 18:58   #6
maksim_serg
Форумчанин
 
Аватар для maksim_serg
 
Регистрация: 25.03.2010
Сообщений: 417
По умолчанию

Уважаемые знатоки, для общего развития объясните эту строчку:
Код:
Dim res As Boolean, cell As Range
    For Each cell In диапазон.Cells
        res = False
        For Each ra In критерии
            res = res Or ra.Interior.Color = cell.Interior.Color
        Next
        If res Then СумЦвет = СумЦвет + Val(Replace(cell, ",", "."))
    Next cell
maksim_serg вне форума Ответить с цитированием
Старый 07.11.2013, 19:49   #7
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

опа!))

по типам операторов приоритеты такие
арифметические операторы
операторы сравнения
логические операторы
в каждом типе своя шкала приоритетов: знаете что 3+2*5 = 13 (а не 25).

Код:
res = res Or ra.Interior.Color = cell.Interior.Color
так вот в этой строке сначала выполниться оператор сравнения
ra.Interior.Color = cell.Interior.Color (результат ЛОЖЬ или ИСТИНА)
потом
логический оператор Or
потом оператор присвоения переменной res результата выполнения предыдущих операторов.
если бы было
Код:
res = res Or ra.Interior.Color = cell.Interior.Color*1
то самым первым выполнилось бы
cell.Interior.Color*1, а потом это уже сравнивалось бы с ra.Interior.Color и т.д.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 07.11.2013, 20:08   #8
maksim_serg
Форумчанин
 
Аватар для maksim_serg
 
Регистрация: 25.03.2010
Сообщений: 417
По умолчанию

это то понятно, но если ее перевести на "русский" то получиться:
ИСТИНА(res = res) или ИСТИНА(ra.Interior.Color = cell.Interior.Color)
и что она должна сделать?
maksim_serg вне форума Ответить с цитированием
Старый 07.11.2013, 20:23   #9
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

нет первый = это не сравнение это присвоение res = ...
встречались с таким i = i+1 у i теперь новое значение на 1 больше чем до того.
в результате выполнения этой строки
res = res Or ra.Interior.Color = cell.Interior.Color
res получит новое значение
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 07.11.2013, 20:32   #10
maksim_serg
Форумчанин
 
Аватар для maksim_serg
 
Регистрация: 25.03.2010
Сообщений: 417
По умолчанию

хорошо, переведем по другому:
res= ЛОЖЬ(Dim res As Boolean) или ИСТИНА(ra.Interior.Color = cell.Interior.Color)
и итог?
maksim_serg вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
пользовательская функция МАКСЕСЛИМН Zorg Microsoft Office Excel 7 22.06.2012 11:43
Пользовательская функция с неопределенным количеством параметров savraska Microsoft Office Excel 1 23.05.2010 12:00
Пользовательская функция с необязательными параметрами savraska Microsoft Office Excel 2 23.05.2010 11:47
Пользовательская функция,возвращающая массив savraska Microsoft Office Excel 2 20.04.2010 03:12
Функция с необязательными параметрами anGeee Общие вопросы Delphi 6 07.08.2009 10:46