excel学习库

excel表格_excel函数公式大全_execl从入门到精通

Excel VBA「案例更正」批量自动生成应收款对账单

本文于2023年9月22日首发于本人同名其他平台。

内容提要

  • 代码更正与优化

大家好,我是冷水泡茶,9月4日我们分享过一个案例【Excel VBA 批量自动生成应收款对账单/应付通知单】,很“不幸地”,代码中有重大错漏

于是,我打开原文件,把一个法人的记录删掉一些,保留2行,

运行,结果让我头皮一阵发麻,没有数据啊,而且法人的名称也不对:

赶紧检查代码,发现问题出在这里:

If语句少了一个Else,只处理了需要增加行的情况,如果不需要增加行,则没有处理,没有把数据写入工作表。

问题找出来了,但具体怎么改呢?

我们可以增加一个Else分支,把不需要增加行的操作处理一下,可以直接复制上面的代码,把插入行的代码删掉,应该就可以了。

但转念一想,我们用IF判断extraLines的值,是为了插入行,那么向工作表写入数据的操作可以在IF判断完成后再执行。比如,我们可以改成下面的形式,只是把原来代码的顺序调一调:

With wsTarget    If extraLines > 0 Then        .Rows(tbFirstLine + 1 & ":" & tbFirstLine + extraLines).Insert Shift:=xlDown        .Rows(tbFirstLine2 + 1 + extraLines & ":" & tbFirstLine2 + extraLines + extraLines).Insert Shift:=xlDown    End If    .Range("B3") = Key    .Range("A5") = Me.CmbCurrentMonth    .Range("F5") = Me.CmbDeadLine    .Cells(tbFirstLine, 2).Resize(UBound(arr1), UBound(arr1, 2)) = arr1    .Cells(tbFirstLine2 + extraLines, 2).Resize(UBound(arr2), UBound(arr2, 2)) = arr2    For j = 1 To dic(Key)        .Cells(tbFirstLine + j - 1, 1) = j        .Cells(tbFirstLine2 + extraLines + j - 1, 1) = j    Next    memoLine = tbLastLine2 + 4 + IIf(extraLines > 0, extraLines * 2, 0)    .Cells(memoLine, 1) = "请各位法人于" & Me.CmbCurrentMonth & "缴完应付额"    End IfEnd With

即,如果需要插入行,则先插入行后再写入数据。如果不需要插入行,那么就跳过插入行的代码,直接写入数据。

但是问题又来了,在下面写入数据的代码中,计算定位数据行时,加上了extraLines, 原来是应用于需要增加行的情况的,对于不需要增行的,应该把这个变量去掉。难道我们需要再来一次判断?先别急着改,我们再来分析分析:

对于不需要插入行的情况有两种,一种正好是3行,extraLines=0,另一种是1行或2行,extraLines的值为负数。

如果extraLines正好等于0,那么代码运行结果应该是正确的,加上0还等于原来的数。如果是负数就不行了。

那么,如果extraLines为负数时,我们到底应该怎么办呢?

别看我啰里啰嗦了一大堆,其实这里的解决方法很简单,如果extraLines不大于0,我们就把它统统改为0。这里有两个地方可以处理它:

1、在计算extraLines的时候

 extraLines = UBound(arr1) - (tbLastLine - tbFirstLine + 1)

我们可以用IIF函数来处理它,可以在“=”号的右边处理,但代码太长,我们可以在上一行代码下面加一行代码:

extraLines = IIf(extraLines > 0, extraLines, 0)

2、在判断extraLines是否大于0的时候,我们加一句Else:extraLines = 0

If extraLines > 0 Then    .Rows(tbFirstLine + 1 & ":" & tbFirstLine + extraLines).Insert Shift:=xlDown    .Rows(tbFirstLine2 + 1 + extraLines & ":" & tbFirstLine2 + extraLines + extraLines).Insert Shift:=xlDownElse    extraLines = 0End If

这样,接下来把数据从数组中写入工作表就没有问题了。

不过,问题并没有完全按上面的思路执行。

我选的是按第2种方法来处理extraLines的值,但我在修改代码的时候发现,有好几处代码块功能相同,都需要修改,感觉非常不爽,后来干脆把这段写入工作表的代码单独为一个过程:WriteData

Sub WriteData(ws As Worksheet)    '把数据写入工作表    With ws        If extraLines > 0 Then            .Rows(tbFirstLine + 1 & ":" & tbFirstLine + extraLines).Insert Shift:=xlDown            .Rows(tbFirstLine2 + 1 + extraLines & ":" & tbFirstLine2 + extraLines + extraLines).Insert Shift:=xlDown        Else            extraLines = 0        End If        .Range("B3") = Key        .Range("A5") = Me.CmbCurrentMonth        .Range("F5") = Me.CmbDeadLine        .Cells(tbFirstLine, 1).Resize(UBound(arr1), UBound(arr1, 2)) = arr1        .Cells(tbFirstLine2 + extraLines, 1).Resize(UBound(arr2), UBound(arr2, 2)) = arr2        memoLine = tbLastLine2 + 4 + extraLines * 2        .Cells(memoLine, 1) = "请各位法人于" & Me.CmbCurrentMonth & "缴完应付额"    End WithEnd Sub

当然,我们要把extraLines,Key定义到过程外面去,把它们变成公众变量,或者作为上面独立过程的参数。

后来,发现生成的序号好象也有问题,也作了修改,直接使用变量k的值。又发现这样的代码有2处一模一样的,干脆也独立为一个过程吧:

Sub WriteArray(arr1(), arr2())    ReDim arr1(1 To dic(fileName), 1 To 13)    ReDim arr2(1 To dic(fileName), 1 To 4)    For i = 2 To UBound(arrDetail)        If arrDetail(i, 1) = fileName Then            k = k + 1            For m = 2 To 13                arr1(k, m) = arrDetail(i, m)            Next            arr1(k, 1) = k            arr2(k, 1) = k            arr2(k, 2) = arrDetail(i, 2)            arr2(k, 3) = arrDetail(i, 14)            arr2(k, 4) = arrDetail(i, 15)        End If    NextEnd Sub

另外,在生成独立文件的时候,有一张空白的表格“Sheet",看着碍眼,删了它!

For Each ws In wb.Worksheets    If ws.Name <> Key Then        ws.Delete    End IfNext

这下清爽多了。测试一下,没有问题。收工!

更新后的完整代码我放到第二条文章吧,感兴趣朋友可以去看一看。或者,跟以前的代码比较比较,捋一捋这里面的逻辑关系,我想,如果是想学VBA,花这点功夫应该是值得的。

写到最后,我想起来,我应该向大家说声抱歉! 以后要多测试、多检查,提高代码质量!

今天是周末,祝大家周末愉快!(好象上个周末我们也是更正代码的,这难道仅仅是巧合?)

~~~~~~End~~~~~~

喜欢就点个赞、点在看、留言评论、分享一下呗!感谢支持!

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«    2024年12月    »
1
2345678
9101112131415
16171819202122
23242526272829
3031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
    文章归档
      友情链接