ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
12
返回列表 发新帖
楼主: 约定的童话

[求助] VBA智能化汇总类型,难度比较高,鲜花奉上!

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-8-21 21:34 | 显示全部楼层
  1. Sub Demo()

  2.     Dim findArr(), arr(), sht1 As Worksheet, sht2 As Worksheet
  3.     Set sht1 = Sheets("成品入库登记表")
  4.     Set sht2 = Sheets("成品库存统计表")
  5.     arr = sht1.Range("I4:I" & sht1.Range("I4").End(xlDown).Row)
  6.     Dim i As Long, j As Long, maxDate
  7.     maxDate = arr(1, 1)
  8.     For i = LBound(arr) + 1 To UBound(arr)
  9.         If maxDate < arr(i, 1) Then
  10.             maxDate = arr(i, 1)
  11.         End If
  12.     Next i
  13.     j = 1
  14.     For i = LBound(arr) + 1 To UBound(arr)
  15.         If maxDate = arr(i, 1) Then
  16.             ReDim Preserve findArr(1 To j)
  17.             findArr(j) = i + 3
  18.             j = j + 1
  19.         End If
  20.     Next i
  21.     Dim rng As Range, bl As Boolean, firstAddress As String
  22.     For i = LBound(findArr) To UBound(findArr)
  23.         Set rng = sht2.Range("B3:B" & sht2.Cells(Rows().Count, 2).End(xlUp).Row).Find(sht1.Cells(findArr(i), 2).Value, , , xlWhole)
  24.         If rng Is Nothing Then
  25.             With sht2.Cells(sht2.Rows().Count, 2).End(xlUp)
  26.                 If IsNumeric(.Offset(0, -1).Value) Then
  27.                     .Offset(1, -1).Value = .Offset(0, -1).Value + 1
  28.                 Else
  29.                     .Offset(1, -1).Value = 1
  30.                 End If
  31.                 .Offset(1, 0).Value = sht1.Cells(findArr(i), 2).Value
  32.                 .Offset(1, 1).Value = sht1.Cells(findArr(i), 3).Value
  33.                 .Offset(1, 2).Value = sht1.Cells(findArr(i), 4).Value
  34.                 .Offset(1, 3).Value = sht1.Cells(findArr(i), 5).Value
  35.                 .Offset(1, 4).Value = sht1.Cells(findArr(i), 6).Value
  36.             End With
  37.         Else
  38.             firstAddress = rng.Address
  39.             Do
  40.                 If rng.Offset(0, 3).Value = sht1.Cells(findArr(i), 5).Value Then
  41.                     rng.Offset(0, 4).Value = rng.Offset(0, 4).Value + sht1.Cells(findArr(i), 6).Value
  42.                     bl = True
  43.                     Exit Do
  44.                 End If
  45.                 Set rng = sht2.Range("B3:B" & sht2.Cells(Rows().Count, 2).End(xlUp).Row).FindNext(rng)
  46.             Loop While Not rng Is Nothing And rng.Address <> firstAddress
  47.             If Not bl Then
  48.                 With sht2.Cells(sht2.Rows().Count, 2).End(xlUp)
  49.                     If IsNumeric(.Offset(0, -1).Value) Then
  50.                         .Offset(1, -1).Value = .Offset(0, -1).Value + 1
  51.                     Else
  52.                         .Offset(1, -1).Value = 1
  53.                     End If
  54.                     .Offset(1, 0).Value = sht1.Cells(findArr(i), 2).Value
  55.                     .Offset(1, 1).Value = sht1.Cells(findArr(i), 3).Value
  56.                     .Offset(1, 2).Value = sht1.Cells(findArr(i), 4).Value
  57.                     .Offset(1, 3).Value = sht1.Cells(findArr(i), 5).Value
  58.                     .Offset(1, 4).Value = sht1.Cells(findArr(i), 6).Value
  59.                 End With
  60.             End If
  61.             bl = False
  62.         End If
  63.     Next i

  64. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-8-22 08:13 | 显示全部楼层
humanmagic 发表于 2018-8-21 20:58
这是因为你清空了之后,B4.End(XlDown)直接到了工作表最下面一行,后面的代码添加新行肯定报错。

