欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在女同学的诱惑下,我第一次写了VBA代码

程序员文章站 2022-07-14 14:38:58
...

VB真的还是高一时候的事情了,还记得那啥冒泡排序,擂台法等等等。
这是我一个朋友的故事,以下就以第一人称来叙述

故事开始了

某日在外校上课回家路上,看见女同学发来消息,甚是激动
点看一看:你会VBA么?(内心:啥,那是啥)
赶紧查百度,原来是给Excel这种用的VB
回:是VB代码么,虽然只在高中学过,难度应该不大(内心:这下可能吹牛吹大了,毕竟虽然是学计算机的,但平时根本不会自己去写写代码)
之后便是那么一点点,一点点无关痛痒的对话,第一次交流就结束了

心脏因为这次突然的消息,多跳了几拍

之后的一段时间内,什么消息都没有,内心稍感难耐,而寂(第二声)寞(第四声)。
期间偶尔会有几幅图片发过来让咱帮忙看看某几句话是啥意思,模糊的还被我用高超的PS技术——锐化了一下。
在女同学的诱惑下,我第一次写了VBA代码

直到临近期末考试的前两周

提一句:那学期的期末考试简直是魔鬼般的安排,5天8门课,包括计算机网络、图形学、计算机体系结构、单片机、算法设计与分析等等
女同学让咱帮忙外包一个Excel里面写VBA的大作业,需求还需要进一步讨论,报酬说能合理范围随便开
最最最开始
我甚至想直接无偿帮忙写掉得了
等等!(尔康手)
我是不是快要考试了
稍微冷静一下了
开始纠结要不要写,毕竟没有真正接触过VBA
再考虑一下
人家女同学难得要人帮忙,再说是个不错的交流机会
辗转再三
数据库那门我就基本没听过,其他课也就上课听听……
最终
接活,但无偿显得,emmmm,prprprprprpr?
为了“平等关系”,便让女同学随便买些零食作为报酬(瞧瞧你这肥仔啥志气)

第一次,从零开始,自学,时间紧迫,可慌了

但也感谢有了这次经历,让我之后从0开始学习用python去写编译原理实验的时候,没那么慌了。
哦,先说结果吧
可能是看在文科生的份上,那边的老师给了90+,我寻思可能都没用上那边课上的东西hhh

首页,只有一个录入成绩,本来只做了单个的成绩录入,被那边的老师初审说太鸡肋了。

在女同学的诱惑下,我第一次写了VBA代码

只能录入一个人的成绩,确实鸡肋

在女同学的诱惑下,我第一次写了VBA代码

sheet2中的内容,根据路径是被说鸡肋后加的,直接通过文件导进数据,计算2项平均分

在女同学的诱惑下,我第一次写了VBA代码

接下去是根据前表,按个按钮,生成折线图,直观清晰,还很贴心地取了上下界,美观

在女同学的诱惑下,我第一次写了VBA代码

接下去上代码

因为要让女同学答辩的时候也没问题,写了很多注释

鸡肋的单个添加

'初始化班级下拉表格
Private Sub CB_class_Enter()
'可视化窗口控制函数,自带的,咱试了好久才找对这个函数
If CB_class.ListCount = 0 Then
'如果现在下拉框是空的,那么
    CB_class.AddItem ("六(一)班")
    '加入“六一班”这个项目
    CB_class.AddItem ("六(二)班")
    '加入“六二班”这个项目
    Else
    '否则,什么都不做,这句else可以写,但没必要
End If
'结束判断
End Sub
'进行赋值,按钮按下操作
Private Sub CB_submit_Click()
'定义赋值
Dim i As Integer
'i控制找表
Dim a As Integer
'a控制行,检索有没有被填,往下
Dim ws
Dim temp As String
'定义临时变量temp为字符串类型,可以任务就是文字
'初始化
i = 1
a = 1
'匹配工作表名
Do While i <= ThisWorkbook.Sheets.count
'当i小于等于当前表的数量时,开始循环
'进入判断
If CB_class.Text = Worksheets(i).Name Then
'找到了对应表,填入数据
Set ws = Worksheets(i)   
    '咱觉得这里写注释也不一定看得懂(只可意会不可言传(fnmdp))
    '先检索一遍有没有相同的学号,如果有,开始填入选择的轮次的成绩,如果没有,找到空行,填入数据
    Do While a <= ws.UsedRange.Columns.count + 65500
        If ws.Cells(a, 1) = TB_stuno.Text Then
        ws.Cells(a, CB_testno.Text + 2) = TB_score.Text
        GoTo 20
        Else
            If a = ws.UsedRange.Rows.count + 1 Then
            ws.Cells(a, 1) = TB_stuno.Text
            ws.Cells(a, 2) = TB_name.Text
            ws.Cells(a, CB_testno.Text + 2) = TB_score.Text
            GoTo 20
            End If
        End If
    a = a + 1
    Loop
