Страницы: 1
RSS
Вычисление значения по многим параметрам в VBA, Создание функции, вычисляющей значение по множеству параметров.
 
Приветствую всех!
Снова мой неугомонный моск не дает мне покоя. Перечитал все доступные заголовки, не смог правильно сформулировать поисковый запрос поэтому рискнул создать новую тему. Имеется задача: вычислить значение исходя из множества параметров.
Пример:
Вычислить стоимость разгрузки груза. Груз может весить до 10 тонн и больше 10 тонн, может быть деревянный или железный, на паллетах или навалом, на колесах или не на колесах, в контейнере или не в контейнере и еще ряд параметров. на каждый вид груза и каждое сочетание имеется своя цена.
Я решил сделать функцию на VBA, которая будет перебирать все параметры IF-Else – ами и в зависимости от сочетания производить вычисления.
Код
Function LUW(Вес, ТипГруза, НаПаллете, Самоход, Контейнер, Ставка_дер_до10т, Ставка_дер_больше10т, Ставка_железный, Ставка_безпалета…. и там далее все аргументы и ставки)
 
If ТипГруза = 1 Then                 ‘ как бы 1 – это деревянный. Если груз деревянный, ТО
   If НаПаллете = True Then             ‘ проверяем на паллете он или нет, Если да, ТО
      If Вес <= 10 Then                    ‘ проверяем сколько весит. Если меньше 10 т, ТО
      LUW = Вес * Ставка_дер_до10т          ‘соответствующая ставка умножается на вес
      Else: LUW = Вес * Ставка_дер_больше10т   ‘ если больше 10 т, то другая ставка
      End If
   Else: LUW = Вес * Ставка_безпалета ‘ если деревянный груз без паллета
   End If
Else: LUW = … ‘Если груз НЕ ДЕРЕВЯННЫЙ… Вот тут и ступор. Получается нужно обращаться опять к условию проверки «На_паллете» и я начинаю тупить…
End If
 
End Function
И еще, получается, что при моей логике у функции 24!!! аргумента. В целом это не большая проблема, но может кто-нить знает более изящное решение?
Лишь стремясь к невозможному, можно достичь максимального.
 
Для начала нужна отдельная линейная таблица соответствий всех комбинаций параметров искомым значениям. С этой таблицей хоть макросами, хоть формулой найти нужное значение уже элементарно.
 
Влад, вариант. Мне почему-то это  вголову не пришло... Наверное потму, что хотел заставить программный код делать эту линейную таблицу соответствий...
А вот как избежать повторения условия отбора? Что бы 2 раза не проверять одно и тоже.
Изменено: Сергей Сахаров - 25.02.2016 12:07:57
Лишь стремясь к невозможному, можно достичь максимального.
 
Сергей Сахаров, ставки наверно не надо передавать как аргументы в функцию, функция может брать их из определенного места (например, отдельного скрытого листа).
Код можно несколько сократить с помощью IIf
Код
Function LUW(Вес, ТипГруза, НаПаллете, Самоход, Контейнер, Ставка_дер_до10т, Ставка_дер_больше10т, Ставка_железный, Ставка_безпалета)

  Select Case ТипГруза
  Case 1                                              ' как бы 1 – это деревянный. Если груз деревянный, ТО
    LUW = Вес * IIf(НаПаллете, IIf(Вес <= 10, Ставка_дер_до10т, Ставка_дер_больше10т), Ставка_безпалета)
  Case 2                                              'другой тип груза
    '
  Case Else 'неизвестный тип груза
    LUW = CVErr(xlErrNA) '#Н/Д
  End Select

End Function
Для другого типа груза, конечно, тоже надо проверять "на паллете". Повторы неизбежно будут - или в коде, или в таблице.
 
Казанский, спасибо! Короче учиться мне еще и учиться. Надо матчасть изучить. Я про Select Case вообще не знал.
Изменено: Сергей Сахаров - 25.02.2016 18:26:44
Лишь стремясь к невозможному, можно достичь максимального.
 
Сергей Сахаров, посмотрите здесь http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=75008&TITLE_SEO=75008-blizhay...  
 
tkachev.al, да. Я эту ветку читал, ковырял, но что-то мне не понравилось. Мне Select Case и Казанский, весьма помогли! Получилось, на мой взгляд, неплохо. Иглавное работает!!!  :D
Код
Function LUW(Weight_ц, Vol_cbm, CargoType, Pallet)
Dim Rate_min, Rate_upto10k, Rate_more10k, Rate_nopal, Rate_st_pal, Rate_st_nopal As Currency
Rate_min = Sheets("Crocus for HMS").Range("EX_MIN")
Rate_upto10k = Sheets("Crocus for HMS").Range("EX_up2_10K")
Rate_more10k = Sheets("Crocus for HMS").Range("EX_over_10K")
Rate_nopal = Sheets("Crocus for HMS").Range("EX_NO_PAL")
Rate_st_pal = Sheets("Crocus for HMS").Range("STND")
Rate_st_nopal = Sheets("Crocus for HMS").Range("STND_NO_PAL")
Select Case Pallet
        Case True
            Select Case CargoType
                    Case 1
                    LUW = IIf(Weight_ц <= 2, Rate_min, IIf(Weight_ц < 100, Weight_ц * Rate_upto10k, Weight_ц * Rate_more10k))
                    Case 2
                    LUW = Vol_cbm * Rate_st_pal
            End Select
        Case False
                    Select Case CargoType
                        Case 1
                        LUW = Weight_ц * Rate_nopal
                        Case 2
                        LUW = Vol_cbm * Rate_st_nopal
                    End Select            
End Select

End Function
Изменено: Сергей Сахаров - 25.02.2016 19:48:35
Лишь стремясь к невозможному, можно достичь максимального.
Страницы: 1
Наверх