3.5.4-代码解析:S0201_文件处理¶
S0201_文件处理(longName, shortName),这里的longName, shortName称为参数,在本书之前介绍的Sub过程括号中无任何信息。
当一个需求比较复杂时,我们会将其分隔成几个Sub过程去完成,某一个过程对应的功能可能被重复调用,只是每次使用的参数不同,这样我们就需要带参数的Sub过程。如本示例中,需要将不同员工的数据读入数据缓存工作表。对于每个员工的操作基本是一样的,每名员工信息占据一列,依次写入。
基本逻辑过程如下:
1)打开员工的数据工作簿
2)获取当前数据缓存工作表最大列maxCol
3)将新员工信息写入maxCol+1列
代码如下
1 Sub S0201_文件处理(longName, shortName)
2 Set wb = Workbooks.Open(longName) '打开工作簿
3 Set sht = wb.Worksheets(1)
4 '获取员工姓名
5 employeeName = Split(shortName, "-")(0)
6 Debug.Print (employeeName)
7 '获取输入Excel最大行
8 maxRow = sht.Cells(Rows.Count, "B").End(xlUp).Row
9
10 ' 拟输入列列号
11 Set shtData = ThisWorkbook.Worksheets("数据缓存")
12 a1Value = shtData.Range("A1")
13 If a1Value = "" Then
14 inputCol = 1
15 Else
16 inputCol=shtData.Cells(1,Columns.Count).End(xlToLeft).Column + 1
17 End If
18
19 shtData.Cells(1, inputCol) = employeeName
20
21 ' 复制每个员工的数据至目标工作表
22 sht.Range("B2:B" & maxRow).Copy Destination:=shtData.Cells(2, inputCol)
23
24 wb.Close
25 End Sub
代码中文解析
1 Sub S0201_文件处理(longName, shortName)
2 打开文件地址为longName的Excel工作簿,用变量wb表示
3 定义工作表sht,表示wb工作簿的第1个工作表,该工作簿只含有1个工作表
4 '获取员工姓名
5 表示文件名的字符串,使用Split函数进行分割,获取员工姓名
6 输出显示员工姓名
7 '获取输入Excel最大行
8 sht工作表B列最大行
9
10 ' 拟输入列列号
11 定义数据缓存工作表为shtData
12 获取shtData工作表A1单元格内容a1Value
13 判断开始:a1Value是否为空
14 如果是,则inputCol = 1
15 如果不是
16 inputCol为shtData工作表第1列最大行+1
17 循环结束
18
19 shtData单元格(行号=1,列号=inputCol)赋值员工姓名employeeName
20
21 ' 复制每个员工的数据至目标工作表
22 将员工工作表B2至B最大行区域复制,在单元格(行号=2,列号=inputCol)处粘贴
23
24 关闭工作簿wb
25 End Sub
其实就是将员工生产的小蛋糕重量信息分别复制到数据缓存工作表,因为不知道员工有多少信息(即多少行),以及不知道数据缓存工作表已有多少信息。所以需要找到每名员工有多少行信息,以及当前数据缓存表中当前写到哪一列。
关键代码解读
1)第2行:Set wb = Workbooks.Open(longName),longName为对应Excel文件的绝对地址。记得使用完毕后,务必关闭该Excel文件,wb.Close。之前的示例中所有的操作都是在代码所在Excel工作簿,使用ThisWorkbook表征就可以,当拟操作的Excel不是当前代码所在Excel文件,需要先获取拟操作的Excel对象,也就是这里的wb。
2)第3行:Set sht = wb.Worksheets(1),获取wb工作簿的第1个Excel工作表。在之前的示例中,我们通过工作表名称获取工作表信息,Worksheets(“工作表名”),同样可以通过位置获取。该方法请慎用,当Excel工作簿中包括多个工作表时,若人工移动Excel工作表,同样的位置信息表示的会是不同的工作表,所以建议在工作簿中只含有一个工作表时使用该方法。
3)第5行:employeeName = Split(shortName, "-")(0),字符串分割函数,当文件名为“员工丙-小蛋糕重量.xlsx”时,以-为分隔符,生成一个数组,如图3-22所示,获取数组第一个元素(从0开始计数)为员工姓名,可以从图3-23有直观的感受。可以看到数据源的标准化是很重要的,如果员工反馈的Excel文件是任意命名的,那么就不能获取其姓名,标准化的数据源大大减少代码体量。
数组是什么?可以看做一个容器,可以将数据放入进去暂存,当程序运行结束后,自动消失,但对它的读写速度远远高于对于Excel文件的读写。这里先只介绍一维数组,类似于Excel中的一行,每个单元格可以分别写入信息,如图3-24所示。通过关键字Array定义一个新数组,数组有如下特征:
从本地窗口中也可以看出数组是从0开始计数的
数组中每个元素的数据类型可以不同
Ubound获取数组最大序列号
Lbound获取数组最小序列号
Debug.Print(a),在程序运行过,输出变a到立即窗口中。但不能直接输出数组,可以输出其每一个元素。数组元素获取,arr(i),i表示在数组的位置
4)第22行: sht.Range("B2:B" & maxRow).Copy Destination:=shtData.Cells(2, inputCol),复制工作表区域,Copy前为拟复制区域,Destination:=后为复制到的新位置第一个单元格。


