在女同学的诱惑下,我第一次写了VBA代码
VB真的还是高一时候的事情了,还记得那啥冒泡排序,擂台法等等等。
这是我一个朋友的故事,以下就以第一人称来叙述
故事开始了
某日在外校上课回家路上,看见女同学发来消息,甚是激动
点看一看:你会VBA么?(内心:啥,那是啥)
赶紧查百度,原来是给Excel这种用的VB
回:是VB代码么,虽然只在高中学过,难度应该不大(内心:这下可能吹牛吹大了,毕竟虽然是学计算机的,但平时根本不会自己去写写代码)
之后便是那么一点点,一点点无关痛痒的对话,第一次交流就结束了
心脏因为这次突然的消息,多跳了几拍
之后的一段时间内,什么消息都没有,内心稍感难耐,而寂(第二声)寞(第四声)。
期间偶尔会有几幅图片发过来让咱帮忙看看某几句话是啥意思,模糊的还被我用高超的PS技术——锐化了一下。
直到临近期末考试的前两周
提一句:那学期的期末考试简直是魔鬼般的安排,5天8门课,包括计算机网络、图形学、计算机体系结构、单片机、算法设计与分析等等
女同学让咱帮忙外包一个Excel里面写VBA的大作业,需求还需要进一步讨论,报酬说能合理范围随便开
最最最开始
我甚至想直接无偿帮忙写掉得了
等等!(尔康手)
我是不是快要考试了
稍微冷静一下了
开始纠结要不要写,毕竟没有真正接触过VBA
再考虑一下
人家女同学难得要人帮忙,再说是个不错的交流机会
辗转再三
数据库那门我就基本没听过,其他课也就上课听听……
最终
接活,但无偿显得,emmmm,prprprprprpr?
为了“平等关系”,便让女同学随便买些零食作为报酬(瞧瞧你这肥仔啥志气)
第一次,从零开始,自学,时间紧迫,可慌了
但也感谢有了这次经历,让我之后从0开始学习用python去写编译原理实验的时候,没那么慌了。
哦,先说结果吧
可能是看在文科生的份上,那边的老师给了90+,我寻思可能都没用上那边课上的东西hhh
首页,只有一个录入成绩,本来只做了单个的成绩录入,被那边的老师初审说太鸡肋了。
只能录入一个人的成绩,确实鸡肋
sheet2中的内容,根据路径是被说鸡肋后加的,直接通过文件导进数据,计算2项平均分
接下去是根据前表,按个按钮,生成折线图,直观清晰,还很贴心地取了上下界,美观
接下去上代码
因为要让女同学答辩的时候也没问题,写了很多注释
鸡肋的单个添加
'初始化班级下拉表格
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,专业第一,一定也有我这朋友稍微一点点小小而微不足道的功劳吧
推荐阅读