20:    Range("f2") = t$
End If
i = i + 1
Loop
MsgBox "添加完成", vbOKOnly
End Sub
'初始化考试轮次下拉表格,和上面类似

Private Sub CB_testno_Enter()
If CB_testno.ListCount = 0 Then
CB_testno.AddItem (1)
CB_testno.AddItem (2)
CB_testno.AddItem (3)
CB_testno.AddItem (4)
CB_testno.AddItem (5)
CB_testno.AddItem (6)
CB_testno.AddItem (7)
CB_testno.AddItem (8)
Else
End If
End Sub

从别的文件那里导入

Sub insert_1()
Dim wb As Workbook
Dim amount As Integer
Dim tstno As Integer
'保存第几次考试数据(1,3)
Dim i As Integer
'学生人数
Dim j As Integer
Dim n As Integer
Dim no As String
Dim path As String
'定义路径


'输入一个路径
Dim message, title
message = "请输入路径"
title = "考试成绩路径"
path = InputBox(message, title)
'MsgBox myvalue1 & "===" & myvalue2 & "数据类型:" & TypeName(myvalue2)
'path赋值用来代替下面的open

n = 1
'初始化
Do While n <= 8
'小于等于考试次数,可以加个输入框,但没必要

no = Str(n)
Set wb = Workbooks.Open("" & path & "\第" & no & "次考试成绩")
'打开表,循环打开
Set ws = Workbooks("拖喇涩 v0.45").Worksheets("六(一)班")
'这个表要加数据,到时候把test-1这个名字替换掉
Set wsout = wb.Worksheets(1)

i = 0
j = 0
amount = wsout.UsedRange.Rows.count - 2
tstno = wsout.Cells(1, 3).Value
'获取姓名学号
Do While j < 2
    Do While i < amount
    ws.Cells(i + 2, j + 1).Value = wsout.Cells(i + 2, j + 1).Value
    i = i + 1
    Loop
i = 0
j = j + 1
Loop

Do While i < amount
ws.Cells(i + 2, tstno + 2).Value = wsout.Cells(i + 2, 3).Value
i = i + 1
Loop

n = n + 1
wb.Close
Loop
End Sub

单次考试平均分

Sub avr()
Dim sum As Integer
'定义sum为整型,即整数
Dim countstu As Integer
'定义countstu为整型
Dim counttst As Integer
Dim i As Integer
Dim j As Integer
j = 0
'初始化j=0
i = 0
'初始化
sum = 0
'初始化
Set sht1 = ThisWorkbook.Worksheets("六(一)班")
'指定sht1为名字是“六(一)班”的表
countstu = sht1.Cells(sht1.Rows.count, 1).End(xlUp).Row - 1
'学生人数countstu为行数-1
counttst = sht1.UsedRange.Columns.count - 2
'考试次数counttst为列数-2
sht1.Cells(countstu + 2, 2).Value = "平均分"
'最后一行第二格添加一个平均分的项目

'这是外层的循环,内层全部走完外层走一次
Do While j < counttst
'开始外层循环,当j小于考试次数

    '这是内层的循环
    Do While i < countstu
    '当i小于学生数
     sum = sum + sht1.Cells(2 + i, j + 3)
     '求成绩和
     i = i + 1
     '向同一列往下跳一格
    Loop
    'i在这里循环
           
    sht1.Cells(2 + i, j + 3).Value = sum \ countstu
    '算出每次考试的平均值,赋值到sht1.Cells(2 + i, j + 3)
    sum = 0
    '初始化一次sum
    i = 0
    '初始化一次i
    j = j + 1
    '下一次考试
