ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

使用VBA进行数据匹配和查询,运行速度特别慢

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-7-4 19:13 | 显示全部楼层 |阅读模式
本人工作有需求使用Excel来处理大量数据,数据量大小情况如下:
原始数据 表单 数据处理 表单
行数 3~5万 100~10000
列数 50~100 15~25


需要进行大量Vlookup操作,所以自己做了一个基于数组+字典的查询函数 Ylookup
  1. 'Ylookup查询函数
  2. Public Function Ylookup(LookupValue() As Variant, TableArray() As Variant, ColIndexNum() As Integer, Optional x As Integer) As Variant
  3.     Dim u_LookupValue_1, u_ColIndexNum_1, u_TableArray_1, u_TableArray_2 As Long '列数和行数
  4.     u_LookupValue_1 = UBound(LookupValue, 1)
  5.     u_ColIndexNum_1 = UBound(ColIndexNum, 1)
  6.     u_TableArray_1 = UBound(TableArray, 1)
  7.     u_TableArray_2 = UBound(TableArray, 2)
  8.    
  9.     '创建字典查询 Dic
  10.     Set Dic = CreateObject("Scripting.Dictionary")
  11.     ReDim YLookupValue(1 To u_ColIndexNum_1, 1 To u_LookupValue_1)
  12.     For j = 1 To u_ColIndexNum_1 Step 1  '获取ColIndexNum(i)的列号
  13.         For i = 1 To u_TableArray_1 Step 1  '1 -> Sheets("LTE").UsedRange.Rows.Count
复制代码


运行速度太慢,完整数据运行的耗时需要 90+s
附件内原始数据少了很多,也要10+s
详情请下载附件查看。

求教各位大佬,这种情况下该怎么办?
是不是我哪里写错了 ,还是应该使用其他方式进行查询。。。


查询.rar

1.62 MB, 下载次数: 5

压缩包

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-4 19:15 | 显示全部楼层
emmmmm。。。代码被截断了,只能这样发了


'Ylookup查询函数
Public Function Ylookup(LookupValue() As Variant, TableArray() As Variant, ColIndexNum() As Integer, Optional x As Integer) As Variant
    Dim u_LookupValue_1, u_ColIndexNum_1, u_TableArray_1, u_TableArray_2 As Long '列数和行数

    u_LookupValue_1 = UBound(LookupValue, 1)
    u_ColIndexNum_1 = UBound(ColIndexNum, 1)
    u_TableArray_1 = UBound(TableArray, 1)
    u_TableArray_2 = UBound(TableArray, 2)

    '创建字典查询 Dic
    Set Dic = CreateObject("Scripting.Dictionary")
    ReDim YLookupValue(1 To u_ColIndexNum_1, 1 To u_LookupValue_1)
    For j = 1 To u_ColIndexNum_1 Step 1  '获取ColIndexNum(i)的列号
        For i = 1 To u_TableArray_1 Step 1  '1 -> Sheets("LTE").UsedRange.Rows.Count
            Dic(TableArray(i, 1)) = TableArray(i, ColIndexNum(j))
        Next
        'Dic_arr = Array(Dic.keys, Dic.items)  'DeBUG,方便核查Dic字典项目和数据

        For k = 1 To u_LookupValue_1 Step 1
            YLookupValue(j, k) = Dic(LookupValue(k))
        Next
    Next

    Ylookup = YLookupValue

End Function

TA的精华主题

TA的得分主题

发表于 2018-7-4 23:59 | 显示全部楼层
代码仅供参考


查询abc123.rar (1.62 MB, 下载次数: 13)

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-5 09:17 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

用SQL啊,这个我还不太熟悉,不知道怎么构造我需要的 SQL语句。

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-5 16:07 | 显示全部楼层
abc123281 的提示中,新增了SQL数据库查询函数:SQuery()
运行效率大大提升,只需要 150ms 左右。
不错不错,果然是神器,不过还有个问题需要求教:
    strSQL = "Select [" & ColIndexStr(i) & "] From [GSM$] Where ECI=" & LookupValue(j)
原始数据的字段、查询的字段 ColIndexStr(i) 不能包含 点符号[.] ,否则会报错,请问有没有什么好的解决方案?

SQL查询报错

SQL查询报错



核心代码如下:
'SQL数据库查询函数
Public Function SQuery(LookupValue() As Variant, ColIndexStr() As String) As Variant
    Dim u_LookupValue_1, u_ColIndexStr_1 As Long '列数和行数
    Dim SQueryValue() As Variant

    u_LookupValue_1 = UBound(LookupValue, 1)
    u_ColIndexStr_1 = UBound(ColIndexStr, 1)
    ReDim SQueryValue(1 To u_LookupValue_1, 1 To u_ColIndexStr_1)

    Dim Conn, Rst As Object
    Dim strConn, strSQL As String

    '创建ADO对象。ADO - ActiveX Data Objects:ActiveX 数据对象
    Set Conn = CreateObject("ADODB.Connection")
    Set Rst = CreateObject("ADODB.Recordset")
    PathStr = ThisWorkbook.FullName  '文件路径

    '设置连接字符串,根据版本创建连接
    Select Case Application.Version * 1
    Case Is < 12
        strConn = "Provider=Microsoft.Jet.Oledb.4.0;Extended Properties=excel 8.0;Data source=" & PathStr
    Case Is >= 12
        strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & PathStr & ";Extended Properties=""Excel 12.0;HDR=YES"";"""
    End Select

    '打开数据库链接
    Conn.Open strConn
    For i = 1 To u_ColIndexStr_1 Step 1
        For j = 1 To u_LookupValue_1 Step 1
            '构造SQL语句
            strSQL = "Select [" & ColIndexStr(i) & "] From [GSM$] Where ECI=" & LookupValue(j)
            '执行查询,并将结果输出到记录集对象
            Set Rst = Conn.Execute(strSQL)  '字段名包含 点符号[.] 的时候,这里会报错。
            '清除Null导致的错误,输出至数组保存
            If IsNull(Rst(0).Value) Then
                MsgBox i & vbNewLine & j
                SQueryValue(j, i) = "Null"
            Else
                SQueryValue(j, i) = Rst(0).Value
            End If
        Next
    Next

    '关闭数据库连接并释放ADO对象
    Rst.Close: Set Rst = Nothing 查询v2.rar (1.63 MB, 下载次数: 7)
    Conn.Close: Set Conn = Nothing

    SQuery = SQueryValue
End Function


详情请下载附件查看:

评分

1

查看全部评分

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

本版积分规则

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

GMT+8, 2024-11-26 07:50 , Processed in 0.055811 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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