|
试试我写的自定义函数吧[C2公式“=bestab(B2,A2,1,1)”]:- Option Explicit
- Function iiatax(x As Double, y As Integer, Optional z As Double) '独立所得税计算函数
- 'y=1 计算中国公民工薪所得税
- 'y=2 计算外国公民工薪所得税
- 'y=3 计算劳务所得税
- 'z 可选,年终一次性奖金发放当月的计税工资
- 'Application.Volatile False
- If IsNumeric(x) = False Then
- iiatax = "#NUM" '计税工资非数值
- Exit Function
- End If
- If x < 0 Then
- iiatax = "-#VAL" '计税工资为负
- Exit Function
- End If
- Dim basicnum As Integer, i As Integer
- Dim downnum As Variant, upnum As Variant, ratenum As Variant, deductnum As Variant, laowudeduct As Variant
- Dim gongxin As Double, laowu As Double, nianjiang As Double
- downnum = Array(0, 1500, 4500, 9000, 35000, 55000, 80000) '定义累进区间下限
- upnum = Array(1500, 4500, 9000, 35000, 55000, 80000, 100000000) '定义累进区间上限
- ratenum = Array(0.03, 0.1, 0.2, 0.25, 0.3, 0.35, 0.45) '定义累进税率
- deductnum = Array(0, 105, 555, 1005, 2755, 5505, 13505) '定义累进速算扣除数
- Select Case y
- Case 1
- basicnum = 3500 '中国公民个税起征点,2011年9月1日起执行
- Case 2
- basicnum = 4800 '外籍公民个税起征点
- Case 3 '劳务所得税
- downnum = Array(0, 4000, 20000, 50000)
- upnum = Array(4000, 20000, 50000, 100000000)
- ratenum = Array(0.2, 0.2, 0.3, 0.4)
- deductnum = Array(0, 0, 2000, 7000)
- laowudeduct = Array(800, x * 0.2, x * 0.2, x * 0.2)
- For i = 0 To UBound(downnum)
- If x > downnum(i) And x <= upnum(i) Then
- laowu = (x - laowudeduct(i)) * ratenum(i) - deductnum(i)
- Exit For
- End If
- Next i
- Case Else
- iiatax = "#N/A" '参数不能识别
- Exit Function
- End Select
- If z > 0 Then '数月奖金计税
- For i = 0 To UBound(downnum)
- If x / 12 > downnum(i) And x / 12 <= upnum(i) Then
- nianjiang = Application.Max((x - Application.Max(basicnum - z, 0)) * ratenum(i) - deductnum(i), 0)
- Exit For
- End If
- Next i
- Else '计算工薪所得税
- For i = 0 To UBound(downnum)
- If x - basicnum > downnum(i) And x - basicnum <= upnum(i) Then
- gongxin = (x - basicnum) * ratenum(i) - deductnum(i)
- Exit For
- End If
- Next i
- End If
- If y = 3 Then gongxin = 0
- iiatax = Application.Round(gongxin + laowu + nianjiang, 2)
- End Function
- Function BestAB(dbl1 As Double, dbl2 As Double, isCN As Boolean, isTrap As Boolean)
- 'dbl1,数月奖金发放当月计税工资
- 'dbl2,数月奖金金额
- 'isCN,“0”为外籍员工,“1”为中籍员工
- 'isTrap,“0”为疯狂模式,“1”为陷阱模式
- Dim r1 As Double, r2 As Double, s As Double, i As Double, arr(9999, 4), j%
- '求优化前的应纳税额
- r2 = iiatax(dbl1, IIf(isCN, 1, 2)) + iiatax(dbl2, IIf(isCN, 1, 2), dbl1)
- For i = 0 To dbl1 + dbl2 Step 500
- '奖金调节为i时,求纳税额
- arr(j, 0) = iiatax(dbl1 + dbl2 - i, IIf(isCN, 1, 2)) + iiatax(i, IIf(isCN, 1, 2), dbl1 + dbl2 - i)
- '工资调节为i时,求纳税额
- arr(j, 1) = iiatax(i, IIf(isCN, 1, 2)) + iiatax(dbl1 + dbl2 - i, IIf(isCN, 1, 2), i)
- arr(j, 2) = i '奖金额
- arr(j, 3) = dbl1 + dbl2 - i '工资额
- r1 = arr(j, 0)
- If isTrap Then '如果是陷阱模式的话,只向下调节奖金
- If r1 <= r2 And i < dbl2 Then
- r2 = r1
- s = i
- End If
- Else '如果是疯狂模式的话,工资奖金双向调节,直至最优
- If r1 <= r2 Then
- r2 = r1
- s = i
- End If
- End If
- j = j + 1
- Next
- If s = 0 Or Round(iiatax(dbl1 + dbl2 - s, IIf(isCN, 1, 2)) + iiatax(s, IIf(isCN, 1, 2), dbl1 + dbl2 - s), 2) = Round(iiatax(dbl1, IIf(isCN, 1, 2)) + iiatax(dbl2, IIf(isCN, 1, 2), dbl1), 2) Then
- BestAB = dbl2
- Else
- BestAB = s
- End If
- End Function
复制代码 |
|