ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 常用工具系列之一(自动查询)

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2009-11-22 20:48 | 显示全部楼层 |阅读模式
隐藏跟帖

【开发初衷】
1、查询是Excel使用者用得最多的功能之一;
2、让更多的初学者不会查询函数也可以用查询功能;
3、当数据量比较大时提高效率;
4、多条件查询;
5、多列结果查询;
6、多条件和多列结果查询;

基于以上这些问题,特开发此工具,希望这个工具能给大家在工作生活中带来力所能及的帮助,这也是我们希望看到的。

【预览和简介】:
第一版:

主界面预览图

主界面预览图

第二版:移动有两种形式,请大家议议哪个比较好。
Snap1.jpg
Snap2.jpg
Snap3.jpg
自动查询_演示.gif
【试用下载】:
常用工具6.0版.rar (197.73 KB, 下载次数: 6872)
见附件里的字典查询,

2003加载宏下载地址:http://club.excelhome.net/viewth ... ;page=18#pid3423818

【开发团队】:
主创人员:彭希仁(彭希遴)
团队成员:little-key(梁才)


【更新日志】:
2009年11月22日
快速查询;
自定义忽略标题行;

注:
+ 表示增加功能
- 表示减少功能
* 表示修改功能
# 表示优化功能


[ 本帖最后由 little-key 于 2009-12-30 00:28 编辑 ]

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-11-22 20:49 | 显示全部楼层
【使用说明】
一、结果为单列的查询
单列查询.gif
二、结果为多列的查询
结果为多列.gif
三、条件为单列的查询
条件为单列.gif
四、条件为多列的查询
多条件查询.gif
五、忽略标题的查询
忽略标题查询.gif
六、横向查询
横向查询.gif
七、向左查询
向左查询.gif

[ 本帖最后由 little-key 于 2009-11-22 22:18 编辑 ]

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-11-22 20:50 | 显示全部楼层
【开发过程】
一:界面设计





二、代码设计
(1)工作表代码
如果需要使用快捷启动(建议),则请在ThisWorkbook中添加以下代码:
  1. Private Sub Workbook_Open()
  2.     On Error Resume Next
  3.     Application.OnKey "^w", "右键字典"
  4. End Sub
