内容提要数组、字典工作表复制工作表动态插入行工作表合并单元格大家好,我是冷水泡茶,这两天在某论坛上看到一则求助贴,要求根据出库明细表按照模板生成送货单,同一个地址合并为一张送货单。关于生成送货单的案例,我们分享过一个【批量生成送货单/根据订单总表生成客户送货单】,但今天这个略有不同,我们一起来看一看:这是出库明细表,是一个单独的文件:这是要生成的送货单模板,也是一个单独的文件:他给的模板中有好多行,我把它给删掉一些,只保留一行,作为模板,格式固定。当数据多于1行时,我们再根据需要插入行,避免出现空行。他的要求是:根据出库明细表里面的地址,按照送货单的信息把出库数据汇总,然后以出库单号命名,多个出库单号用-来连接。花了一点时间,终于完工了,分享给大家:基本思路与实现过程1、设置一个用户窗体UserForm1,用来选择出库明细表、选择工作表、选择生成的送货单保存文件夹。2、把启动窗体的命令按钮放到菜单栏“加载项”中,主要原因是,如果在模板表中加一个命令按钮,那么复制工作表的时候需要删除它,再如果增加一张工作表,放置命令按钮,又有点松垮。所以,这回我们尝试另一种方式。3、我们点击“加载项”选项卡,点“送货单”,点“生成”,启动用户窗体UserForm1。4、在UserForm1启动后,我们选择文件,打开出库明细文件,并选择正确的工作表。为了不影响后续操作,我们隐藏打开的工作表。
Set wb = Workbooks.Open(filePath)wb.Windows(1).Visible=False
5、选好保存路径,我们点“生成”按钮,按既定要求生成送货单。(1)把数据读入数组arr。(2)循环数组arr,以地址作为key,数组arrTem作为itme加入字典dic。arrTem存放明细数据。(3)循环字典的key,取出item到arrTem,把其中的第四列“出库单号”用“-”连起来作为保存文件名。(4)把“送货单”模板表复制到新建工作簿,这里我们直接复制工作表,并保存文件。ws.CopySet wb = ActiveWorkbookwb.SaveAssaveFolder&"\"&fileName
(5)根据arrTem的列数插入相应的行,把arrTem的数据写入工作表。(6)设置合计行的汇总公式。 .Cells(5 + u + 1, 3).Formula = "=sum(" & rng.Address & ")"
(7)设置出库单号栏格式,把相同号码单元格合并居中。For i = 5 To 5 + u If .Cells(i, 4) <> .Cells(i - 1, 4) Then m = i End If If .Cells(i, 4) <> .Cells(i + 1, 4) Then n = i .Range(.Cells(m, 4), .Cells(n, 4)).Merge End IfNext
这种合并相同单元格的方法,我们在以前的案例中也使用过,可以算一个模式代码了。先找到开始行m(判断标准是与其上一行不同),再找到结束行n(判断标准是与其下一行不同),有了m和n,则合并单元格的范围就好确定了。6、工作表排序:在前述单元格合并居中操作中,我们需要把相同的出库单号连续排列,否则合并居中的结果可能就不符合我们的预期(虽然不会报错),所以在提取数据前,我们对出库明细表按出库单号进行升序排序。我们在两个地方需要执行排序操作(一处是选择文件时,会自动选择第一张表,另一处是CmbSheets的Change事件,选择工作表),所以单独做了一个排序过程,供多处调用:Private Sub SortSheet(ws As Worksheet) With ws.Sort .SortFields.Clear .SortFields.Add Key:=ws.Cells(1, 9), _ SortOn:=xlSortOnValues, Order:=xlAscending, _ DataOption:=xlSortNormal .SetRange ws.UsedRange .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End WithEndSub
这个代码别看他内容多,其实录制个自定义排序的宏就都有了。有一些属性可以加到自定义过程的参数里,这样适用性就高一点。7、数据校验:在我们保存文件时,是按照出库单号作为文件名的,而归集数据的标准是以地址为准的,是不是有可能存在同一个出库单有不同的地址?那么就有可能会有文件被覆盖,造成数据缺失。所以,在生成送货单之前,做了一个数据检查,如果同一个出库单有不止一个地址的,将退出程序。虽然这样的情况不太可能发生,但从写代码的角度来说,不得不考虑。看上去有点多此一举,但这样做应该有利于拓展我们的思维,让我们考虑问题会更加全面。当然,这样肯定会增加工作量。其实,引起这个问题的的原因是他要求文件保存的方式,不能100%确定是唯一的文件名。解决这种问题,我们可以用dic的key,也就是“地址”作为文件名,或者在文件名后面添加不可能重复的随机数,比如当前时间等。不过,话又说回来,用地址作为文件名,说不定会含有不符合文件名要求的字符,又是一件麻烦事。8、在我准备到论坛发文件时,发现楼主的需求又变了,他要把“地址“放到“合计”的下面。算了,不发也罢。不改了,就这样。打完收功。完整代码见第二条推文。~~~~~~End~~~~~~喜欢就点个赞、点在看、留言评论、分享一下呗。
感谢支持。
案例文件分享说明:关注同名VX公众号了解案例文件免费分享方法
0 评论