VBA语言入门:玩转Excel

再写一篇,记录一下今天的收获!

主题是:通过Excel的宏语言来对其进行自动化~

需求是给一组关于利润(单位:w)的数据如下:

数据\年份12345678910
利润-8-7-5-2-14671015
需纳税利润          

求得需纳税利润。

这里有一个小的要求:

1⃣️当年利润会受到之前5年负利润的抵销。

也就是说对于有正利润的第6年,即使利润为4w,但由于之前五年的负利润(绝对值)>4w,因此第6年的需纳税利润仍为0。做到这一点并不难,但是还有第二个要求:

2⃣️之前抵扣过正利润的负利润,不能在以后的正利润中抵扣。

有点拗口,举个例子。对于第8年,利润为7w。我们可以知道由于第3、4、5年分别为-5、-2、-1,所以第八年仍不用交税,但此时第八年已经将第3、4年的利润抵扣了,因此在计算第9年时,虽然第4、5年表面上都是负利润但是,第4年已经抵扣,所以仅能用第5年进行抵扣,也就是需要以(10-1)作为纳税的基数。

明白了需求,就可以开始写代码了。先用c++进行模拟:

#include<iostream>
using namespace std;

int main() {
    float sq[11] = {0, -8, -7, -5, -2, -1, 4, 6, 7, 10, 15}; //税前利润 便于理解不用第一个元素
    float ksdk[12][11]; //亏损抵扣 全部赋值为0 ksdk[i][i]为真正带入函数前的值 最后一行保存前五年已经抵扣的

    for (int i = 0; i <= 11; i++) { //初始化数据
        for(int j = 0; j <= 10; j++) {
            ksdk[i][j] = 0.0;
        }
    }

    for (int i = 1; i <= 10; i++) { //第一次载入数据 近五年会用到的数据
        for(int j = 1; j <= 10; j++) {
            if ((j > i && (j - i) <= 5 && sq[i]<0) || j == i) ksdk[i][j] = sq[i];

        }
    }

    //输出1
    cout<<"----1----\n";
    for (int i = 1; i <= 11; i++) {
        for(int j = 1; j <= 10; j++) {
            cout<<ksdk[i][j]<<"\t\t";
        }
        cout<<"\n";
    }

    for (int j = 1; j <= 10; j++) {
        if (j > 1) {
            for (int i = 1; i < j; i++){
                if ((j - i) <= 5) ksdk[i][j] = ksdk[i][j-1];
            }
        }
        for (int i = 1; i <=10; i ++) {
            if (j > i && ksdk[i][j] < 0) { //上三角中的负数为有效项
                if (ksdk[j][j] > 0) { //若今年利润为正数则需要检验前五年
                    //ksdk[j][j] += ksdk[i][j]; //今年剩余需要交税的基数
                    if((ksdk[j][j] + ksdk[i][j]) > 0) { //今年剩余需要交税的基数很大
                        ksdk[j][j] = ksdk[j][j] + ksdk[i][j];
                        ksdk[i][j] = 0;
                    }
                    else { //今年剩余需要交税的基数很小 可能可以留下下一年
                        ksdk[i][j] = ksdk[j][j] + ksdk[i][j];
                        ksdk[j][j] = 0;
                        break;
                    }
                }
            }

        }

    }

    //输出2
    cout<<"----2----\n";
    for (int i = 1; i <= 11; i++) {
        for(int j = 1; j <= 10; j++) {
            cout<<ksdk[i][j]<<"\t\t";
        }
        cout<<"\n";
    }

    for (int i = 1; i <= 11; i++) {
        if (ksdk[i][i] > 0) ksdk[11][i] = ksdk[i][i];
    }

    //输出3
    cout<<"----3----\n";
    for (int i = 1; i < 11; i++) {
        cout<<ksdk[11][i]*0.25<<"\t";
    }

}

太棒了,完全可以~(实际上弄了我一上午hhh~

接下来就是VBA化:

Option Base 1
Const TaxRate As Double = 0.25
Sub 计算所得税()

Dim sh As Worksheet
Set sh = Worksheets("sheet1")

Dim sq(1 To 10) As Double '定义待处理的十年数据存储空间
Dim sds(1 To 10) As Double '定义输出

For i = 1 To 10
    sq(i) = sh.Cells(2, i+1) '填入初始数据
    sds(i) = sh.Cells(2, i+1)
Next i

Dim ksdk(10, 10) As Variant

For i = 1 To 10
    For j = 1 To 10
        If j > i AND (j-i) <= 5 AND sq(i) < 0 OR j = i Then
            ksdk(i, j) = sq(i)
        End If
    Next j
Next i

For j = 1 To 10
    If j > 1 Then
        For k = 1 To (j-1)
            If (j-k) <= 5 Then
                ksdk(k, j) = ksdk(k, j-1)
            End If
        Next k
    End If

    For i = 1 To 10
        If j > i AND ksdk(i, j) < 0 Then
            If ksdk(j, j) > 0 Then
                If (ksdk(j, j)+ksdk(i, j)) > 0 Then
                    ksdk(j, j) = ksdk(j, j) + ksdk(i, j)
                    ksdk(i, j) = 0
                Else
                    ksdk(i, j) = ksdk(j, j) + ksdk(i, j)
                    ksdk(j, j) = 0
                    Exit For
                End If
            End If
        End If
    Next i
Next j

For i = 1 To 10
    If ksdk(i, i) > 0 Then
        sh.Cells(3, i+1) = ksdk(i, i) * TaxRate
    Else
        sh.Cells(3, i+1) = 0
    End If
Next i


End Sub

天呐,也是轻轻松松呢~(感觉要被揍一顿了(つД`)ノ

想知道对不对?自己去跑一遍鸭~

以上~这是一篇完全没有营养,只是单纯记录快乐的文章~溜了溜了~

 

正文:

有些事情没去尝试怎么知道自己不行呢?如果想做的话就去试一试呀,哪怕心脏砰砰跳,害怕做不好。可是事实上没有人会在乎的,如果你失败,又多收获一点经验;你成功了,自己心情会为之雀跃。所以,请570同学多多尝试一下。

另外,把编程用在生活中的感觉真好。我爱编程(真香)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值