复制代码
(2)窗体代码
  1. Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
  2. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  3. Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  4. Private Const GWL_STYLE = (-16)
  5. Private Const WS_THICKFRAME As Long = &H40000
  6. Private Const WS_MINIMIZEBOX As Long = &H20000
  7. Private Const WS_MAXIMIZEBOX As Long = &H10000

  8. Private Sub CheckBox1_Click()
  9.     On Error GoTo ren
  10.     If CheckBox1.Value = False And ref(1) <> "" Then
  11.         Set myc.sht = Nothing
  12.         Set myc = Nothing
  13.         ref(1) = ""
  14.         ref(5) = ""
  15.         ref(6) = ""
  16.         ref(7) = ""
  17.         ref(8) = ""
  18.         ref(9) = ""
  19.         ref(2) = ""
  20.         ref(3) = ""
  21.         Set ref(4) = Nothing
  22.     End If
  23. ren:
  24. End Sub

  25. Private Sub CheckBox2_Click()

  26. End Sub

  27. Private Sub CheckBox3_Click()
  28.     If CheckBox3.Value Then
  29.         ref(10) = 0
  30.     Else
  31.         ref(10) = 1
  32.     End If
  33. End Sub

  34. Private Sub CommandButton2_Click()
  35.     RefEdit2.Text = ""
  36.     RefEdit1.Text = ""
  37.     RefEdit3.Text = ""
  38.     RefEdit4.Text = ""
  39. End Sub

  40. Private Sub CommandButton3_Click()
  41.     Unload Me
  42. End Sub

  43. Private Sub RefEdit1_BeforeDragOver(Cancel As Boolean, ByVal Data As MSForms.DataObject, ByVal x As stdole.OLE_XPOS_CONTAINER, ByVal y As stdole.OLE_YPOS_CONTAINER, ByVal DragState As MSForms.fmDragState, Effect As MSForms.fmDropEffect, ByVal Shift As Integer)

  44. End Sub

  45. Private Sub RefEdit3_Change()
  46.     On Error GoTo ren
  47.     If RefEdit1.Text <> "" Then
  48.         If Range(RefEdit1.Text).Rows.Count < Range(RefEdit1.Text).Columns.Count Then OptionButton2.Value = True
  49.     End If
  50. ren:
  51. End Sub

  52. Private Sub UserForm_Activate()
  53.     If ref(10) = 1 Then
  54.         RefEdit2.Text = ""
  55.         RefEdit1.Text = ""
  56.         RefEdit3.Text = ""
  57.         RefEdit4.Text = ""
  58.     End If

  59.     If ref(10) = "" Then
  60.         CheckBox3.Value = False  '如果启动默认为勾选的话,则修改为True
  61.         ref(10) = 1    '如果启动默认为勾选的话,则删除此句
  62.     ElseIf ref(10) = 0 Then
  63.         CheckBox3.Value = True
  64.     Else
  65.         CheckBox3.Value = False
  66.     End If
  67. End Sub

  68. Private Sub UserForm_Initialize()
  69.     Dim hWndForm As Long
  70.     Dim IStyle As Long
  71.     hWndForm = FindWindow("ThunderDFrame", Me.Caption)
  72.     IStyle = GetWindowLong(hWndForm, GWL_STYLE)
  73.     IStyle = IStyle Or WS_THICKFRAME
  74.     IStyle = IStyle Or WS_MINIMIZEBOX
  75.     IStyle = IStyle Or WS_MAXIMIZEBOX
  76.     SetWindowLong hWndForm, GWL_STYLE, IStyle
  77.     OptionButton1.Value = 1

  78.     RefEdit2.Text = ref(1)
  79.     RefEdit1.Text = ref(5)
  80.     RefEdit3.Text = ref(6)
  81.     RefEdit4.Text = ref(7)

  82.     If ref(7) = 1 Then
  83.         OptionButton2.Value = 1
  84.     Else
  85.         OptionButton1.Value = 1
  86.     End If
  87.     CommandButton3.Top = Me.Height + 1
  88. End Sub

  89. Private Sub CommandButton1_Click()
  90.     On Error Resume Next
  91.     Dim R1, R2, R3
  92.     If OptionButton2.Value = True Then
  93.         Call Hlkup
  94.         Exit Sub
  95.     End If
  96.     Dim d1 As New Dictionary
  97.     R1 = RefEdit1.Text  '字典的目录
  98.     Call xinz(R1)

  99.     R2 = RefEdit2.Text    '需要查找的目录
  100.     Call xinz(R2)

  101.     R3 = RefEdit3.Text  '字典的内容
  102.     Call xinz(R3)
  103.     Arr = Range(R1)

  104.     If CheckBox2.Value = False Then
  105.         For i = 1 To UBound(Arr, 2)
  106.             For J = 1 To UBound(Arr)
  107.                 Arr(J, i) = LCase(Arr(J, i))
  108.             Next J
  109.         Next i
  110.     End If


  111.     If R1 Like "*!*" Then
  112.         a = Split(R1, "!")(0)
  113.         If a Like ("*'*") Then a = Split(a, "'")(1)
  114.     Else
  115.         a = ActiveWorkbook.Name
  116.     End If
  117.     arr1 = Sheets(a).Cells(Range(R1).Row, Range(R3).Column).Resize(UBound(Arr), Range(R3).Columns.Count)


  118.     '建立字典
  119.     x = UBound(Arr, 2)
  120.     For i = 1 To UBound(Arr)
  121.         a = ""
  122.         For J = 1 To x
  123.             a = a & "♀" & Arr(i, J)
  124.         Next J
  125.         If Not d1.Exists(a) Then d1(a) = i
  126.     Next i

  127.     arr2 = Application.Intersect(Range(R2), Range(R2).Offset(Abs(CheckBox4 + 0), 0))

  128.     If CheckBox2.Value = False Then
  129.         For i = 1 To UBound(arr2, 2)
  130.             For J = 1 To UBound(arr2)
  131.                 arr2(J, i) = LCase(arr2(J, i))
  132.             Next J
  133.         Next i
  134.     End If

  135.     ReDim arr3(1 To UBound(arr2), 1 To UBound(arr1, 2))
  136.     x = UBound(arr2, 2)
  137.     y = UBound(arr1, 2)
  138.     For i = 1 To UBound(arr2)
  139.         a = ""
  140.         For J = 1 To x
  141.             a = a & "♀" & arr2(i, J)
  142.         Next J
  143.         If d1.Exists(a) Then
  144.             For J = 1 To y
  145.                 arr3(i, J) = arr1(d1(a), J)
  146.             Next J
  147.         End If
  148.     Next i
  149.     If RefEdit4.Text Like "*!*" Then
  150.         a = Split(RefEdit4.Text, "!")(0)
  151.         If a Like ("*'*") Then a = Split(a, "'")(1)
  152.     Else
  153.         a = ActiveWorkbook.Name
  154.     End If

  155.     Sheets(a).Cells(Range(R2).Row + Abs(CheckBox4 + 0), Range(RefEdit4.Text).Column).Resize(UBound(arr3), UBound(arr3, 2)) = arr3

  156.     If CheckBox1.Value = True Then
  157.         Set myc = New csh
  158.         Set myc.sht = ActiveSheet
  159.         ref(1) = RefEdit2.Text
  160.         ref(5) = RefEdit1.Text
  161.         ref(6) = RefEdit3.Text
  162.         ref(7) = RefEdit4.Text
  163.         ref(8) = 0
  164.         ref(9) = CheckBox2.Value
  165.         ref(2) = arr1
  166.         ref(3) = Range(RefEdit4.Text).Column
  167.         Set ref(4) = d1
  168.     End If
  169.     Me.hide
  170.     Exit Sub
  171. ren:
  172.     MsgBox ("出错")
  173. End Sub


  174. Sub Hlkup()
  175.     On Error Resume Next
  176.     ' Set d1 = CreateObject("Scripting.Dictionary")
  177.     Dim d1 As New Dictionary
  178.     R1 = RefEdit1.Text
  179.     Call xinz(R1)

  180.     R2 = RefEdit2.Text
  181.     Call xinz(R2)

  182.     R3 = RefEdit3.Text
  183.     Call xinz(R3)

  184.     Arr = Range(R1)
  185.     If CheckBox2.Value = False Then
  186.         For i = 1 To UBound(Arr, 2)
  187.             For J = 1 To UBound(Arr)
  188.                 Arr(J, i) = LCase(Arr(J, i))
  189.             Next J
  190.         Next i
  191.     End If

  192.     If RefEdit1.Text Like "*!*" Then
  193.         a = Split(R1, "!")(0)
  194.         If a Like ("*'*") Then a = Split(a, "'")(1)
  195.     Else
  196.         a = ActiveWorkbook.Name
  197.     End If
  198.     arr1 = Sheets(a).Cells(Range(R3).Row, Range(R1).Column).Resize(Range(R3).Rows.Count, UBound(Arr, 2))
  199.     '建立字典
  200.     x = UBound(Arr)
  201.     For i = 1 To UBound(Arr, 2)
  202.         a = ""
  203.         For J = 1 To x
  204.             a = a & "♀" & Arr(J, i)
  205.         Next J
  206.         If Not d1.Exists(a) Then d1(a) = i
  207.     Next i
  208.     arr2 = Range(R2)
  209.     If CheckBox2.Value = False Then
  210.         For i = 1 To UBound(arr2, 2)
  211.             For J = 1 To UBound(arr2)
  212.                 arr2(J, i) = LCase(arr2(J, i))
  213.             Next J
  214.         Next i
  215.     End If
  216.     ReDim arr3(1 To UBound(arr1), 1 To UBound(arr2, 2))
  217.     x = UBound(arr2)
  218.     y = UBound(arr1)
  219.     For i = 1 To UBound(arr2, 2)
  220.         a = ""
  221.         For J = 1 To x
  222.             a = a & "♀" & arr2(J, i)
  223.         Next J
  224.         If d1.Exists(a) Then
  225.             For J = 1 To y
  226.                 arr3(J, i) = arr1(J, d1(a))
  227.             Next J
  228.         End If
  229.     Next i
  230.     If RefEdit4.Text Like "*!*" Then
  231.         a = Split(RefEdit4.Text, "!")(0)
  232.         If a Like ("*'*") Then a = Split(a, "'")(1)
  233.     Else
  234.         a = ActiveWorkbook.Name
  235.     End If
  236.     Sheets(a).Cells(Range(RefEdit4.Text).Row, Range(R2).Column).Resize(UBound(arr3), UBound(arr3, 2)) = arr3

  237.     If CheckBox1.Value = True Then
  238.         Set myc = New csh
  239.         Set myc.sht = ActiveSheet
  240.         ref(1) = RefEdit2.Text
  241.         ref(5) = RefEdit1.Text
  242.         ref(6) = RefEdit3.Text
  243.         ref(7) = RefEdit4.Text
  244.         ref(8) = 1
  245.         ref(9) = CheckBox2.Value
  246.         ref(2) = arr1
  247.         ref(3) = Range(RefEdit4.Text).Row
  248.         Set ref(4) = d1
  249.     End If
  250.     Me.hide
  251.     Exit Sub
  252. ren:
  253.     MsgBox ("出错")
  254. End Sub

  255. Sub xinz(a)  '确定选择区域的最佳区域,特别是选择整列时
  256.     Dim i As Long
  257.     Dim J As Long
  258.     Dim z As Long
  259.     Dim x
  260.     Dim y
  261.     Dim arr1, n
  262.     On Error GoTo ren
  263.     If a = "" Then Exit Sub
  264.     arr1 = Split(a, "$")
  265.     If UBound(arr1) = 0 Then Exit Sub
  266.     If arr1(1) Like "*:" Then
  267.         a = arr1(0)
  268.         If arr1(0) Like ("*'*") Then
  269.             arr1(0) = Split(a, "'")(1) & "!"
  270.         End If
  271.         If IsNumeric(Mid(arr1(1), 1, Len(arr1(1)) - 1)) Then
  272.             y = Sheets(Mid(arr1(0), 1, Len(arr1(0)) - 1)).UsedRange.Column
  273.             x = Sheets(Mid(arr1(0), 1, Len(arr1(0)) - 1)).UsedRange.Columns.Count + y - 1
  274.             y = Split(Cells(1, y).Address, "$")(1)
  275.             x = Split(Cells(1, x).Address, "$")(1)
  276.             z = Sheets(Mid(arr1(0), 1, Len(arr1(0)) - 1)).UsedRange.Rows.Count
  277.             n = arr1(2)
  278.             If z < n Then arr1(2) = z
  279.             a = a & "$" & y & "$" & arr1(1) & "$" & x & "$" & arr1(2)
  280.         Else
  281.             a = a & "$" & Mid(arr1(1), 1, Len(arr1(1)) - 1) & "$" & "1:$" & arr1(2) & "$" & Sheets(Mid(arr1(0), 1, Len(arr1(0)) - 1)).UsedRange.Rows.Count
  282.         End If
  283.     Else
  284.         If IsNumeric(arr1(2)) And UBound(arr1) = 2 Then Exit Sub
  285.     End If
  286.     Exit Sub
  287. ren:
  288.     MsgBox ("出错")
  289. End Sub

  290. Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  291.     On Error Resume Next
  292.     If KeyCode = 27 Then Unload Me
  293. End Sub
