ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 彭希仁

[讨论]有点难度的汇总

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-11-30 09:23 | 显示全部楼层

不错,又提供一种新的思路。

TA的精华主题

TA的得分主题

发表于 2007-11-30 09:34 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
数据少时可能看不出差别,数据多时复制、删除占用时间较多

TA的精华主题

TA的得分主题

发表于 2007-11-30 09:47 | 显示全部楼层

怎么都要借助外力呢才能达到高速呢!我这个自定义数据类型,不用排序,所有数据统计完毕才0.5秒,最后显示估计不会超过1秒!!欢迎大家来完善,因为这更具有通用性.(好象论坛之中,讲到自定义数据类型(也就是大家所熟悉的结构)的很少啊)

Option Explicit
'-----------------------
Type sf
name As String
sum As Integer
End Type
'-----------------------
Type gz
name As String
pro(1 To 50) As sf
sum As Long
sfsum As Byte
End Type
'-----------------------
Type jx
name As String
sum As Long
bad(1 To 20) As gz
gzsum As Byte
End Type
'----------------------


Dim data(1 To 20) As jx, p As Long, p1 As Integer, p2 As Integer
Dim arr
Dim j As Integer, jj As Integer, jjj As Integer
Dim over As Boolean, over1 As Boolean, over2 As Boolean
Dim str As String, str1 As String, str2 As String

Sub erw()
Dim a
Dim i As Long, m As Long, jxsum As Byte
a = Timer
With Worksheets("sheet2")
p = .Range("a65536").End(xlUp).Row
arr = .Range("a2:c" & p)
End With
m = UBound(arr, 1)
p = 0
p1 = 0
p2 = 0
jxsum = 0
For i = 1 To m
over = False
str = Trim(arr(i, 1))
str1 = Trim(arr(i, 2))
str2 = Trim(arr(i, 3))
For j = 1 To jxsum
If data(j).name = str1 Then
over = True
data(j).sum = data(j).sum + 1
checkgz j
Exit For
End If
Next
If over = False Then
jxsum = jxsum + 1
data(jxsum).name = str1
data(jxsum).sum = data(jxsum).sum + 1
data(jxsum).name = str1
data(jxsum).gzsum = data(jxsum).gzsum + 1
data(jxsum).bad(data(jxsum).gzsum).sfsum = data(jxsum).bad(data(jxsum).gzsum).sfsum + 1
data(jxsum).bad(data(jxsum).gzsum).pro(data(jxsum).bad(data(jxsum).gzsum).sfsum).name = str2
data(jxsum).bad(data(jxsum).gzsum).pro(data(jxsum).bad(data(jxsum).gzsum).sfsum).sum = data(jxsum).bad(data(jxsum).gzsum).pro(data(jxsum).bad(data(jxsum).gzsum).sfsum).sum + 1
End If
Next

'------------------------------------------------------------------
For i = 1 To jxsum
Cells(i + 1, 4) = data(i).name
Cells(i + 1, 5) = data(i).sum
Next
MsgBox Format(Timer - a, "0.00")
End Sub
Sub checkgz(j As Integer)
over1 = False
For jj = 1 To data(j).gzsum
If data(j).bad(jj).name = str2 Then
over1 = True
data(j).bad(jj).sum = data(j).bad(jj).sum + 1
checksf j, jj
Exit For
End If
Next
If over1 = False Then
data(j).gzsum = data(j).gzsum + 1
data(j).bad(data(j).gzsum).name = str2
data(j).bad(data(j).gzsum).sum = data(j).bad(data(j).gzsum).sum + 1
data(j).bad(data(j).gzsum).sfsum = data(j).bad(data(j).gzsum).sfsum + 1
data(j).bad(data(j).gzsum).pro(data(j).bad(data(j).gzsum).sfsum).name = str
data(j).bad(data(j).gzsum).pro(data(j).bad(data(j).gzsum).sfsum).sum = data(j).bad(data(j).gzsum).pro(data(j).bad(data(j).gzsum).sfsum).sum + 1
End If
End Sub
Sub checksf(j As Integer, jj As Integer)
over2 = False
For jjj = 1 To data(j).bad(jj).sfsum
If data(j).bad(jj).pro(jjj).name = str Then
over2 = True
data(j).bad(jj).pro(jjj).sum = data(j).bad(jj).pro(jjj).sum + 1
Exit For
End If
Next
If over2 = False Then
data(j).bad(jj).sfsum = data(j).bad(jj).sfsum + 1
data(j).bad(jj).pro(data(j).bad(jj).sfsum).name = str
data(j).bad(jj).pro(data(j).bad(jj).sfsum).sum = data(j).bad(jj).pro(data(j).bad(jj).sfsum).sum + 1
End If
End Sub

