「原创」Excel批量生成表单调试与完善

翻墙后,即可评论博文

先放出根据调试结果,修改的代码,由于公司的技术保密限制,在公司调试好的代码没办法直接拷贝。另外,上一篇博文中的代码块,遇到中文会显示乱码,由于我使用的是Linux系统,使用的编码跟Windows的是不一样的,再加上自己懒,只把重要的代码作注释: [VBA_Example.rar](/data/VBA_Example.rar)

开篇先吐吐苦水。由于事先知道公司的电脑有数据使用限制,所以就没有带U盘和数据线,而是把做好的Excel表格发到同事的邮箱,通过内部邮件下载,公司的电脑就有了我作好的Excel。然而,问题在于我测试的时候,并不知道Excel表格的代码其实是单独存放在个人电脑里的某个路径路径下的,拷贝表格是没有用的,要导出代码才行。导致,我在公司里做测试的时候,所有的代码都得重新码一遍,那个痛苦啊,更悲剧的是,我忘了代码不能用当前的工作簿保存,而要用个人宏工作簿,导致我关闭表格的时候,代码又没了。于是又码了一遍。码完之后,才开始正式测试代码。

现在,谈一谈测试过程中遇到的Bug及完善方法:

首先遇到的问题是分表重名的冲突,同事在制作表格的时候,不小心弄了两个一模一样的设备型号,导致了该问题的出现,于是就要修改表格了。

改完表格之后,遇到的Bug就是总表链接到分表的超链接失效,先后检查了表格的函数hyperlink是否有误,VBA重命名是否有错。最终修改型号列的一格数据,把型号里的"-"号去掉(设备的型号里带“-”是很常见的),再链接一次,发现成功了,问题找到了:"在建立超链接的过程中,‘-’是作为运算符使用的,不能用于超链接。" 那么,如何解决呢,方法是为每一行表格建立序号索引,序号索引具有唯一性,不会重名(当然,这就没法发现型号重复的问题了),序号不涉及运算符号,不会使超链接失效。

接下来遇到的问题是总表剩余项无法更新,为了说明问题的原因,先把代码搬出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Sub 更新总表剩余数量项状态()
’更新剩余数量单元格

'重要常量

Const sht_Cell_Beg = 2 '单元列中数据块的起点行号
Const sht_Cell_End = 6 '单元列中数据块的终点行号
Const sht_Cell_Rest = 4 '总表中剩余数量项所在列数
Const sub_sht_Cell_Rest_Row = 8 '分表中剩余数量实时更新状态单元格所在列数
Const sub_sht_Cell_Rest_Col = 2 '分表中剩余数量实时更新状态单元格所在行数
Const sht_Main_ID = 1 '总表顺序ID

For i = sht_Cell_Beg To sht_Cell_End 'i遍历所有整个数据块,同时也是循环变量
Cells(i,sht_Cell_Rest).Select '选中单元格剩余列的第i行单元格
ActiveCell.FormulaR1C1 = Sheets(i).Cells(sub_sht_Cell_Rest_Col,sub_sht_Cell_Rest_Row)
Next
End Sub

再附上,建分表的节选代码:

1
2
3
For i = sht_Cell_Beg to sht_Cell_End
Sheets.Add After:=Sheets(Sheets.Count)
Sheets(Sheets.Count).Name = Sheets(sht_Main_ID).Cells(i,sht_Data_Rel_Index)

在编程的时候,通常是建议重要常量定义为一个常变量名,这样以后这个程序就可以作为模板,只要情况差不多,那就只要改参数,基本上就能达到效果了,不用一个一个的去找变量修改,那样很累。

问题的关键在于总表顺序ID上,我在进行实际运用之前,所有做的测试基于总表顺序ID=1的情况下进行的。

那么,在这种情况,仍然测试通过的原因,是什么呢?原因就是分表顺序ID与表格数据列是同步的。即当我的表格从行号2时就有数据时,在总表顺序ID=1的情况下,建立的下一个表格即分表,其顺序ID也是2。

但是,当总表ID=2时,情况就发生了变化,这也是我在公司进行实际运用的情景,于是就出现了BUG,很明显,前一种条件下,程序运行逻辑成立的原因是总表顺序号ID=1,导致分表ID恰巧与表格数据块的起点行号同步。对这个原因取非逻辑,就是出现Bug的原因,即总顺序表ID不等于1,导致分表ID与数据块的序列不同步。

要如何解决这种问题呢?既然不同步,也就是说两者存在差值,两者有差值的原因在于总表顺序ID,那么解决方案就是数据块指向变量i与总顺序表ID作运算,使得Sheets()函数索引到正确的分表。

假设总表顺序ID=2,数据块由行号2开始,即sht_Cell_Beg=2
那么在建立分表之后,头一个分表的顺序ID=3
"Sheets(i).Cells(sub_sht_Cell_Rest_Col,sub_sht_Cell_Rest_Row)"这条语句是要索引分表中某一单元格的数据,但是i=2的情况下,索引到的是总表的表格,这就发生了矛盾了,我们要做的事情是将分表的数据传到总表,并不是要总表数据传到总表。

这个时候,只有ID=3的表格才有我们所需要的数据。也就是说Sheets(N)中的N不等于i;
如果N=3,又由于有 i = 2 , sht_Main_ID=2,
那么,求 N = i + sht_Main_ID + x ;
得 x = 3 - 2 -2 = -1
所以正确的索引方式是 Sheets(i + sht_Main_ID -1)

在建分表的程序段中有常变量sht_Data_Rel_Index,这个变量用于指明我们在表格中所建立的索引顺序列,通过索引号给分表命名,就能有效地保证超链接的使用。