Loop
'内层循环
End Sub

个人平均分

Sub avr()
'求个人成绩平均分
Dim sum As Integer
'定义sum为整型,即整数
Dim countstu As Integer
'定义countstu为整型
Dim counttst As Integer
Dim i As Integer
Dim j As Integer
j = 0
'初始化j=0
i = 0
'初始化
sum = 0
'初始化
Set sht1 = ThisWorkbook.Worksheets("六(一)班")
'指定sht1为名字是“六(一)班”的表
countstu = sht1.Cells(sht1.Rows.count, 1).End(xlUp).Row - 1
'学生人数countstu为行数-1
counttst = sht1.UsedRange.Columns.count - 2
'考试次数counttst为列数-2
sht1.Cells(1, counttst + 3).Value = "平均分"
'最后一列最上面添加一个平均分的项目

'这是外层的循环,内层全部走完外层走一次
Do While j < countstu
'开始外层循环,当j小于学生人数

    '这是内层的循环
    Do While i < counttst
    '当i小于考试次数
     sum = sum + sht1.Cells(2 + j, 3 + i)
     '求和
     i = i + 1
     '向同一行往右跳一格
    Loop
    'i在这里循环
    
    sht1.Cells(2 + j, i + 3).Value = sum \ counttst
     '算出个人考试的平均值,赋值到sht1.Cells(2 + i, j + 3)
    sum = 0
    '初始化和
    i = 0
    '初始化i
    j = j + 1
    '下一个学生
Loop
End Sub

生成折线图