TA的精华主题

TA的得分主题

发表于 2007-11-30 09:57 | 显示全部楼层
全是高手呀,不想让人活了??

学习了!

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-11-30 10:01 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
QUOTE:
以下是引用tycp在2007-11-30 9:47:00的发言:

怎么都要借助外力呢才能达到高速呢!我这个自定义数据类型,不用排序,所有数据统计完毕才0.5秒,最后显示估计不会超过1秒!!欢迎大家来完善,因为这更具有通用性.(好象论坛之中,讲到自定义数据类型(也就是大家所熟悉的结构)的很少啊)

Option Explicit
'-----------------------
Type sf
name As String
sum As Integer
End Type
'-----------------------
Type gz
name As String
pro(1 To 50) As sf
sum As Long
sfsum As Byte
End Type
'-----------------------
Type jx
name As String
sum As Long
bad(1 To 20) As gz
gzsum As Byte
End Type
'----------------------


Dim data(1 To 20) As jx, p As Long, p1 As Integer, p2 As Integer
Dim arr
Dim j As Integer, jj As Integer, jjj As Integer
Dim over As Boolean, over1 As Boolean, over2 As Boolean
Dim str As String, str1 As String, str2 As String

Sub erw()
Dim a
Dim i As Long, m As Long, jxsum As Byte
a = Timer
With Worksheets("sheet2")
p = .Range("a65536").End(xlUp).Row
arr = .Range("a2:c" & p)
End With
m = UBound(arr, 1)
p = 0
p1 = 0
p2 = 0
jxsum = 0
For i = 1 To m
over = False
str = Trim(arr(i, 1))
str1 = Trim(arr(i, 2))
str2 = Trim(arr(i, 3))
For j = 1 To jxsum
If data(j).name = str1 Then
over = True
data(j).sum = data(j).sum + 1
checkgz j
Exit For
End If
Next
If over = False Then
jxsum = jxsum + 1
data(jxsum).name = str1
data(jxsum).sum = data(jxsum).sum + 1
data(jxsum).name = str1
data(jxsum).gzsum = data(jxsum).gzsum + 1
data(jxsum).bad(data(jxsum).gzsum).sfsum = data(jxsum).bad(data(jxsum).gzsum).sfsum + 1
data(jxsum).bad(data(jxsum).gzsum).pro(data(jxsum).bad(data(jxsum).gzsum).sfsum).name = str2
data(jxsum).bad(data(jxsum).gzsum).pro(data(jxsum).bad(data(jxsum).gzsum).sfsum).sum = data(jxsum).bad(data(jxsum).gzsum).pro(data(jxsum).bad(data(jxsum).gzsum).sfsum).sum + 1
End If
Next

'------------------------------------------------------------------
For i = 1 To jxsum
Cells(i + 1, 4) = data(i).name
Cells(i + 1, 5) = data(i).sum
Next
MsgBox Format(Timer - a, "0.00")
End Sub
Sub checkgz(j As Integer)
over1 = False
For jj = 1 To data(j).gzsum
If data(j).bad(jj).name = str2 Then
over1 = True
data(j).bad(jj).sum = data(j).bad(jj).sum + 1
checksf j, jj
Exit For
End If
Next
If over1 = False Then
data(j).gzsum = data(j).gzsum + 1
data(j).bad(data(j).gzsum).name = str2
data(j).bad(data(j).gzsum).sum = data(j).bad(data(j).gzsum).sum + 1
data(j).bad(data(j).gzsum).sfsum = data(j).bad(data(j).gzsum).sfsum + 1
data(j).bad(data(j).gzsum).pro(data(j).bad(data(j).gzsum).sfsum).name = str
data(j).bad(data(j).gzsum).pro(data(j).bad(data(j).gzsum).sfsum).sum = data(j).bad(data(j).gzsum).pro(data(j).bad(data(j).gzsum).sfsum).sum + 1
End If
End Sub
Sub checksf(j As Integer, jj As Integer)
over2 = False
For jjj = 1 To data(j).bad(jj).sfsum
If data(j).bad(jj).pro(jjj).name = str Then
over2 = True
data(j).bad(jj).pro(jjj).sum = data(j).bad(jj).pro(jjj).sum + 1
Exit For
End If
Next
If over2 = False Then
data(j).bad(jj).sfsum = data(j).bad(jj).sfsum + 1
data(j).bad(jj).pro(data(j).bad(jj).sfsum).name = str
data(j).bad(jj).pro(data(j).bad(jj).sfsum).sum = data(j).bad(jj).pro(data(j).bad(jj).sfsum).sum + 1
End If
End Sub

