用excel操作variables

语言:Excel

您好,感谢您阅读我的文章。

我正在尝试创build一个公式,以便…根据variables乘以单元格(或在这种情况下的字母)。 variables是可以被(1000 + 250x)整除的,根据答案乘以相应的字母百分比。

视觉performance:

ABC 1% 2% 3% 250 500 1000 1 1,000 2 1,250 3 1,500 4 1,750 5 2,000 

例如,因为#1可以被1000整除,所以我会把它乘以3%二次,因为#2可以被250整除,1000,我会把250乘以1%和1000乘以3%,然后add他们在一起。

我目前的尝试:

 =IF(MOD(A2,F14)<=1,A2*F15,"") 

A2 =起始金额F14 = A2除以的金额
F15 =百分比

这种作品,但它不允许我find最好的解决scheme

将非常感谢您在我的困境中的帮助。

我不能想像Excel公式的任何好的解决scheme,因为你想要的结果太复杂了:就像你标记了你的问题,你需要一个循环,不pipe怎样,哪个公式不能为你做。
但是,当您将VBA添加为您的标签之一时,我认为VBA解决scheme适用于您,所以我写了这个脚本:

 Option Explicit 'variables MUST BE declared, otherwise error. very handy rule Option Base 0 'won't be needed this time, but in general, this rule is also a great ally 
'(it says: arrays' 1st item will always be the "0th" one)
Dim divLARGE, divMED, divSMALL 'you can use variable types in Excel Dim percLARGE, percMED, percSMALL 'but sadly, not in VBScript which I have ATM

'test input values and their results, won't be needed in your Excel Dim testA, testB, testC, testD, testE, testF 'so add types if you like Dim resA, resB, resC, resD, resE, resF '(should make execution a little faster)

'Init our variables declared above. in VBScript you can't do this at declaration,
'ie can't say "Dim whatever As Boolean = true" which would be the right way to do this Call Initialize()

'Call the "main routine" to execute code
Call Main()

'you can add access modifiers here. "private" would be the best
'ie "private Sub Main()" Sub Main() resA = CalcMaster(testA, divLARGE) resB = CalcMaster(testB, divLARGE) resC = CalcMaster(testC, divLARGE) resD = CalcMaster(testD, divLARGE) resE = CalcMaster(testE, divLARGE) resF = CalcMaster(testF, divLARGE) MsgBox (CStr(testA) + " --> " + CStr(resA) + vbCrLf + _ CStr(testB) + " --> " + CStr(resB) + vbCrLf + _ CStr(testC) + " --> " + CStr(resC) + vbCrLf + _ CStr(testD) + " --> " + CStr(resD) + vbCrLf + _ CStr(testE) + " --> " + CStr(resE) + vbCrLf + _ CStr(testF) + " --> " + CStr(resF) + vbCrLf) End Sub
Sub Initialize() divLARGE = 1000 'the large number for which we look after remnants divMED = 500 'medium/middle sized number to divide by divSMALL = 250 'the small value percLARGE = 3 'percentage we want if no remnants on LARGE number percMED = 2 'same but for medium/mid size numbers percSMALL = 1 'and the percentage we want for the small remnants
testA=1000 'result should be exactly 30.0 testB=1250 'res == 32.5 testC=1500 'res == 40.0 testD=1750 'res == 42.5 testE=2000 'res == 60.0 testF=-198 'res == #ERROR/INVALID VALUE End Sub
Function CalcMaster(inVar, byDiv) 'A silly function name popped in my mind, sorry :) Dim remnant, percDiv
'sometimes happens, looks cheaper calc.wise to handle like this; if initial input
'can be 0 and that's a problem/error case, handle this scenario some other way If (inVar = 0) Then Exit Function remnant = inVar Mod byDiv 'if you'll implement more options, do a Select...Case instead (faster) If (byDiv = divLARGE) Then percDiv = percLARGE ElseIf (byDiv = divMED) Then percDiv = percMED Else percDiv = percSMALL End If

If (remnant = 0) Then CalcMaster = inVar * (percDiv / 100) Exit Function End If 'had remnant; for more than 3 options I would use an array of options 'and call back self with the next array ID If (byDiv = divLARGE) Then CalcMaster = CalcMaster(inVar - remnant, divLARGE) + CalcMaster(remnant, divMED) ElseIf (byDiv = divMED) Then CalcMaster = CalcMaster(inVar - remnant, divMED) + CalcMaster(remnant, divSMALL) Else 'or return 0, or raise error and handle somewhere else, etc 'MsgBox ("wrong input number: " + CStr(inVar)) CalcMaster = -1 End If End Function

这不是完美的,我认为可以有更好的解决scheme,但我认为这是足够好的原因。 我希望你同意:)
干杯

在Sparrow解释之后,我得到了“最好的解决scheme”是将所有可能的整除因子(即250,500,1000)乘以其通讯员“奖”(1%,2% 3%)

这是一个相应的解决scheme

 Option Explicit Sub main() Dim dataRng As Range, cell As Range, percRng As Range, divRng As Range Dim i As Long, value As Long, nDivisors As Long Dim prize As Double, totalPrize As Double Set dataRng = ActiveSheet.Range("B1:B10") '<== here set the range cointaining the numbers to be processed Set percRng = ActiveSheet.Range("F15:H15") '<== here set the range of % "prizes": they MUST be in ascending order (from lowest to highest) Set divRng = ActiveSheet.Range("F14:H14") '<== here set the range of the possible divisors. this range MUST be of the same size as thre "prizes" range For Each cell In dataRng.SpecialCells(xlCellTypeConstants, xlNumbers) value = cell.value nDivisors = 0 prize = 0 totalPrize = 0 Do i = FindMaxDivisor(value, percRng, divRng) If i > 0 Then value = value - divRng(i) ' update value to the remainder prize = percRng(i) * divRng(i) ' get current "prize" totalPrize = totalPrize + prize 'update totalprize nDivisors = nDivisors + 1 'update divisors number cell.Offset(, nDivisors) = divRng(i) 'write divisor in next blank adjacent cell in the number row End If Loop While value > 0 And i >= 0 If i >= 0 Then ' the number has been correctly divided by given divisors With cell.Offset(, nDivisors + 1) .value = totalPrize .Font.Color = vbRed End With Else MsgBox "Not possible to break " & cell.value & " into given divisors" End If Next cell End Sub Function FindMaxDivisor(value As Long, percRng As Range, divRng As Range) As Long Dim i As Long FindMaxDivisor = -1 'default value should not be found any whole divisor i = divRng.Columns.Count Do While value Mod divRng(i) <> 0 And i > 1 i = i - 1 Loop If value Mod divRng(i) = 0 Then FindMaxDivisor = i End Function 

每个数字“最好”的除数将被写在数字旁边的列中,最后一个将会写入“总奖”为红色