思路决定运行速度
vba吧
全部回复
仅看楼主
level 5
思路决定运行速度
excel提取重复值的数量(筛选出唯一值的数量)有很多方法,不同方法的运行速度差别很大,尤其在处理海量数据是选择不当的话速度能让人崩溃。
要提取重复值的数量分删除重复值+重复值计数2个动作,在低版本的excel一般采用函数Countif、函数match等求的处理,对于海量数据简直是煎熬,用高级筛选或删除重复值速度能稍微少一些,至于用VBA的字典或集合等方式更是蛮不可以,80万行数据要4000s才能给出结果。有没有更迅捷的方式?
下面是新写自定义函数适合所有excel版本,速度超快,100万行数据4s出数据,堪比高版本新出的函数unique。
思路:备份数据、原位排序、数组计数、恢复数据、输出
Function dys(a As Range) As Long'独有数
'a为在同一列內单元格区域,默认没有合并单元格,空行忽略不计数
i = Range(a.Cells(1, 1), a.Cells(a.Rows.Count, 1)) '把原始数据保存,最后再恢复
a.Cells(1, 1).Select
Range(a.Cells(1, 1), a.Cells(a.Rows.Count, 1)).Sort Key1:=a.Cells(1, 1), Order1:=1 '把原始数据排序便于比较
h = Range(a.Cells(1, 1), a.Cells(Cells(1048576, Selection.Column).End(xlUp).Row - a.Cells(1, 1).Row + 1, 1)) '把排序数据存入新数组提高比较运行速度
a.Cells(1, 1).Resize(UBound(i), 1) = i: Set i = Nothing'恢复数据、释放内存
For i = 2 To UBound(h)
If h(i, 1) = h(i - 1, 1) Then c = c + 1’对重复值计数,不能采用h(i, 1)<>h(i - 1, 1)N
ext
i = UBound(h) - c
Set h = Nothing'释放内存
dys = i
End Function
2025年02月19日 07点02分 1
level 5
设计唯一值/独有值提取还有一个案例,求2列数据的独有值(A列有且不在J列的称A列独有值)
在低版本的excel一般采用函数Countif、函数match、函数vlookup等的处理,对于海量数据简直是煎熬,至于用VBA的字典或集合等方式更是蛮不可以,80万行数据要4000s才能给出结果。有没有更迅捷的方式?
用删除重复值速度大约20s(2列都是60多万行为例):A列数据复制到J列数据下,执行数据-删除重复值,J列数据下面就是A列独有值,J列同理。
有没有更快的方式,采用VBa调用更成熟的bat处理,写个自定义函数,3s出结果。
vba:我数据从3行开始
aa= Range("a3:a" & [a1048576].End(xlUp).Row)
jj= Range("j3:j" & [j1048576].End(xlUp).Row)
Workbooks.Add
[a1].Resize(UBound(aa), 1) = aa
ActiveWorkbook.SaveAs Filename:="G:\319\a.txt",FileFormat:=xlUnicodeText, CreateBackup:=False
[a1].Resize(UBound(aa), 1).Clear: Set aa = Nothing
[a1].Resize(UBound(jj), 1) = jj: Set jj = Nothing
ActiveWorkbook.SaveAs Filename:="G:\319\j.txt", FileFormat:=xlUnicodeText,CreateBackup:=False
ActiveWorkbook.Close
Setwsh = CreateObject("WScript.Shell")
result = wsh.Run("""" & "G:\319\求独有.bat"& """", 0, True)
Workbooks.Open Filename:="G:\319\独有a.txt"
aa= Range("a1:a" & [a1048576].End(xlUp).Row)
ActiveWorkbook.Close
Range("a" & [a1048576].End(xlUp).Row +1).Resize(UBound(aa), 1) = aa: Set aa = Nothing
Workbooks.Open Filename:="G:\319\独有j.txt"
aa= Range("a1:a" & [a1048576].End(xlUp).Row)
ActiveWorkbook.Close
bat脚本
<#*,:
@璐村惂鐢ㄦ埛_000076K馃惥 off
cd /d "%~dp0"
set "batchfile=%~f0"
Powershell -ExecutionPolicy Bypass -C "Set-Location -LiteralPath ([Environment]::CurrentDirectory);. ([ScriptBlock]::Create([IO.File]::ReadAllText($env:batchfile,[Text.Encoding]::GetEncoding(0) )) )"
exit /b
#>
# a.txt j.txt 生成独有文件
$srca = "a.txt" # 文件 a.txt
$srcj = "j.txt" # 文件 j.txt
$dsta = "独有a.txt" #文件 独有a.txt
$dstj = "独有j.txt" #文件 独有j.txt
foreach ($item in $srca, $srcj) {
if (-not [IO.File]::Exists($item)) {
"找不到文件:$item"
return
}
}
$watch = [System.Diagnostics.Stopwatch]::StartNew() # 计时器
Add-Type -AssemblyName System.Core
# 读取$srca
"读取文件:$srca"
$linesa = [IO.File]::ReadAllLines($srca)
# 读取$srcj
"读取文件:$srcj"
$linesj = [IO.File]::ReadAllLines($srcj)
# 兼容ps2.0,需要先获取GenericMethod
$method_except = [System.Linq.Enumerable].GetMethods() | Where-Object { $_.Name -eq 'Except' } | Select-Object -First 1
$method_except_string = $method_except.MakeGenericMethod([string])
# 生成$dsta
"生成文件:$dsta"
$method_except_string.Invoke($null, @($linesa, $linesj)) | Set-Content -LiteralPath $dsta
# 生成$dstj
"生成文件:$dstj"
$method_except_string.Invoke($null, @($linesj, $linesa)) | Set-Content -LiteralPath $dstj
"脚本用时:"
$watch.Elapsed #统计脚本用时
2025年02月19日 07点02分 2
可以看配置和需求,修改
2025年02月19日 08点02分
level 3
Excel处理数据量较小是很不错的,但像这类数据量大的问题还是使用一些数据库工具用SQL查询比较好
2025年02月20日 01点02分 3
对绝大多是小白来讲数据库是不会的、只会简单的excel。有的单位也没有也不允许在电脑上安装数据库,
2025年02月22日 02点02分
level 1
ADO引用数据盘表,然后SQL GROUP BY 就出结果了
2025年02月20日 01点02分 4
可以,但速度超慢。
2025年02月22日 02点02分
有吧友问我为啥用txt不用csv或xlsx格式?TXT文件是纯文本,没有格式和分隔符等,BAT脚本可以直接读取和处理,无需复杂的解析,速度最快
2025年02月22日 02点02分
bat处理txt的速度相对较快:bat文件中的命令在Windows系统中可以直接执行,无需额外的解释或编译过程,这保证了命令的快速响应和执行。这才是把要比较的数据另存为txt,bat脚本处理、读入txt结果,步骤多了速度却超快的本质原因,跳出excel用原始最成熟的bat方式
2025年02月22日 02点02分
@国泰家美满 如果速度超慢,我觉得你应该先检查一下是不是你使用的方法不对,我都是是秒出数据的,当然记录集回写到表的话,如果数据量大确认会卡一下,但绝对不会超慢的程度,你可以出个题,提供个数据源,然后你用你的方法,我用我的方法来对比一下
2025年02月24日 01点02分
level 1
用的就是ADO的方式,1048576数据去重
2025年02月24日 04点02分 5
level 1
2列10位 1048576行 1000000000到1000001000的随机数分别去重
2025年02月24日 04点02分 6
厉害,高手
2025年03月08日 12点03分
求助,谢谢
2025年03月08日 14点03分
1