APP下载

信息专业学生的开发者思维训练

2021-12-19陈浩强吴红燕杨飞谢俊松张海航梁振

电脑知识与技术 2021年32期

陈浩强 吴红燕 杨飞 谢俊松 张海航 梁振

摘要:该文介绍了以基于Excel的信息筛选导出的VBA程序设计项目为基础展开针对初学者的编程实践教学的过程。通过对教学任务的科学分解和演示训练向程序设计初学者展示了一个项目开发的思路和流程,对初学者进一步学习和训练具有积极作用。本文采用的项目开发者的探索式学习方式区别于传统课堂学习场景下的系统性学习方式,对新工科教育的落地、对学生实践应用开发能力和创新能力培养有一定的启发意义。

关键词:Excel;VBA编程;零基础编程;探索式学习;开发者思维

中图分类号:G424      文献标识码:A

文章编号:1009-3044(2021)33-0261-05

The Training of Developer Thinking for Information Majors—Taking the Information Screening Project Based on Excel VBA Programming as an Example

CHEN Hao-qiang1, WU Hong-yan1,YANG Fei1, XIE Jun-song1,  ZHANG Hai-hang2, LIANG  Zhen1

(1.Anhui Medical University , Hefei 230032, China; 2.Hefei No.11 Middle School, Hefei 230011, China)

Abstract: This paper introduces the process of programming practice teaching for beginners on the basis of VBA program design project based on Excel.Through the scientific decomposition and demonstration training of teaching tasks, the idea and process of a project development are shown to the beginners of programming, which has a positive effect on the further learning and training of beginners.

It has a certain enlightening significance for the implementation of new engineering education and the cultivation of students' practical application development ability and innovation ability.

Key words: Excel; VBA programming; zero basic programming; exploratory learning; developer thinking

随着计算机信息处理相关专业的发展,应用软件开发所需的综合技能逐渐增强,所要准备的技术储备也愈加丰富。对于信息工程相关专业的高校学生而言,应用软件開发是非常重要的技能,然而因为各种原因导致学生对软件开发具有畏惧心理,不少学生迟迟不愿动手去进行相关的实践训练。也有许多学生花费了大量时间去学习、实践,还是进展缓慢,无法得到较满意的作品,从而渐渐失去信心和兴趣,转向专注于传统的课堂知识学习,只求课程高分,回避主流的应用技术实践开发活动。没有主流应用技术的土壤滋润,新工科教育要求的“能力”和“创新”方面必然有所欠缺,学校和教育工作者又要在其他方面尽可能提供支持,花费更大的代价[1]。

作者在教学一线进行了大量的座谈和调研,发现学生经常习惯性地带入课课堂教学普遍采用的知识系统学习思维模式,而信息专业实践应用方面的开发工作往往需要根据目标功能就某方面的知识进行针对性深入学习或者探索式学习。这两种学习指导思想本身是根据目标不同而产生,只是在大多数情况下并不能被清晰区分,从而导致学生们在应用能力学习方面付出代价较高。这样的情况下,学生对开发实践可能会产生畏惧心理,还有些学生有了课堂学习无用的想法。甚至有些学生为此不愿去工作而选择进一步考研,希望在研究生阶段能够更加系统地学习相关理论和实践技能,然后再就业从事相关工作。

为了让学生体会到程序设计的开发者思维与系统学习思维的不同,尽可能让他们打消对计算机软件开发的畏惧感,并体会软件开发工作的成就感和乐趣[2]。本文通过对项目式教学的研究,结合多所高校开设的公共计算机应用课程——VisualBasic6.0程序设计,针对刚刚入校的高校学生进行了一次项目教学的尝试[3]。

项目以对Office的Visual Basic for Applications(本文简称“VBA”)开发为技术基础,时间大约2学时,功能目标是要在Excel工作簿基础上实现一个数据筛选处理功能,根据已有的数据筛选形成一个数据集。

1 项目的用户需求分析

该项目教学的训练内容设定是为某部门信息管理员提供一个基于Excel的信息筛选导出的应用系统,可以帮助我们解决需要频繁重复填写、提交各种格式个人信息的问题。

教学训练过程中采用思维导图逐层展开的方式作为辅助,再结合实际环境下的演示操作,可以让训练内容更加有条理、便于学生理解。为了让学生课后也能回顾和跟练,本教学团队还对整个教学过程进行屏幕录像,把视频文件分享给了学生。