复制代码
(3)模块代码
  1. Public myc, ref(1 To 10)    '此句代码为字典查询专用
复制代码
(4)类模块代码
1、csh
  1. Public WithEvents sht As Worksheet
  2. Private Sub sht_Change(ByVal Target As Range)
  3.     On Error GoTo ren
  4.     If ref(8) = 1 Then
  5.         x = Range(ref(1)).Row
  6.         y = Range(ref(1)).Column
  7.         xx = x - 1 + Range(ref(1)).Rows.Count
  8.         yy = y - 1 + Range(ref(1)).Columns.Count
  9.         x1 = Target.Row
  10.         y1 = Target.Column
  11.         If Not (x1 >= x And y1 >= y And x1 <= xx And y1 <= yy) Then Exit Sub
  12.         z = Target.Columns.Count
  13.         If z > 1 Then
  14.             arr2 = Range(Cells(x, y1), Cells(xx, y1 + z - 1))
  15.             If ref(9) = False Then
  16.                 For i = 1 To UBound(arr2, 2)
  17.                     For J = 1 To UBound(arr2)
  18.                         arr2(J, i) = LCase(arr2(J, i))
  19.                     Next J
  20.                 Next i
  21.             End If
  22.             ReDim arr3(1 To UBound(ref(2)), 1 To z)
  23.             For J = 1 To z
  24.                 a = ""
  25.                 For i = 1 To xx - x + 1          '建立
  26.                     a = a & "♀" & arr2(i, J)
  27.                 Next i

  28.                 If Not ref(4).Exists(a) Then
  29.                     For i = 1 To UBound(ref(2))
  30.                         arr3(i, J) = ""
  31.                     Next i
  32.                 Else
  33.                     For i = 1 To UBound(ref(2))
  34.                         arr3(i, J) = ref(2)(i, ref(4)(a))
  35.                     Next i
  36.                 End If
  37.             Next J
  38.             Cells(ref(3), y1).Resize(UBound(arr3), UBound(arr3, 2)) = arr3
  39.         Else
  40.             For i = x To xx              '建立
  41.                 If ref(9) = False Then
  42.                     a = a & "♀" & LCase(Cells(i, y1).Value)
  43.                 Else
  44.                     a = a & "♀" & Cells(i, y1).Value
  45.                 End If

  46.             Next i

  47.             If Not ref(4).Exists(a) Then
  48.                 For i = 1 To UBound(ref(2), 2)
  49.                     Cells(ref(3) - 1 + i, y1) = ""
  50.                 Next i
  51.             Else
  52.                 For i = 1 To UBound(ref(2))
  53.                     Cells(ref(3) - 1 + i, y1) = ref(2)(i, ref(4)(a))
  54.                 Next i
  55.             End If
  56.         End If

  57.     Else
  58.         x = Range(ref(1)).Row
  59.         y = Range(ref(1)).Column
  60.         xx = x - 1 + Range(ref(1)).Rows.Count
  61.         yy = y - 1 + Range(ref(1)).Columns.Count
  62.         x1 = Target.Row
  63.         y1 = Target.Column
  64.         If Not (x1 >= x And y1 >= y And x1 <= xx And y1 <= yy) Then Exit Sub
  65.         z = Target.Rows.Count
  66.         If z > 1 Then
  67.             arr2 = Range(Cells(x1, y), Cells(x1 + z - 1, yy))
  68.             If ref(9) = False Then
  69.                 For i = 1 To UBound(arr2, 2)
  70.                     For J = 1 To UBound(arr2)
  71.                         arr2(J, i) = LCase(arr2(J, i))
  72.                     Next J
  73.                 Next i
  74.             End If
  75.             ReDim arr3(1 To z, 1 To UBound(ref(2), 2))
  76.             For J = 1 To z
  77.                 a = ""
  78.                 For i = 1 To yy - y + 1          '建立
  79.                     a = a & "♀" & arr2(J, i)
  80.                 Next i
  81.                 If Not ref(4).Exists(a) Then
  82.                     For i = 1 To UBound(ref(2), 2)
  83.                         arr3(J, i) = ""
  84.                     Next i
  85.                 Else
  86.                     For i = 1 To UBound(ref(2), 2)
  87.                         arr3(J, i) = ref(2)(ref(4)(a), i)
  88.                     Next i
  89.                 End If
  90.             Next J
  91.             Cells(x1, ref(3)).Resize(UBound(arr3), UBound(arr3, 2)) = arr3
  92.         Else
  93.             For i = y To yy              '建立
  94.                 If ref(9) = False Then
  95.                     a = a & "♀" & LCase(Cells(x1, i).Value)
  96.                 Else
  97.                     a = a & "♀" & Cells(x1, i).Value
  98.                 End If
  99.             Next i
  100.             If Not ref(4).Exists(a) Then
  101.                 For i = 1 To UBound(ref(2), 2)
  102.                     Cells(x1, ref(3) - 1 + i) = ""
  103.                 Next i
  104.             Else
  105.                 For i = 1 To UBound(ref(2), 2)
  106.                     Cells(x1, ref(3) - 1 + i) = ref(2)(ref(4)(a), i)
  107.                 Next i
  108.             End If
  109.         End If
  110.     End If
  111.     Exit Sub
  112. ren:
  113.     '   Set myc.sht = Nothing
  114.     '  Set myc = Nothing
  115.     '  MsgBox ("出错")
  116. End Sub