高,实在是高

 

  data(j).bad(data(j).gzsum).name = str2              这句下标越界,详情见附件

 

EjE6brxY.rar (212.3 KB, 下载次数: 34)
[此贴子已经被作者于2007-11-30 10:08:40编辑过]

TA的精华主题

TA的得分主题

发表于 2007-11-30 10:19 | 显示全部楼层
QUOTE:
以下是引用彭希仁在2007-11-30 10:01:46的发言:

高,实在是高

 

  data(j).bad(data(j).gzsum).name = str2              这句下标越界,详情见附件

 



自定义数据类型可以构造很好的数据结构出来,这样就不需要用到EXCEL的排序功能或者用对象!!虽然速度没有以上两者快!!我这个还有点问题,大家可以完善结合彭兄的数组算法!应该可以提高到极速!

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-11-30 11:07 | 显示全部楼层
QUOTE:
以下是引用tycp在2007-11-30 10:19:34的发言:

自定义数据类型可以构造很好的数据结构出来,这样就不需要用到EXCEL的排序功能或者用对象!!虽然速度没有以上两者快!!我这个还有点问题,大家可以完善结合彭兄的数组算法!应该可以提高到极速!

希望楼上的兄弟能尽快做出一个代替排序的程序出来。这将是伟大的创举。解决问题又出多一种全新的解决方案。

TA的精华主题

TA的得分主题

发表于 2007-11-30 12:02 | 显示全部楼层
QUOTE:
以下是引用彭希仁在2007-11-30 11:07:38的发言:

希望楼上的兄弟能尽快做出一个代替排序的程序出来。这将是伟大的创举。解决问题又出多一种全新的解决方案。

这道题目难点在于数据要怎么存放的问题,也就是怎么设计一种好的数据结构,在一次循环中把数据全部统计出来,根本不需要排序!!

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-11-30 12:35 | 显示全部楼层
QUOTE:
以下是引用tycp在2007-11-30 12:02:52的发言:

这道题目难点在于数据要怎么存放的问题,也就是怎么设计一种好的数据结构,在一次循环中把数据全部统计出来,根本不需要排序!!

有道理,好的数据结构最重要了.

TA的精华主题

TA的得分主题

发表于 2007-11-30 12:45 | 显示全部楼层

自定义数据类型倒是个很好的想法。但是是如何定义才是速度的关键。这一方面要求很高(我是没这水平的)。

字典和数组我都写过类似要求的代码,算是比较了解两者的差别。

用字典完成工作,写代码的时间短一些,用数组时间长一些,因为要考虑的因素多很多。

一个疏忽就会导致结果错误,(彭兄的新代码,就有一个瑕疵,在最后一行出错)

大多数情况下,字典完成的代码,可以用数组更快的完成,前提是写代码的水平高。

我处理这类问题通常都是先用字典,如果速度很不理想(创建了N多的字典),再花更多的时间换成数组。

通用的东西只在某一方面做的较理想,字典就是微软提供的一个通用的类,字典处理重复值就很快。

但用在这里,不是最快的(但代码完成的时间是最早的,不用考虑太多的因素)。

做这道题60000行的汇总,个人感觉应该能在0.1秒内完成计算(没吃过猪肉,还没见过猪跑吗)。

这个汇总统计很有实用价值,希望高人引起兴趣。

顶!!!

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-15 07:22 , Processed in 0.037794 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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