教学训练的开始是先提出平时工作、学习中常见的重复填表问题,请学生参与讨论,分别列举出可行的解决办法。然后根据学生们的方案逐个分析其优缺点、技术路线和所需要的技术储备,最后提出较小代价开发和便于用户使用的理念并引出VBA编程的方案。

本项目所设定的问题场景下,面对的用户就是基层信息管理员。用户拥有自己部门各成员的基本信息,这些数据集中、规范地保存在一个Excel文件里。因此,训练的开始就要新建一个Excel文件,按照预设场景中的格式添加虚拟的数据信息以便进一步处理。

2 规划解决方案

从原始数据生成最终的结果,需要对数据进行重新组织,那就必须建立一个原始数据和结果数据的对照联系,用于表示两种数据形式的关系。比较简单的一种处理方式,就是直接在当前Excel工作簿里新建2个工作表,其中一个用于保存最终的结果,另一个用于存放临时的对照表,用于设定要导出的数据项。根据其特点,这两个工作表可以分别命名为“结果表”“处理表”。

作为原始数据表和结果表的桥梁,处理表里面应该同时能够体现原始数据表和结果表的字段信息,并让用户能灵活地选择、配置。同时,原始数据表的字段数量应该是多于结果表的,那么,处理表里也无须直接列出结果表的字段名。因此,处理表的结构可以设置为图3所示的结构。

其中,第1行、第2行来自原始数据表,第1行主要用于标记列的编号,引用数据列的时候更加直观。第3行用于表示是否选中原始数据表的当前字段。

如果用户最终所需要的结果字段名和原始数据表的字段名不完全一致,只要内容一致,可以在结果表里面进一步人工调整修改。这样的设计可以减轻编程任务、简化处理表的结构,完成最终目标的效率反而会增加,代码的适应性也会更好。

需要注意的是,现在常用的Excel版本下,普通文档默认保存的扩展名为xlsx,但是针对编写了VBA宏代码的文档应保存为xlsm格式。这是Office出于对文档信息安全的设计,可以在一定程度上防止未知代码的恶意操作。

2.1本项目的目标

本项目的目标大体上可以分为技术学习和功能实现两个方面。

作为针对零基础学生的教学,技术学习应该针对项目功能所需要的技术点展开,在介绍完一个技术知识,应该尽可能快地把它应用于项目功能的实现。

由于技术知识的学习主要围绕项目功能实现所需要的范围进行,整个学习过程就有非常强的以目标驱动进行探索式学习的特点。

2.2从大目标出发规划小目标

基于软件开发的自顶向下、逐步求精原则[4],要把做的工作按功能和相互关系划分为一个个具体的小目标。小目标的划定不仅有利于分步驟实现对应的具体功能,还可以帮助学生在项目管理的视角下分析项目、开阔思路。

为了减少开发难度,可以先手工把原始数据表里的前两行复制到处理表对应的位置,做好一定的数据的准备。那么第一个目标就是根据处理表里第3行的值判断用户选中了哪些数据列(字段)。

目标二:假设上述功能已经实现,就要根据所选中的字段,从原始数据表里复制数据。如果把数据直接放在结果表里,还涉及存放顺序、空白列的问题,就会有些复杂。可以先把这些数据放在处理表第4行及以下的部分,可以避免问题的复杂度,还便于对照参考是否复制了正确的数据。

目标三:在数据已经正确存放到处理表对应字段下方的情况下,可以接着把数据再从处理表复制到结果表。

最后就可以在已经完成的工作基础上,改进、增添功能,让用户使用起来更加方便。

3 项目的实施

这部分的策略主要是围绕目标问题进行分析,通过网络搜索对应的关键词逐步学习、逐层深入。

在演示和功能实施的过程中,出于训练的需要,尽可能特意“产生”一些常见错误。通过这些小错误的发现、定位、分析、解决,呈现开发者“调试”代码的过程,可以让学生理解并掌握一定的程序调试能力。此外还要尽可能对代码编写注释,这个习惯在言传身教下对学生的影响也是非常直接的。

3.1目标一的实现——判断用户选中了哪些数据列

考虑到零基础的情况,这部分的功能实现还有必要再分为更细的步骤:先读取处理表第3行第1列单元格的数据并输出,然后判断它是否被选中,再逐个读取第3行所有的单元格数据并判断其选中状态。