复制代码
2、css
  1. Public WithEvents sht As Worksheet
  2. Private Sub sht_Change(ByVal Target As Range)
  3. On Error GoTo ren
  4.     Set yunx.sht = Nothing
  5.     Set yunx = Nothing
  6.     Set S = CreateObject("MSScriptControl.ScriptControl")
  7.     S.Language = "VBScript"
  8.     S.AddObject "ActiveWorkbook", ActiveWorkbook
  9.     S.AddObject "Application", Application
  10.     S.AddObject "Activesheet", ActiveSheet
  11.     S.AddObject "sheets", Sheets
  12.     S.AddObject "cells", Cells
  13.     S.addcode yunxi
  14.     S.Run "xi"
  15.     S.Reset
  16. ren:
  17. End Sub
复制代码

[ 本帖最后由 little-key 于 2009-11-22 21:33 编辑 ]

TA的精华主题

TA的得分主题

发表于 2009-11-22 21:20 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
我路过的。,来学习一下

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-11-22 21:23 | 显示全部楼层
希望大家多提一些修改或完善的意见,你们的需要,就是我们的需求,软件完善需要大伙的支持。

TA的精华主题

TA的得分主题

发表于 2009-11-22 21:40 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
主要用于哪些情况之下呢,
BS自已一下,在大师的面前,提出这样的问题,再 汗一个

TA的精华主题

TA的得分主题

发表于 2009-11-22 21:41 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2009-11-22 21:57 | 显示全部楼层
谢谢两位版主的分享,试用一下先

TA的精华主题

TA的得分主题

发表于 2009-11-22 23:04 | 显示全部楼层
感觉很好,学习了。谢谢分享。

TA的精华主题

TA的得分主题

发表于 2009-11-22 23:21 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-18 17:34 , Processed in 0.042268 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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