Sub test()
    ThisWorkbook.Sheets.Add after:=Worksheets(ThisWorkbook.Sheets.count)
    '在最后加一个表
    Worksheets(ThisWorkbook.Sheets.count).Name = "六(一)班个人成绩折线图"
    '指定表表名字
    Set sht2 = ThisWorkbook.Worksheets("六(一)班个人成绩折线图")
    '指定sht2为名字是“六(一)班个人成绩折线图”的表
    Set sht1 = ThisWorkbook.Worksheets("六(一)班")
    '指定sht1为名字是“六(一)班”的表
    Dim i As Integer
    Dim m As Integer
    Dim tempmax As Integer
    Dim count As Integer '考试次数
    Dim tempmin As Integer '最低成绩
    Dim test As Integer  '行数测试
    Dim x As Integer
    Dim y As Integer   
    i = 2   '控制循环
    test = sht1.Cells(sht1.Rows.count, 1).End(xlUp).Row
    'test=行数,好像后面就没咋用到了    
    Do While i < sht1.Cells(sht1.Rows.count, 1).End(xlUp).Row
    '按人数控制循环    
    '初始化
    m = 0
    x = 0
    y = 0
    
    count = sht1.UsedRange.Columns.count - 2
    'count=列数-2,即考试次数
    tempmin = sht1.Cells(i, 3 + m).Value
    '临时变量min=这位学生第一次考试的值,相当于是初始化
    tempmax = sht1.Cells(i, 3 + m).Value
    '临时变量max=这位学生第一次考试的值,相当于是初始化
         
    '先求成绩最小值
    'do while 到loop是个循环体,即循环这两句话之间的内容,直到达成判断条件
    Do While m < count - 1
    '这里的判断条件是m<count-1
    
    'if…end if 是判断语句
    If sht1.Cells(i, 3 + m + 1) < tempmin Then
    '如果这个学生的这个成绩比tempmin小
    tempmin = sht1.Cells(i, 3 + m + 1)
    '那么tempmin就更新数据为这次考试的成绩    
    '否则就什么都不做    
    End If
    '结束循环
    m = m + 1
    '走向这个学生的下一次考试
    Loop
    '循环
    m = 0
    '初始化m的值
   
    '求最大值
    Do While m < count - 1
    '如果没有上面初始化m的值,那么现在m的值就是count-1的值
    '下面和求最小值类似
    If sht1.Cells(i, 3 + m + 1) > tempmax Then
    tempmax = sht1.Cells(i, 3 + m + 1)
    End If
    m = m + 1
    Loop
    
    m = m - 1
    '如果没算错现在m应该=count-2
    
     'i此时应该是2
    sht2.Cells((i - 2) * 18 + 1, 1).Value = "姓名"
    sht2.Cells((i - 2) * 18 + 1, 2).Value = "学号"
    '每间隔18行,在第一列生成姓名,学号
    
    '用来生成1,2,3,4……即考试次数,x一开始是0
    Do While x < sht1.UsedRange.Columns.count - 3
    sht2.Cells((i - 2) * 18 + 1, x + 3).Value = x + 1
    x = x + 1
    Loop
    sht2.Cells((i - 2) * 18 + 1, x + 3).Value = "平均分"
    '在后面跟个平均分项
    x = 0
    '只是以防万一初始化一下x的值
         
    '把姓名学号从前面的sht1表里嫖过来
    sht2.Cells((i - 2) * 18 + 2, 1).Value = sht1.Cells(i, 2)
    sht2.Cells((i - 2) * 18 + 2, 2).Value = sht1.Cells(i, 1)
        
    '用来嫖前面表的个人成绩项
    Do While y < sht1.UsedRange.Columns.count - 3
    sht2.Cells((i - 2) * 18 + 2, y + 3).Value = sht1.Cells(i, y + 3)
    y = y + 1
    Loop
    
    sht2.Cells((i - 2) * 18 + 2, y + 3).Value = sht1.Cells(i, y + 3)
    '因为前面用的是<号,所以要在来一次
    y = 0
    '还是以防万一
        
    '用来嫖前面的班级平均分项,用到了x,所以之前的初始化x是有用的(点头)
    sht2.Cells((i - 2) * 18 + 3, 1).Value = "班级平均分"
    Do While x < sht1.UsedRange.Columns.count - 3
    sht2.Cells((i - 2) * 18 + 3, x + 3).Value = sht1.Cells(test + 1, x + 3)
    x = x + 1
    Loop
    x = 0
    '还是以防万一
        
    '设定表格大小
    x = sht1.Cells(4 + (i - 2) * 18, 2).Left
    y = sht1.Cells(4 + (i - 2) * 18, 2).Top
    '起始坐标x,y,看来之前初始化是必要的(其实是偷懒共用了一个变量名字
    w = sht1.Cells(4 + (i - 2) * 18, 2).Width * 10
    h = sht1.Cells(4 + (i - 2) * 18, 2).Height * 15
    '设定宽和高
    Set ch1 = sht2.ChartObjects.Add(x, y, w, h)
    'ch1=在sht2生成的表格

    'chart方法
    ch1.Chart.SetSourceData Source:=sht2.Range(Cells(2 + 18 * (i - 2), 3), Cells(3 + (i - 2) * 18, m + 3))
    '图表里用到的数据范围
    ch1.Chart.SetElement (msoElementDataLabelOutSideEnd)
    '设定图表元素数据标签属性
    ch1.Chart.SetElement (msoElementLegendTrue)
    '设定图表元素,启用legend
    ch1.Chart.SeriesCollection(1).Name = sht2.Cells(2 + 18 * (i - 2), 1)
    ch1.Chart.SeriesCollection(2).Name = sht2.Cells(3 + 18 * (i - 2), 1)
    '设定图表legend名字如“zyc”,“班级平均分”
        
    'chart表名
    ch1.Chart.HasTitle = True
    '这个表有题目
    ch1.Chart.ChartTitle.Text = sht1.Cells(i, 2).Text & "的成绩折线图"
    '这个表的题目是XXX的成绩折线图
        
    'chart折线图分布
    ch1.Chart.ChartType = xlLineMarkers
    '用折线图的方式呈现
    ch1.Chart.Axes(xlValue).MinimumScale = tempmin - 10
    'y轴最小值是这个学生成绩最小值-10
    ch1.Chart.Axes(xlValue).MaximumScale = tempmax + 10
    'y轴最大值是这个学生成绩最小值+10
    ch1.Chart.Axes(xlValue).MajorUnit = (tempmax - tempmin + 20) \ 8
    '间隔平均分8块还是9块来着(???
    
    i = i + 1
    '有请下一位
    
    Loop
    '请继续循环直到满足之前的条件,这个是最外层的循环,咱NB!!!      
End Sub

最后的最后,这位女同学这学年绩点3.88,专业第一,一定也有我这朋友稍微一点点小小而微不足道的功劳吧