通过搜索“ExcelVBA编程”“ExcelVBA读写单元格”、类似的关键词,根据结果页里的提示进行操作,很快就可以了解到对Excel展开VBA编程的方法、对某个工作表单元格数据的读取和写入的方法。读取到数据后,为了便于查看,还要知道如何查看得到的数据,继续搜索“ExcelVBA输出数据”即可了解到常用的Msgbox对话框输出功能。

获取单元格数据有多个方法,这里可以根据搜索结果集的情况,演示即可。

方法一:

Msgbox Range("A2").value '通过对话框输出读取到的单元格“A2”的内容

方法二:

MsgboxWorksheets(1).Cells(2, 3)'读取到从左到右,序号为1的工作表,第2行、第3列的单元格

VBA编程的基本语法遵从VisualBasic程序设计语言(以下简称VB语言)的规则,通过解释代码含义根据项目功能所需对VB语言进行简单梳理并列举相对简单的例子演示其基本功能和特点。可以简单介绍:变量、数据类型、赋值语句、注释、数据输出、if语句、for语句、函数及其基本应用。

从程序设计循环结构的特点结合读写单元格数据的两种方法,可以让学生体会到上述方法二比较适合接下来的编程应用。

3.1.1读取“处理表”的选中标记数据

可以先实现读取一个单元格的数据,同时输出进行观察,确保读取的数据和预期一致。

Sub test()

Msgbox Worksheets(2).Cells(3, 1)

End Sub

再连续读取多个单元格,为了让初学者更容易看明白,可以只考虑前5列的数据。这样简化问题的策略也是开发者常采用的方法,可以避免复杂问题带来的错误和思维混乱。

For i = 1 To 5

Msgbox Worksheets(2).Cells(3, i)

Next i

说明:根据VBA编程的特点,这部分代码应该放在“Subtest()”和“EndSub”之间,本文后续描述将不再特别说明。

3.1.2判断读到的数据是否符合“选中”的条件

根据实际情况,可以先设定假如读到的数值是1,就认为用户选定了这一列。先手工把第3行的第1列单元格的内容设置为1,然后编写代码:

MsgboxWorkSheets(3).Cells(3,1)=1

观察运行结果,如果显示结果为“true”即可判定这部分功能逻辑上成立,可以进一步完善代码功能。

再引入if语句讲解和演示条件判断的应用逻辑关系:

For i = 1 To 5 '先考虑前5列数据的判断

If Worksheets(2).Cells(3, i) = 1 Then

Msgbox"第" &3 & "行" i & "列被选中"

Endif

Next i

3.2 目标二的实现——从原始数据表里复制数据

这部分的目标是把用户选中的数据列(字段)复制到第4行开始的区域,可以先把原始数据表对应的字段名称也复制一遍,这样便于对照排错。

3.2.1复制部分数据

先假定对第3行、第2列的值进行判断,假如用户选中了此列,就应该把原始数据表里第2行、第2列的字段名(列名)复制到处理表的第4行、第2列。

If Worksheets(2).Cells(3,2) = 1 Then

Worksheets(2).Cells(4, 2) = Worksheets(1).Cells(2, 2) '把字段名称放到数据区开头的一行

Endif

那么对于前5列的数据连续判断和复制多个字段名就应该写成:

'这里要实现的是把第3行前5列的内容进行判断,根据是否为1决定是否复制数据表对应列的字段名。

For i = 1 To 5   'i代表列号,简单的名称方便描述和理解

If Worksheets(2).Cells(3,i) = 1 Then

Worksheets(2).Cells(4, 2) = Worksheets(1).Cells(2, 2) '把字段名称放到处理表

Endif

Next i

接下来就可以把对应字段的数据也复制到“处理表”。同样,为了简化问题,可以假定只复制5行数据。

'仅复制前5行(包括字段名)、5列

For j= 1 To 5 'j代表行号

For i = 1 To 5   'i代表列号

If Worksheets(2).Cells(3,i) = 1 Then

Worksheets(2).Cells(j+3, 2) = Worksheets(1).Cells(j+1,i)

Endif

Next i

Nextj

3.2.2复制所有的数据到处理表

为了更加便于自动、准確处理数据,原始数据表里的数据区域行数、列数通过代码进行判断和处理更好。

