拙作《利用Excel 97打印工资条》在《电脑报》2000年2期刊出后,由于本人考虑欠周及排版上出现的细微差错,致使多数读者在运行该文所提供的源代码时,出现了致命的错误,在此深表抱歉。同时,本人收到了本版责编转发来的多位读者的E-mail,在E-mail中,读者们除了指出原文中的漏洞外,有些读者还对源代码提出了富有建设性的改进意见,在此一并作谢。
应广大读者要求,就前面诸问题作一扼要回答。
问1:如何编译及运行原文中提供的源代码?
答:我们知道该源代码是用Excel 97自带的宏语言VBA编写的。虽然对于宏语言VBA,《电脑报》1999年第39期的《掀起Word “宏”盖头》及第50期的《小试“宏”刀》等都有相关的介绍,但对于初学者,要完全弄懂它还要花些时间。在这里,仅对编译及运行原文中提供的源代码的过程作一简单介绍。
第一步:打开VBA编辑器。单击“工具”/“宏”/“Visual Basic编辑器”或按快捷键Alt+F11,把源代码完整地输入到右边的代码窗口中即可(见

1);
第二步:在工具栏上添加一按钮。单击“视图”/“工具栏”/“自定义”,当出现

2画面时,把右边的“自定义按钮”拖到工具栏的适当位置放开,接着右击该按钮,指定刚才所建的宏,同时可以更改按钮图标等;
第三步:调试运行。确认工作簿的“sheet1”为当前工作表,现在就大功告成,可以单击刚才的新按钮看看。
问2:把源代码完整输入后,编译为何没法通过?
答:编译没法通过主要是排版上出现一些错误的缘故,因版面关系,此处不再一一列出,请读者对照后面所附正确源代码修正。
问3:纠正上述错误后,运行结果还达不到要求,源代码是否有有待改进的地方?
答:诚如有些读者指出的“该文在利用‘If aa(1)=aa(2)Then Exit Do’检测aa(1)=aa(2)存在一些不足”那样,该语句在源代码中有着举足轻重的地位,它是退出循环、结束运行的依据。本人恰恰在此考虑欠周,致使运行结果达不到要求,其改进的方法有多种,如:
把Set aa(2)=ActiveSheet.Range("B"&List_str)改成:
Set aa(2)=ActiveSheet.Range("C"&List_str)等。
当然,对于VBA语言掌握熟练的读者,还可以利用其丰富的函数、强大的功能,把源代码改得更简练、更具有通用性。若运行改进程序后仍有问题的读者请与我联系,我的E-mail地址是:jiaming_wu@163.net。
编者按:《利用Excel 97打印工资条》一文刊出后,收到不少读者对该文的肯定,除收到一些对该文源代码的改进意见外,还收到不少对此问题的非VBA解决方案,由于版面有限,不能一一登出,请大家见谅!在此,编者向这些热心读者表示衷心感谢。
改进后的程序清单:
Option Base1
Dim aa(13)As Range,xm As Range
'xm准备存放条头的项目
Dim List_1 As Integer
'源表格中的行定位变量
Dim List_2 As Integer
'目标表格中的行定位变量
Dim List_str As String
'源表格中的行定位变量,字符型
Sub mymain()
List_1=2 '从源表格的第二行开始
List_2=2
Do
List_str=RTrimS(LTrimS(StrS(List_1)))
Set aa(1)=ActiveSheet.Range("A"&List_str)
'读编号
Set aa(2)=ActiveSheet.Range("C"&List_str)
'读姓名
If aa(1)=aa(2) Then Exit Do
'编号、姓名均为空白时不再读
transform List_2
List_1=list_1+1
List_2=List_2+2
Loop
End Sub
Sub transform(num As Integer)
Dim n As Integer
Dim v As String '源表格的列定位变量
Dim nl As Variant '目标表格的列定位变量
Dim w As Variant '目标表格的行定位变量
n1=num
w=n1+1
For n=1 To 11 Step 1
'准备传送工资条的条头及工资数
With Worksheets("sheet2")
v=Chr(64+n) '源表格的数据从A列开始
Set xm=ActiveSheet.Range(v&"1")
·Range(Chr(n+64)&n1)=xm
'传送工资条的条头
Set aa(n+2)=ActiveSheet.Range(v&List_str)
·Range(Chr(n+64)&w)=aa(n+2)
'传送工资条的工资数
End With
Next
End Sub