乐于分享
好东西不私藏

Excel VBA 编程基础 -- 文件处理(六)

Excel VBA 编程基础 -- 文件处理(六)
前面我们讨论了如何写入文件,今天讨论如何读取文件。
与写入文件 Print # 和 Write # 相对应的,是 Input # 和 Line Input #。
Input #
Input # 从顺序文件中读取数据,并赋给变量。其一般格式是:
Input #filenumbervarlist
其中,filenumber 是整数常量或整型变量,表示要读取文件的文件号,varlist 则是用于接受数据的以逗号分隔的变量列表。
例1. Input # 用法示例
下面我们用 Input # 语句来读取 data.txt 文件内容:
图1 data.txt
这个文件收集了一些人物的基本信息,包括姓名、出生日期、去世日期、创立公司年份,公司名称,目前是否 CEO。可以看出,数据包含了字符串类型、日期类型、整型、Boolean 类型。其中,第一行是标题行。
不难看出,这个文件就是一个 CSV 文件。既可以通过 Write # 语句生成,也可以手工编辑而成。下面是读取该文件的代码:
先要定义一个 UDT:
TypeBigPersonNameAsStringBirthdateAsDateDeathdateAsVariantYearOfFounderAsIntegerCopmanyAsStringCEOAsBooleanEndType
在自定义类型 BigPerson 的基础上,读取 data.txt 文件的代码如下:
图2 读取 data.txt 的代码
这段代码使用了两个还没有讲过的工具:
  • Line Input #:Input # 是一项一项地读,Line Input # 则是一行一行地读。
  • EOF(filenumber):判断当前的文件号是否已经到达文件尾。
注:VBA 中与文件操作有关的语句都要求文件号作为参数,但文件号前面的井号(#)比较混乱:
  • 有的 # 号可选,如 Close [#]filenumber 语句。
  • 有的必须有 # 号,如 Input #filenumber 语句。
  • 有的则不能带 # 号,如 EOF(filenumber)。
回到我们的例子。文件打开之后,首先用 Line Input # 语句读取标题行,然后进入一个 For 循环,逐行逐项读取文件内容。
在图2 中的 Input # 语句中,我们把一行中的所有项目都写在一行 Input # 语句上,实际上不需要这样,Input # 语句可以分为多行,只要所有 Input # 语句中的变量加起来对应到文件中的一行即可,如下图:
图3 Input # 分行书写
注:由图可见,Close 语句中的文件号没有前缀 # 号。
在我们定义的 UDT BigPerson 中,考虑到 Deathdate 数据有 Null,所以 Deathdate 分量的类型要定义为 Variant 以容纳 Null 值。
注:Input # 语句中各个变量的类型要对应于文件中相应项目的类型。如果变量是数值类型但数据却不是数值类型,则变量将被赋以 0 值。当然,如果事先不知道数据类型,为了保险,可以将各个变量都声明为 Variant 类型。
Line Input #
如果说 Input # 语句是一项一项地读,那么 Line Input # 则是一行一行地读。其一般格式是:
Line Input #filenumbervarname
其中,filenumber 是要读取文件的文件号,varname 则是用来接受一行数据的变量,其类型是 Variant 或 String。
例1 已经演示了 Line Input # 的用法。下面我们用 Line Input # 语句来重写例1。
例2. 用 Line Input # 重写例1。
图4 用 Line Input # 重写例1
仔细比较图4 和图3,可以看出,图4 唯一的变化在于用 Line Input # 代替了 Input #,并且多出了一个 ParsingData 过程。因为 Line Input # 是将整行一次性读入,就需要我们自己把一行的数据项解析出来。ParsingData 过程就是用来解析数据项的。其代码如下:
图5 ParsingData 过程
可以看出,VBA 的 CXxx 类型转换函数无法识别 # 符号,如 CDate("#2026/6/18#") 将引发"类型不匹配"错误。必须先将 "#2026/6/18#" 变换为 "2026-6-18",然后再使用 CDate 将其转换为 Date 类型。CBool() 函数也是如此,需要先将 "#TRUE#" 中的 # 符号去掉,才能转换为 Boolean 类型。
综上所述,对于 Write # 输出的 CSV 格式文件,读入时要使用 Input # 逐项读入。对于 Print # 输出的文件,因为项与项之间没有分隔符,只能使用 Line Input # 逐行读入。
相关阅读
Excel VBA 编程基础 -- 文件处理(一)
Excel VBA 编程基础 -- 文件处理(二)
Excel VBA 编程基础 -- 文件处理(三)
Excel VBA 编程基础 -- 文件处理(四)
Excel VBA 编程基础 -- 文件处理(五)