处理的思路是设定一个规范的“数据表”:要求“数据表”必须满足所有行、列的内容都应该是连续的(无空白的行或者空白列分隔)。尤其是对第一行、第一列,可以规定其在有效的数据区域内,不允许设置为空白值,用于确保数据区域的连续和代码判断数据区域的方便性。那么,即使后期数据表的数据区域发生了变化,在执行宏代码的时候也可以快速判断行数和列数,不需要再次手动修改代码。

作为一个特定用途的项目,这样的设定完全可以作为一个数据表必须满足的规范。

那么我们对数据处理的逻辑就是:从左到右顺序扫描第一行各个单元格的值,一旦发现某个单元格内容为空,表明数据区域的列已经结束。这时可以记录到当前列为止的列数,作为后续评判数据区的依据。从上到下顺序扫描第一列一旦发现某个单元格内容为空,表明数据行已经结束,可以记录到当前列为止的列数,作为后续评判数据区的依据。

到目前为止,由于只学习了一个循环语句for…next语句,这部分代码就可以写为:

For i = 1 To 16384  '16384这是一个Excel工作表默认的列数最大值,i代表列数

If Worksheets(1).Cells(2, i) = "" Then '假定数据列是连续的,字段行空白,数据列结束

lie = i - 1 '工作表1“信息表”总共有lie个列,便于后续处理

Exit For

End If

Next i

当然,这部分功能更加适合的是do…loop语句,但是作为初学者,for语句更加友好、便于理解。后续可以安排学生自己学习do…loop结构的循环语句并把这里的代码改进、完善。

把这部分功能进行综合,将得到以下程序代码:

Sub 信息提取到结果表()

'假定处理表里面的数据都为空白

'获取原始数据表(工作表1)里面的列数

For i = 1 To 16384

If Worksheets(1).Cells(2, i) = "" Then '假定数据列连续,第一行某字段为空,数据列结束

lie = i - 1 '工作表1“信息表”总共有lie个列,便于后续处理;lie的值其他代码公用

Exit For

End If

Next i

'把“信息表”的前两行的数据移到“处理表”序号用于定位标记

For i = 1 To lie

Worksheets(2).Cells(1, i) = Worksheets(1).Cells(1, i)'复制数据表第1行

Worksheets(2).Cells(2, i) = Worksheets(1).Cells(2, i)'复制数据表第2行

If Worksheets(2).Cells(3, i) = 1 Then

For j = 2 To 1048576    'Excel工作表默认最多可以有1048576行

If Worksheets(1).Cells(j, 1) = "" Then

'假定各行数据连续的,空白序号列,数据结束

hang = j - 1    '存放数据区域的总行数,后续代码可以使用此值

Exit For    '不再继续扫描更多的行

Else

Worksheets(2).Cells(j + 2, i) = Worksheets(1).Cells(j, i)

'复制数据到处理表

End If

Next j

End If

Next i

End Sub

程序在第一次执行的时候,因为还没有在处理表的第3行选中任何列,代码不会复制数据区域的内容,只是把原始数据表里面的前两行复制到了处理表里。接下来,在用户选中特定列后,再次执行这段代码,即可复制相关的数据。

3.3目标三的实现——把数据放入结果表

实现的方法也有很多,比较简单的是在上述代码里添加复制数据到结果表的代码即可。代码如下:

Worksheets(3).Cells(j - 1, i) = Worksheets(1).Cells(j, i)  '复制原始数据表的数据到结果表

所要注意的是,未选中的列是空值,而结果表里的数据应该是连续的列,可以通过代码删除空的列。

For i = lie To 1 Step -1   '从数据区域最右侧的一列开始判断

If Worksheets(3).Cells(1, i).Value = "" Then '第1行为空,表示当前列为空

Worksheets(3).Columns(i).Delete  '删除列

End If

Next i

对于初学者而言,这里是一个难点,需要解释为什么循环变量从右到左逐列判断、处理。因为涉及删除一列的时候,循环变量从右向左追溯对代码执行没有影响,而从左往右逐列检查,空列删除后循环变量的变化情况稍微有些复杂,可以以扩展任务的方式布置给学生去思考、观察和实现。

4 功能实用性扩展

经过上述的演示和讲解,学生已经可以理解Excel的VBA编程思路和特点,结合网络信息检索完全可以独立获取对应功能的核心代碼并应用到项目开发中。

