.net 怎么循环得到数组里的值_ExcelVBA 7.23当横向合并数据,碰到行数据不全怎么办?VBA来帮你...

前景提要(文末提供源码下载)

昨天分享了关于多个报表横向合并数据的操作,相对于之前我们常见的纵向合并数据,横向合并数据在一些场合中也是经常使用到的,今天我们将针对这个问题进行更进一步的研究,因为昨天我们分享的方法仅仅是合并,没有太多的要求,但是按照惯例,日常工作中肯定会碰到很多不标准的数据,比方说参照列数据不全,字段数据也不全的情况,那么这些情况要如何处理呢?

场景模拟

还是使用我们上一节使用的案例来说明,为了适应场景,我们改造下数据源,第一个表去掉A1,第二个表去掉A6,A7第三个表去掉A2,A10

总之三个表没有一个表的字段是完整的,尽可能的接近我们日常使用的数据情况

d399998f2478b62fd93f927c6e3ba95a.png

那么如何讲这样的一份数据汇总在一个工作表中呢?

代码区

上节我们主要是用了数组的方式,那么今天我们来换种方法,准确的说是新增一种组合方法,字典+数组

Sub twotwo()Dim nsth As Worksheet, arr(), arr1(), zd As ObjectSet zd = CreateObject("scripting.dictionary")h = 0For Each sth In Worksheets For x = 1 To sth.Cells(Rows.Count, 1).End(xlUp).Row k1 = sth.Cells(x, 1) If Not zd.exists(k1) Then zd.Add k1, k1 End If Next xNext sthcountN = zd.CountFor Each sth In Worksheets 'If sth.Name <> nsth.Name Then k = k + 1 If k = 1 Then l = sth.Cells(1, Columns.Count).End(xlToLeft).Column counts = Worksheets.Count ReDim Preserve arr(1 To countN, 1 To l) For i1 = 1 To sth.Cells(Rows.Count, 1).End(xlUp).Row For j1 = 1 To l arr(i1, j1) = sth.Cells(i1, j1) Next j1 Next i1 Else arrt = sth.UsedRange.Columns(1) l = sth.Cells(1, Columns.Count).End(xlToLeft).Column new_arr = WorksheetFunction.Transpose(arrt) ReDim Preserve arr(1 To countN, 1 To UBound(arr, 2) + l - 1) 'rrrt = WorksheetFunction.Transpose(WorksheetFunction.Index(arr, 0, 1)) For i = 1 To UBound(new_arr) On Error Resume Next num = WorksheetFunction.Match(new_arr(i), WorksheetFunction.Transpose(WorksheetFunction.Index(arr, 0, 1)), 0) If Err.Number = 0 Then For j = 2 To l arr(num, UBound(arr, 2) + j - l) = sth.Cells(i, j) Next j Else h = i1 arr(h, 1) = new_arr(i) For j = 2 To l arr(h, UBound(arr, 2) + j - l) = sth.Cells(i, j) Next j End If Next i End If 'End IfNext sthWorksheets.Add after:=Worksheets(Worksheets.Count)Set nsth = ActiveSheetnsth.Name = "横向汇总(2)"nsth.Cells(1, 1).Resize(UBound(arr), UBound(arr, 2)) = arrEnd Sub

来看看最终的效果

fea9612922497a35384d0c919c4b185c.png

原始参照列中有的字段,应该为空的都为空,本身有数据的,也增加了相应的数据,其中在第一个表中被我们删除的数据A1,单独增加到行,数据也没有缺少,

成功的实现了我们的要求

代码分析

本次代码,我们多引入了一个概念,就是字典,字典在VBA中主要的作用,就是用统计非重复数据的,在字典中,所有的数据都具有唯一性

在本案例中

For Each sth In Worksheets For x = 1 To sth.Cells(Rows.Count, 1).End(xlUp).Row k1 = sth.Cells(x, 1) If Not zd.exists(k1) Then zd.Add k1, k1 End If Next xNext sth

就是通过一个小小的循环,在实现字典的构造

首先我们先声明一个字典,这是标准结构,大家直接套用即可

Set zd = CreateObject("scripting.dictionary")
  1. 通过循环来构造字典
  2. 判断字典中,这个值是否存在
  3. 存在,就跳过
  4. 不存在,则写入字典

上面的这段循环,就是下面的这段代码

 If Not zd.exists(k1) Then'判断是否存在 zd.Add k1, k1'不存在写入 End If

为什么要构造一个字典呢?因为我们知道动态数组,每次重置只能更改他的二维的坐标,一维坐标是无法更改的,放在excel中就是只能增加列,不能增加行

所有我们需要先得到总共有多少行,那么得到了字典之后,如何得到总个数呢?

countN = zd.Count

好了,现在有了总行数,我们就可以声明一个动态数组了,利用动态数组不断的根据行

当进行第一次循环的时候,我们通过遍历循环的方式得到一个数组,这个数组就是第一个表的全部数据

 If k = 1 Then l = sth.Cells(1, Columns.Count).End(xlToLeft).Column counts = Worksheets.Count ReDim Preserve arr(1 To countN, 1 To l) For i1 = 1 To sth.Cells(Rows.Count, 1).End(xlUp).Row For j1 = 1 To l arr(i1, j1) = sth.Cells(i1, j1) Next j1 Next i1
7b42db9282133252aa0fae01d5f6f9be.png

当从第二个工作表的饿时候,我们就要进行判断了,这里我们来看看是如何进行判断的

我们先将当前工作表的第一列复制给输入arrt,然后我们去判断,当前arrt中的数据是否在我们之前已经汇总好数组中,判断的方式就用我们之前学习过的match方法

我们这里先对数组进行下增加列的操作

ReDim Preserve arr(1 To countN, 1 To UBound(arr, 2) + l - 1)

增加多少列呢?当前数组的列数+当前活动工作表的列数-第一行参考列,这样大家应该很好理解了。

 For i = 1 To UBound(new_arr) On Error Resume Next num = WorksheetFunction.Match(new_arr(i), WorksheetFunction.Transpose(WorksheetFunction.Index(arr, 0, 1)), 0) If Err.Number = 0 Then For j = 2 To l arr(num, UBound(arr, 2) + j - l) = sth.Cells(i, j) Next j Else h = i1 arr(h, 1) = new_arr(i) For j = 2 To l arr(h, UBound(arr, 2) + j - l) = sth.Cells(i, j) Next j End If Next i

这就是今天判断了,如果存在就是直接在原来数组的后面写入数据,如果不存在的话,就在原有数组的后面写入,这里要注意,并不是新增数组的行数,而是原有数组的非空行,怎么理解呢?

在第一次循环第一个表的时候,i1正好代表了,所有的行数,所以这里我们直接将H=i1的行数,就可以得到最后一个非空数组的位置了,

9a3b9f242bc97e52e92832f18d298f43.png

这里11的这个位置还是空值

06832c4215adf0078c82a03056e8b339.png

将数组的状态和最终形成的状态对比着看,这样大家会更好理解一点

后面的思路就和上节相同了。

=======================================================

本节课的案例源码已经上传,需要的小伙伴们后台私信“7-23-6”即可,希望大家多多支持~~

说明一下,下载了源码文件之后,要放在需要合并的文件夹内才可以正常执行

好了~明晚19:00,准时再见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值