明白了,我想一下有没有好办法解决这个问题

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-8-22 08:14 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-8-22 09:32 | 显示全部楼层
  1. Sub 查找()
  2.     Dim oConn As Object, sSelect As String
  3.     Dim nRow As Double
  4.    
  5.     nRow = Sheets("成品入库登记表").Cells(Rows.Count, 9).End(xlUp).Row
  6.     Set oConn = CreateObject("Adodb.Connection")
  7.     If Val(Application.Version) < 12 Then
  8.         oConn.Open "Provider=Microsoft.Jet.Oledb.4.0;Extended Properties=Excel 8.0;Data Source=" & ThisWorkbook.FullName '建立数据库连接
  9.     Else
  10.         oConn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & ThisWorkbook.FullName '建立数据库连接
  11.     End If
  12.    
  13.     sSelect = "Select [产品编号],[产品名称],[规格],[品牌],[数量] From [成品入库登记表$A3:I" & nRow & "] " & _
  14.         "Where [入库时间] in (" & _
  15.             "Select A.[入库时间] From (Select [入库时间],abs([入库时间]-#" & Date & "#) as 日期差 From [成品入库登记表$A3:I" & nRow & "] group by [入库时间]) As A " & _
  16.                 "Where A.[日期差] in (Select min([日期差]) From (Select [入库时间],abs([入库时间]-#" & Date & "#) as 日期差 From [成品入库登记表$A3:I" & nRow & "] group by [入库时间])))"
  17.     Sheets("成品库存统计表").Cells(Rows.Count, 2).End(xlUp).Offset(1).CopyFromRecordset oConn.Execute(sSelect)
  18.     oConn.Close
  19.     Set oConn = Nothing
  20. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2018-8-22 09:43 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
附上附件以供参考

123(by.micro).rar

43.84 KB, 下载次数: 12

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2018-8-22 10:29 | 显示全部楼层
本帖最后由 ivccav 于 2018-8-22 10:35 编辑
约定的童话 发表于 2018-8-22 08:14
大神,是汇总求和到第二个表里面,参考1楼的思路

我的程序就是把第一个表汇总到第二个表里面,跟你1楼的思路完全一致。

我为了避免频繁操作Range对象和Find方法而造成运行效率低下,才改为数组+字典。

Find方法适合只找1次的情况,如果循环多次,效率非常低,应该用字典。用数组循环也比Range循环快很多倍。因为数组的数据是存放在内存中的。使用字典则不需要循环,一次到位,查找数据非常快。

你试试就知道是否正确了。2楼的代码是有问题的,xlDow是向下找,所以你清空表二数据就报错了,且使用range对象和find方法来操作数据,在数据多的情况下,速度可能会慢几百倍以上。
2楼应该是初学者,写的代码还是比较原始的,跟我开始写代码的时候一样,程序效率很低。我开始写的代码经常运行几分钟,后来用数组和字典,基本都是1秒以内了。


TA的精华主题

TA的得分主题

 楼主| 发表于 2018-8-22 14:41 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
ivccav 发表于 2018-8-22 10:29
我的程序就是把第一个表汇总到第二个表里面,跟你1楼的思路完全一致。

我为了避免频繁操作Range对象和 ...

可是我运行结果都是在第一个表累积的?难道我下错文件了?

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-8-22 14:41 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-8-22 14:58 | 显示全部楼层
本帖最后由 ivccav 于 2018-8-22 15:05 编辑
约定的童话 发表于 2018-8-22 14:41
可是我运行结果都是在第一个表累积的?难道我下错文件了?

不是文件下错了,而是你在第一个表内运行代码,第一个表成了活动工作表。你在表二建个按钮就行了。

为了不捆绑固定的工作表,我特意没有指定输出数据的表名,而让数据输出到任意活动工作表内。

VBA中操作对象是非常慢的,如2楼的代码。ADO(操作数据库的对象)操作EXCEL能减少代码,但是因为EXCEL不是数据库,效率也不会高。你复制几千上万的数据试试就知道运行效率了。

算了,为了这个简单的问题,浪费这么多笔墨。你什么自己爱用什么方式就什么方式吧。我只提供速度快,容易懂的代码。我写的代码都是验证过才发出来的,并不是你说的那种结果。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-8-22 17:35 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
ivccav 发表于 2018-8-22 14:58
不是文件下错了,而是你在第一个表内运行代码,第一个表成了活动工作表。你在表二建个按钮就行了。

为 ...

收到,大神,我说呢,原来我在第一个表运行了.....
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-19 22:51 , Processed in 0.036336 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表