完成了项目预先设定的基本功能之后,还应该从用户的实际使用环境和需求出发进行功能改进和升级。这一阶段主要是多考虑用户的实际使用环境,以用户使用更加便捷、高效为准。

4.1考虑多个数据表的场景

考虑到用户的实际工作环境中的原始数据表可能是以多个工作表的形式存放,以上代码和功能可以在这方面适当升级改进。解决方案的设计原则是便于用户操作,并且尽可能小幅度调整先前的方案。

为此,可以在处理表的上方新增2行,用于存放当前所有的工作表、让用户确定选择哪一个工作表进行筛选导出。其中,第1行通过VBA代码自动获取并填入当前工作簿的所有工作表名称,用户在第2行输入选中标记,通过代码判断当前处理过程选中的是哪一个工作表。同时,要规定一次只允许选择一个工作表进行字段数的提取。相应地,先前处理表中的相关行功能也要做适当调整,向下推动2行。

获取当前工作簿里所有工作表的关键代码如下:

for each gzb in Worksheets

k=k+1

cells(1,k)=gzb.name '获取当前工作簿中所有的工作表名称放入第1行

next

因为工作表的增多也带来顺序序号的问题,可以把结果表放在所有工作表的最前面,把处理表作为第2个工作表,相应地需要把上述代码中涉及工作表序号的部分修改调整。

4.2数据结果存入独立的文档

Excel的VBA编程功能强大、灵活,可以实现打开指定的word文档或Excel工作簿并存入数据,也可以直接新建word文档或Excel工作簿并存入指定的数据。完全可以根据需要在指定位置输出一个或多个相关文档并存入数据,甚至可以设置特定数据的格式、样式。

4.3结合Word邮件合并功能

既然已经可以根据需要导出所需的数据,那么, 以导出数据作为数据源,结合Word的“邮件合并”功能,也可以快速生成多个Word文档或者直接打印多份指定格式的文稿[5]。

4.4添加快捷按钮和快捷键

Excel的标签栏、工具按钮可以根据需要定制,自己编写的宏代码也可以以“按钮”的方式放在“工具选项卡”或者“快速访问工具栏”,可以实现“一键运行”,用起来更加方便、快捷。

5 总结

从功能方面来看:

本项目代码工作量不大、灵活性高,开发周期短。项目实施过程中充分考虑了用户的实际需求和使用便捷性,能够解决信息联络员频繁进行数据收发的一般需求。对于更特殊的需求,也可以根据具体情况对相关功能进行调整。

从教学模式上看:

这样一个零基础就可以听得懂、做得到的项目,作为项目教学的案例,既具有一定难度,又有较好的灵活性和可扩充性。

项目实施过程中通过对总目标的层层分解、逐步细化,以零基础学生的知识背景逐渐展开知识点介绍和功能实施,逻辑清晰、目标明确。不仅可以消除学生对程序设计的畏惧感和神秘感、了解项目开发的全过程、体验开发者思考方式,也可以独立、快速完成一个实用性较高的作品。此外,项目的改进方案多样,难度适中,比较有利于学生发挥想象力、进行拓展训练。

综上,本项目对信息学科相关老师、对应用编程感兴趣的学生而言都是一个不错的案例。

参考文献:

[1] 沈光,洪一明.新工科背景下高校实验室促进创新人才培养的治理策略[J].实验室研究与探索,2020,39(8):263-266.

[2] 王迷迷,郑英,张立珍.“互联网+”背景下创客项目式教学研究[J].信息系统工程,2020(7):155-156.

[3] 王艳芬.基于项目式教学的安卓开发公选课改革探索[J].教育教学论坛,2020(33):171-173.

[4] 倪飞舟.Visual Basic程序设计教程[M].北京:中国水利水电出版社,2010:276.

[5] 何振娟,王玮,刘海,等.Excel中VBA及Word邮件合并功能在批量处理报表中的应用[J].电脑知识与技术,2021,17(6):212-214.

【通联编辑:唐一东】

收稿日期:2021-07-15

基金项目:安徽医科大学2017年校级质量工程项目教学研究项目(2017076);EAST AST长脉冲数据的实时发布系统研究(2012SQRL265);安徽省高校质量工程项目(2017jyxm1322)

作者简介:陈浩强(1979—),男,安徽界首人,講师,硕士,主要研究方向为嵌入式系统设计。