故事背景
工作日的某一天,技术宅男小墨鱼先生正在认真的摸鱼。突然收到WL(Wife Leader)的指示,需要在Excel里面实现一个功能: <math xmlns="http://www.w3.org/1998/Math/MathML"> 读取指定 E x c e l 的 S h e e t 页内容,然后复制到当前 E x c e l 的指定位置。 \color{red}{读取指定Excel的Sheet页内容,然后复制到当前Excel的指定位置。} </math>读取指定Excel的Sheet页内容,然后复制到当前Excel的指定位置。
一开始,小墨鱼先生打算使用Java语言来完成,那对专攻Java的小墨鱼先生来说简直就是小菜一碟,但是WL又加上了一个限定条件------必须使用VBA来完成。小墨鱼先生懵了一下,多么古老的技术,记得上一次用它还是在上一次(刚开始实习的时候),但是已经答应了,身为技术宅男,必须完成任务。
解决经过
首先,小墨鱼先生先打开了官网,看一下大致的语法是什么,开发语言都大差不差,只要了解了基础语法,就能按照自己的想法去实现功能(要不说机器是最好沟通的朋友呢)。
下面放上VBA-Excel部分的语法的链接: VBA-Excel部分。
看完了基础语法,那么小墨鱼先生就开始拆分这个需求。
第一步,需要在当前Excel打开另一个指定的Excel,这一步还是比较好实现的,用一个打开文件函数就可以轻松做到:
vb
Set source_work_book = Workbooks.Open("指定文件目录")
接下来,就是读取指定Sheet页的内容,并且复制到对应的位置:
vb
Set source_work_sheet = source_work_book.Worksheets("Sheet页的索引或名称")
Set source_range = source_work_sheet.Range("读取范围")
source_range.Copy "指定位置"
最后也别忘了关闭已经打开的文件:
vb
source_work_book.Close
OK! 初步版本就已经完成啦,于是小墨鱼先生把初稿交到了WL的手里,WL一运行,还是比较满意的,但是又提出了新的需求,小墨鱼先生当前欣然接受(小墨鱼先生ps:咋这么多事),WL的新需求是需要把最新的内容放到上一次粘贴的位置上,需要清空上一次的内容,小墨鱼先生一听,多大点事,于是又赶紧奋笔疾书,洋洋洒洒的写下了一段代码:
vb
Sheets("选中目标sheet页").Select
ActiveSheet.UsedRange.EntireRow.Offset("写入的单元格偏移行数").Delete
于是小墨鱼先生把第二版发送给了WL,WL看了,又有了新的要求:目前读取的文件都是写死的,想要把功能变得灵活一点,能根据名字读取文件的第一个Sheet页,这样其他不懂VBA的同事也能够快速使用。 小墨鱼先生也很快就满足了这个需求,毕竟是WL,但是这次小墨鱼先生学聪明了,他把一些固定的值,都变成了变量,这样下次不管WL提出什么变动,都能很快的调整。新调整后的代码如下:
vb
Sub data_copy()
' --------------------定义变量开始-------------------
Dim source_work_book As Workbook
Dim target_work_book As Workbook
Dim source_work_sheet As Worksheet
Dim target_work_sheet As Worksheet
Dim source_range As Range
Dim target_range As Range
' --------------------定义变量结束-------------------
' --------------------用户自定义初始变量赋值开始-------------------
' 源sheet页索引
source_sheet_index = 1
' 目标sheet页索引
target_sheet_index = 1
' 文件输入位置坐标
input_file_index = "F1"
' 基础文件路径
base_url = "D:/"
' 读取的单元格范围
source_range_index = "A1:AB100000"
' 写入的的起始单元格
target_range_index = "A1"
' 写入的单元格偏移行数
target_range_offset = 2
' --------------------用户自定义初始变量赋值结束-------------------
' 选中目标sheet页
Sheets(target_sheet_index).Select
' 清除历史数据
ActiveSheet.UsedRange.EntireRow.Offset(target_range_offset).Delete
' 读取文件名
file_name = Range(input_file_index).Value
' 拼接文件全路径
full_file_name = base_url + file_name
' 设置源工作簿和目标工作簿
Set source_work_book = Workbooks.Open(full_file_name)
Set target_work_book = ThisWorkbook
' 设置源和目标sheet页
Set source_work_sheet = source_work_book.Worksheets(source_sheet_index)
Set target_work_sheet = target_work_book.Worksheets(target_sheet_index)
' 设置源和目标单元格范围
Set source_range = source_work_sheet.Range(source_range_index)
Set target_range = target_work_sheet.Range(target_range_index).Offset(target_range_offset, 0)
' 复制和粘贴数据
source_range.Copy target_range
' 关闭文件
source_work_book.Close
' --------------------清除对象引用开始-------------------
Set source_range = Nothing
Set target_range = Nothing
Set source_work_sheet = Nothing
Set target_work_sheet = Nothing
Set source_work_book = Nothing
Set target_work_book = Nothing
' --------------------清除对象引用结束-------------------
End Sub
故事结局
这次WL看完以后,非常满意,要奖励小墨鱼先生,当然具体的奖励我们也不得而知了。
未完待续。。。
注意事项
使用Microsoft Office的同学可以直接Alt+F11进行VBA(宏)的开发,但是使用WPS的同学需要安装一个插件。安装地址放在了代码仓库中,也可以加入QQ群获取。QQ群:936062125
代码仓库地址:https://gitee.com/maochd/wlstory/tree/master/vba1/