Board logo

標題: VBA 資料搜尋問題 [打印本頁]

作者: Qin    時間: 2018-7-1 18:22     標題: VBA 資料搜尋問題

我有一個龐大的資料庫(資料已超出65536筆),因為 Excel 的公式已經不能滿足我的需求, 所以想以 VBA 解決問題

     請問當我想以"編號"或者以"品名"再或者想以"廠商"搜尋資料, 這時 VBA 的語法要如何撰寫?
     (當然這3個問題不是同一時間一起進行)

     [attach]28902[/attach]
作者: Qin    時間: 2018-7-1 21:34

回復 1# Qin

   補充

[attach]28903[/attach]
作者: ikboy    時間: 2018-7-2 21:44

Dim d As Object, k, t, s$
  1. Private Sub Worksheet_Activate()
  2. If d Is Nothing Then dic
  3. End Sub
複製代碼
  1. Private Sub Worksheet_Change(ByVal Target As Range)
  2. Application.EnableEvents = 0
  3. Set td = Application.Intersect([b1:b3], Target)
  4. If Not td Is Nothing Then
  5.     If Len(td.Value) Then
  6.         k = td.Value: [b1:b3] = "": td.Value = k
  7.         a = Array("CD#", "DC#", "CO#")
  8.         k = a(td.Row - 1) & td.Value
  9.         ar = Sheets("資料庫").[a1].CurrentRegion.Value
  10.         If d Is Nothing Then dic
  11.         t = Split(d(k), "|")
  12.         ReDim b(1 To UBound(t), 1 To UBound(ar, 2))
  13.         For i = 1 To UBound(t)
  14.             b(i, 1) = i
  15.             For j = 2 To UBound(ar, 2)
  16.                 b(i, j) = ar(t(i), j)
  17.             Next
  18.         Next
  19.         [a5].CurrentRegion.Offset(4).Clear
  20.         [a5].Resize(i - 1, j - 1) = b
  21.     End If
  22. End If
  23. Application.EnableEvents = 1
  24. End Sub
複製代碼
  1. Sub dic()
  2. Set d = CreateObject("scripting.dictionary")
  3. ar = Sheets("資料庫").[a1].CurrentRegion.Value
  4. For i = 2 To UBound(ar)
  5.     d("CO#" & ar(i, 4)) = d("CO#" & ar(i, 4)) & "|" & i
  6.     d("CD#" & ar(i, 6)) = d("CD#" & ar(i, 6)) & "|" & i
  7.     d("DC#" & ar(i, 7)) = d("DC#" & ar(i, 7)) & "|" & i
  8. Next
  9. For Each t In Array("CD#", "DC#", "CO#")
  10.     k = Filter(d.keys, t): s = ""
  11.     For i = 0 To UBound(k)
  12.         k(i) = Replace(k(i), t, "")
  13.     Next
  14.     For i = 0 To UBound(k) - 1
  15.         For j = i + 1 To UBound(k)
  16.             If k(j) < k(i) Then t = k(i): k(i) = k(j): k(j) = t
  17.         Next
  18.     Next
  19.     n = n + 1
  20.     With Range("b" & n).Validation
  21.         .Delete
  22.         .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
  23.         xlBetween, Formula1:=Join(k, ",")
  24.     End With
  25. Next
  26. End Sub
複製代碼

作者: Farnsworth    時間: 2018-7-3 11:13

一直在学习中,下载看看,感谢分享你的技术与经验,谢谢!!!
作者: Qin    時間: 2018-7-4 23:29

回復 3# ikboy


首先, 謝謝 ikboy 的幫助,接下來, 還有2個問題,可否請你抽空幫我看看…. 在此謝過.
作者: ikboy    時間: 2018-7-5 09:36

加一句AntoFilter不是更好作關聯嗎。
  1. Private Sub Worksheet_Change(ByVal Target As Range)
  2. Application.EnableEvents = 0
  3. Dim td As Range, a, ar, i&, j&
  4. Set td = Application.Intersect([b1:b3], Target)
  5. If Not td Is Nothing Then
  6.     If Len(td.Value) Then
  7.         k = td.Value: [b1:b3] = "": td.Value = k
  8.         a = Array("CD#", "DC#", "CO#")
  9.         k = a(td.Row - 1) & td.Value
  10.         ar = Sheets("Data").[a1].CurrentRegion.Value
  11.         If d Is Nothing Then dic
  12.         t = Split(d(k), "|")
  13.         ReDim b(1 To UBound(t), 1 To UBound(ar, 2))
  14.         For i = 1 To UBound(t)
  15.             b(i, 1) = i
  16.             For j = 2 To UBound(ar, 2)
  17.                 b(i, j) = ar(t(i), j)
  18.             Next
  19.         Next
  20.         [a5].CurrentRegion.Offset(4).Clear
  21.         [a5].Resize(i - 1, j - 1) = b
  22.         [color=Red][a4:j4].AutoFilter[/color]
  23.     End If
  24. End If
  25. Application.EnableEvents = 1
  26. End Sub
複製代碼

作者: Qin    時間: 2018-7-7 22:29

回復 6# ikboy

為何不能運行? 請問, 是問題什麼?
[attach]28934[/attach]
   

[attach]28935[/attach]
作者: faye59    時間: 2018-7-12 05:42

回復 1# Qin


   
提供兩個版本給你,看看適不適用。
作者: faye59    時間: 2018-7-12 07:51

回復 8# faye59


    搜尋資料1.xlsm
  1. Cells(NextRow, 1) = n
複製代碼
這段沒改到,這麻煩自行修正。
Thanks!
作者: Kubi    時間: 2018-7-14 19:57

回復 1# Qin
請參考
[attach]28980[/attach]
作者: Qin    時間: 2018-7-15 15:27

回復 8# faye59

由於是 VBA 菜鳥的關係, 雖然,一直以來也有看看各路高手在此論壇的貼文,
如: GBKEE 版主用心的在程序碼上寫上註解. 也許,不是自己發出的提問, 看後也是似懂非懂.

你所上載2篇程式碼, 由於我的電腦是英文系統, 皆屬亂碼.
在此希望你能將這2篇程式碼貼在留言版上.讓我可以解讀並收下研究. 謝謝!!


[attach]28990[/attach]
   



我心存迷惘, 因為對 VBA 的一知半解, 當我在網上發問時, 我遇到了一群熱心幫助我的人.
作者: Qin    時間: 2018-7-15 15:39

回復 10# Kubi

你上載的範圍物件法, 非常適用.

如果可以, 可否幫我修改以下2個問題...
1)        Data (資料庫)里的資料如果是日期由遠至今. ( 22/05/2015 -  22/05/2017) 希望VB 搜尋結果呈現的是由今至遠.
2)        Search (搜尋) 里的 Row 4 可否增加 Filter, 方便在搜尋后, 可以進一步篩選. (如: 薯條, 薯泥, 薯片)

P/s: 由於亂碼的關係, 你上載的"列陣法”我不能完全的解讀, 可否也請你將它貼在留言板上.  無限感激.
作者: faye59    時間: 2018-7-15 19:39

回復 11# Qin


   
搜尋資料.xlsm
  1. Sub 搜尋表單()
  2. Dim F1, F2 As Variant
  3. F1 = Sheets("搜尋").Range("B1")
  4. Sheets("搜尋").Select
  5. Sheets("搜尋").Range([A3], [J3].End(xlDown)) = ""
  6. If F1 = "" Then

  7. MsgBox "您未輸入條件"
  8. Exit Sub
  9. End If

  10. For I = 2 To Sheets("資料庫").UsedRange.Rows.Count
  11. If Sheets("資料庫").Cells(I, 4) = F1 Or Sheets("資料庫").Cells(I, 6) = F1 Or Sheets("資料庫").Cells(I, 7) = F1 Then
  12. Worksheets("資料庫").Range("A" & I, "J" & I).Copy Destination:=Worksheets("搜尋").Range("A" & Application.CountA(Sheets("搜尋").Columns("A:A")) + 1)
  13. End If
  14. Next I

  15. MsgBox "您輸入" & "條件" & "[ " & F1 & " ]" & "共計" & Application.CountA(Sheets("搜尋").Columns("A:A")) - 2 & "筆資料"

  16. End Sub
複製代碼
搜索資料1
  1. Sub Serach()
  2. Application.DisplayAlerts = False
  3. Application.ScreenUpdating = False
  4. Dim a, b, c As String
  5. Dim f1, f2, f3 As Workbook

  6. Set f1 = Sheets("資料庫")
  7. Set f2 = Sheets("搜尋資料")
  8. a = Application.InputBox("請輸入查詢的項目代碼:1.公司 2.編號 3.品名", "輸入搜尋項目")
  9. b = Application.InputBox("請輸入查詢的內容名稱", "輸入搜尋內容")
  10. If a = "" Or a = False Or b = "" Or b = False Then
  11. Exit Sub
  12. Else
  13. Select Case a
  14. Case "1"
  15.     X = 3
  16. Case "2"
  17.     X = 5
  18. Case "3"
  19.     X = 6
  20. Case Else
  21. Exit Sub
  22. End Select
  23. f1.Select
  24. For Each aa In Range([A2], [A2].End(xlDown))
  25. If aa.Offset(, X) = b Then
  26.     f2.Select
  27.     n = n + 1
  28.     NextRow = Cells(Rows.Count, 2).End(xlUp).Row + 1
  29.     Cells(NextRow, 1) = n
  30.     Cells(NextRow, 2).Resize(1, 9) = aa.Offset(0, 1).Resize(1, 9).Value
  31.     Cells(NextRow, 15).Resize(1, 1) = aa.Offset(0, 0).Resize(1, 1).Value
  32. End If
  33. Next
  34. End If
  35. f2.Cells(1, 15) = "total: " & Application.CountA(f2.Range("A:A")) - 1
  36. f2.Select
  37. Application.DisplayAlerts = True
  38. Application.ScreenUpdating = True
  39. End Sub
複製代碼
  1. Sub clase()
  2. [A3:O60000] = ""
  3. [O1] = "total: 0"
  4. End Sub
複製代碼

作者: Kubi    時間: 2018-7-15 20:28

回復 12# Qin
Q1:希望VB 搜尋結果呈現的是由今至遠。
A1:已加寫了,如附件。

Q2:方便在搜尋后, 可以進一步篩選。
A2:不曾寫過這種方式,還是請其他前輩幫忙吧。

陣列的程式碼已加註,請參考:
  1. Private Sub Worksheet_Change(ByVal Target As Range)
  2.     Dim arr     '宣告arr為靜態陣列
  3.     Dim brr()   '宣告brr為動態陣列
  4.     If Target.Count <> 1 Then Exit Sub  '假如Change的儲存格數量不是1個的話退出程序
  5.     If Intersect(Target, [B1:B3]) Is Nothing Then Exit Sub      '假如Change的儲存格不是位於B1:B3儲存格中的任一個的話退出程序
  6.     If Target.Value = "" Then       '假如Change的儲存格的值是空值得話(被User按了Delete鍵)時....
  7.         Application.EnableEvents = False        '取消觸發事件避免因底下的Delete而再次觸發此Change事件
  8.         Rows("4:" & Cells.Rows.Count).Delete    '刪除第4列至最底列的舊資料
  9.         Application.EnableEvents = True     '恢復觸發事件
  10.         Exit Sub    '退出程序
  11.     End If
  12.     ar = Array(6, 7, 4)     '將6, 7, 4等關鍵欄位存入ar陣列中
  13.     arr = Sheets("Data").Range("A2:J" & Sheets("Data").[A1].End(4).Row)     '將Data工作表內的A2至J欄有資料的最底列存入arr靜態陣列中
  14.     n = 0   'n值存入0
  15.     For i = 1 To UBound(arr)    '從1至 arr 1維的最大下標值作為迴圈
  16.         If arr(i, ar(Target.Row - 1)) = Target.Value Then   '假如靜態陣列arr中的列i及ar陣列中欄的資料等於Change的儲存格的資料時....
  17.             n = n + 1   'n的值加1
  18.             ReDim Preserve brr(1 To 10, 1 To n)     '重新宣告動態陣列brr的一、二維上、下標的數組,以準備存入底下迴圈的資料
  19.             For j = 1 To 10     '因Data欄位總共為10欄,因此迴圈10次來讀取該arr內符合列的資料,存入動態陣列的brr內
  20.                 brr(j, n) = arr(i, j)   '將上述狀況存入值
  21.             Next j
  22.         End If
  23.     Next i
  24.     If n = 0 Then   '假如上述迴圈都找不到資料時....
  25.         MsgBox "於資料庫中並無符合搜尋條件∼", vbCritical + vbOKOnly, "請注意"      '彈出訊息警告
  26.         Exit Sub    '退出程序
  27.     End If
  28.     Application.EnableEvents = False    '取消觸發事件
  29.     For i = 1 To 3  '此迴圈主要處理B1:B3儲存格內的殘存資料
  30.         If Cells(i, 2).Address <> Target.Address Then Cells(i, 2).Value = ""    '假如B1:B3儲存格內不是Change的儲存格,則刪除資料
  31.     Next i
  32.     Application.ScreenUpdating = False      '將螢幕凍結,以減少畫面的跳動
  33.     Rows("4:" & Cells.Rows.Count).Delete    '刪除第4列至最底列的舊資料
  34.    
  35.     [A4].Resize(n, 10) = Application.Transpose(brr) '將存入brr的值轉置後放入以A4儲存格展延n列,10欄的範圍內
  36.     '注意上面的Transpose,因VBA最多只能轉置65536列資料,多了就會產生錯誤,我用的2010版,之後的版本是否有更新不得而知。
  37.    
  38.     Application.ScreenUpdating = False  '取消螢幕凍結
  39.     Application.EnableEvents = True         '恢復觸發事件
  40. End Sub
複製代碼
[attach]28992[/attach]
作者: Qin    時間: 2018-7-18 21:11

回復 14# Kubi


    有疑問, 再次勞煩....

    [attach]29002[/attach]
作者: Kubi    時間: 2018-7-19 20:35

回復 15# Qin

請參考
[attach]29010[/attach]
作者: Qin    時間: 2018-7-19 22:15

回復 16# Kubi


    謝謝....
作者: Qin    時間: 2018-7-19 23:17

本帖最後由 Qin 於 2018-7-19 23:19 編輯

回復 16# Kubi



     再次勞煩..
     當我使用 filter 篩選後, 沒有還原, 接下來再搜尋資料, 就會 Debug
  
     [attach]29014[/attach]
     [attach]29015[/attach]
作者: Kubi    時間: 2018-7-20 20:10

回復 18# Qin

試看看
[attach]29028[/attach]
作者: Qin    時間: 2018-7-22 00:00

本帖最後由 Qin 於 2018-7-22 00:06 編輯

回復 19# Kubi


    可以了... Thanks
作者: a5007185    時間: 2018-7-25 18:03

回復 20# Qin

如果不吝嗇的話,
這個也給你參考!

    [attach]29065[/attach]
作者: Qin    時間: 2018-8-30 20:42

回復 21# a5007185


    謝謝, 熱心分享
作者: Qin    時間: 2018-8-30 20:46

回復 14# Kubi

  請教, 如果 Data 目前又增加多一頁,  Data 1, 又或者好幾頁, 那語法又要如何修改?

    [attach]29301[/attach]
作者: Kubi    時間: 2018-8-31 21:18

回復 23# Qin
請參考
[attach]29309[/attach]
作者: Qin    時間: 2018-9-3 23:33

回復 24# Kubi

    Kubi
   
   不懂是不是我的 Data 太多了

   Data & Data 1 加起來共有8萬多筆

   所以在搜尋過程中, 有時可以, 有時又不可以

   原本想將附檔上傳給你看. 但文件太大了(7MB), 不可以上傳
   
    想問, 你給我最后的語法, 是否超出6萬筆, 就搜尋不到?
作者: Kubi    時間: 2018-9-5 10:04

回復 25# Qin
原先設計不知會用到那麼多的資料,已修改程式碼。
模擬10萬筆資料大約1秒內能搜尋完成。
因上傳檔案大小限制,而無法將模擬的10萬筆資料上傳。
請參考。
[attach]29343[/attach]
作者: Qin    時間: 2018-9-6 23:58

本帖最後由 Qin 於 2018-9-7 00:05 編輯

回復 26# Kubi

   首先,謝謝你抽空幫我修改程式碼
   搜尋資料的速度的確非常的快.

   原本,我想在 Data & Data1 的 K 欄里再添多1欄資料.
   但是, 有一個我不明白的地方,為何我找不到" Temp" File, 感覺很神奇.
   在不得要領的情況下,再次請你指點迷津.
   謝謝!
作者: Kubi    時間: 2018-9-10 20:15

回復 27# Qin
請查閱ThisWorkbook模組便知。
作者: 准提部林    時間: 2018-9-13 11:52

以〔雙按滑鼠左鍵〕執行,可〔單條件〕或〔多條件〕搜尋:
[attach]29388[/attach]
作者: Qin    時間: 2018-9-14 00:45

回復 29# 准提部林

   由於亂碼的關係,  可否請你將語法貼在留言板上.謝謝!
作者: Qin    時間: 2018-9-14 00:51

本帖最後由 Qin 於 2018-9-14 01:01 編輯

回復 28# Kubi
   哎呀! 腦袋卡住了, 忘了模組..
    幸好以上問題解決了.

    在"temp"的隱藏功能
作者: Qin    時間: 2018-9-14 07:33

本帖最後由 Qin 於 2018-9-14 07:36 編輯

奇怪, 為何留言不能完全顯示???
作者: 准提部林    時間: 2018-9-14 09:39

回復 30# Qin

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
With Target
     If .Address = "$C$1" Then
        Cancel = True
        If [B1] = "" Then MsgBox "未輸入搜尋文字! ", 0 + 16: Exit Sub
        Call 搜尋(Array([B1], "", ""), Array(6, 7, 4))
        .Interior.ColorIndex = 6: [B1].Interior.ColorIndex = 6
     ElseIf .Address = "$C$2" Then
        Cancel = True
        If [B2] = "" Then MsgBox "未輸入搜尋文字! ", 0 + 16: Exit Sub
        Call 搜尋(Array("", [B2], ""), Array(6, 7, 4))
        .Interior.ColorIndex = 6: [B2].Interior.ColorIndex = 6
     ElseIf .Address = "$C$3" Then
        Cancel = True
        If [B3] = "" Then MsgBox "未輸入搜尋文字! ", 0 + 16: Exit Sub
        Call 搜尋(Array("", "", [B3]), Array(6, 7, 4))
        .Interior.ColorIndex = 6: [B3].Interior.ColorIndex = 6
     ElseIf .Address = "$A$1:$A$3" Then
        Cancel = True
        If [B1] & [B2] & [B3] = "" Then MsgBox "未輸入搜尋文字! ", 0 + 16: Exit Sub
        Call 搜尋(Array([B1], [B2], [B3]), Array(6, 7, 4))
        .Interior.ColorIndex = 6: [B1:B3].Interior.ColorIndex = 6
     End If
End With
End Sub

'====================================
Sub 搜尋(Ur1, Ur2)
Dim Sht As Worksheet, xU As Range, xE As Range, k%
Call 清除
For Each Sht In Sheets
    If Left(Sht.Name, 4) <> "Data" Then GoTo 101
    If Sht.FilterMode Then Sht.ShowAllData
    Set xU = Sht.UsedRange
    For k = 0 To 2
        If Ur1(k) <> "" Then
           xU.AutoFilter Field:=Ur2(k), Criteria1:=Ur1(k)
        End If
    Next k
    Set xE = Cells(Rows.Count, 1).End(xlUp)(2)
    If xE.Row < 6 Then Set xE = [A6]
    xU.Offset(1, 0).Copy xE
    Sht.AutoFilterMode = False
101: Next
Set xE = Cells(Rows.Count, 1).End(xlUp)
If xE.Row < 6 Then MsgBox "找不到符合的資料! ": Exit Sub
[A6:J6].Interior.ColorIndex = 35
[A7:J7].Interior.ColorIndex = 6
[A6:J7].Copy
Range(xE, [J6]).PasteSpecial Paste:=xlFormats
xE(2).EntireRow.Delete
[A6].Select
End Sub

Sub 清除()
With Sheets("Search")
     If .FilterMode Then .ShowAllData
     With .UsedRange.Offset(5, 0)
          .ClearContents
          .Interior.ColorIndex = xlNone
     End With
     .[A1,C1:C3].Interior.ColorIndex = 15
     .[B1:B3].Interior.ColorIndex = 35
     .[A6].Select
End With
End Sub
 
 
作者: 准提部林    時間: 2018-9-14 10:08

改一下[雙擊觸發]部份:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim T1$, T2$, T3$, R As Range, C%
With Target
     Select Case .Item(1).Address(0, 0)
       Case "C1": T1 = [B1]: Set R = [B1]: C = 1
       Case "C2": T2 = [B2]: Set R = [B2]: C = 1
       Case "C3": T3 = [B3]: Set R = [B3]: C = 1
       Case "A1": T1 = [B1]: T2 = [B2]: T3 = [B3]: Set R = [B1:B3]: C = 1
    End Select
    If C = 0 Then Exit Sub
    Cancel = True
    If T1 & T2 & T3 = "" Then MsgBox "未輸入搜尋文字! ", 0 + 16: Exit Sub
    Call 搜尋(Array(T1, T2, T3), Array(6, 7, 4))
    Union(.Cells, R).Interior.ColorIndex = 6
End With
End Sub
作者: Qin    時間: 2018-9-14 13:03

回復 34# 准提部林

准大的心法和招式真的千變萬化,層出不窮.

讓我想起很久以前, 在此論壇上的一位版主曾說過:
只有你想不到的, 沒有做不到的.
作者: Qin    時間: 2018-9-14 13:07     標題: VBA資料搜尋問題

本帖最後由 Qin 於 2018-9-14 13:18 編輯

回復 28# Kubi

文接31樓
我想將原本的一個檔分成2個檔來使用.
A檔是: Data , Password 1234 , 路徑是 U:/ACWH/
B檔是: Search Data , Password 5678 , 路徑是 C:/Users/Public/Documents/
請問,要做這些修改, 語法又要如何寫呢?
2檔皆附上
在31樓
作者: 准提部林    時間: 2018-9-14 14:21

回復 36# Qin


[attach]29402[/attach]

只能用2003版檔案格式, ".xls" 須改為 2007版以上的副檔名
〔檔案路徑〕自行去修改
作者: Qin    時間: 2018-9-16 01:07

回復 37# 准提部林

准大, 還有一些問題想修改, 勞煩了!
1) Data 檔資料持續增加中, 在有新資料更新才會打開更新 (有用密碼鎖上的 " 1234") , 所以希望在 使用 Search Data檔搜尋資料時,  Data 檔是不需要打開的
2) 希望搜尋結果所呈現的 "Date" 是由現今的年份至較久遠的年份...
3) 臨時想起, 想增加1個"日期"搜尋功能, 請参考 Search Data檔

[attach]29404[/attach]
作者: 准提部林    時間: 2018-9-16 09:48

回復 38# Qin

1) Data 檔資料持續增加中, 在有新資料更新才會打開更新 (有用密碼鎖上的 " 1234") , 所以希望在 使用 Search Data檔搜尋資料時,  Data 檔是不需要打開的
 _data是以〔唯讀〕開啟的,並不影響原檔自己的資料
2) 希望搜尋結果所呈現的 "Date" 是由現今的年份至較久遠的年份...
 _什麼意思???
3) 臨時想起, 想增加1個"日期"搜尋功能, 請参考 Search Data檔
 _如果日期都不輸入,如何篩?
 _三條件不輸入,只有日期,如何篩?
作者: Qin    時間: 2018-9-16 16:53

回復 39# 准提部林

請參考

[attach]29405[/attach][attach]29406[/attach][attach]29407[/attach]
作者: 准提部林    時間: 2018-9-16 18:33

本帖最後由 准提部林 於 2018-9-16 18:35 編輯

xN = "Data.xls"  >> xN = "Data.xlsx"  
還有 open 的路徑是錯的, mybook.path 要清掉,
檔案無法打開, 自行去找解決


[attach]29408[/attach]
作者: Qin    時間: 2018-9-17 09:03

回復 41# 准提部林

不知問題出在那里? 為何還是不行?

[attach]29414[/attach][attach]29415[/attach]
作者: 准提部林    時間: 2018-9-17 09:48

回復 42# Qin


我沒有新版本的EXCEL,
請其他大大是否可測一下, 修改OPEN程式碼~
作者: Qin    時間: 2018-9-20 23:16

回復 43# 准提部林


准大, 想請你再幫我看一看…
我再次測試,
你第一次給的程式碼, 不論是 Data.xls  或 Data.xlsx 都可以執行

後來,在我要求增加2項玏能后:

1) 日期排序
2) 增加日期搜尋玏能

不論是 Data.xls 或 Data.xlsx 都不能執行.

在此附上2個 xls 檔, 希望可以獲得正確的答案. 謝謝!

[attach]29427[/attach]
作者: 准提部林    時間: 2018-9-21 10:03

回復 44# Qin


你所謂的不能執行, 是指會錯誤中斷(要看程式碼錯在哪一行)?  還是抓不到資料?
我這測是可以(.xls),
作者: Qin    時間: 2018-9-21 22:51

本帖最後由 Qin 於 2018-9-21 22:53 編輯

回復 45# 准提部林


     以品名"楊桃"為例,雙擊觸發, 告之都是"找不到符合的資料!" (.xls)
作者: 准提部林    時間: 2018-9-22 08:37

本帖最後由 准提部林 於 2018-9-22 08:40 編輯

回復 46# Qin

沒問題的~~
[attach]29429[/attach]
作者: Qin    時間: 2018-9-23 01:21

回復 47# 准提部林

准大,        
       
因為第2個檔有問題,根本搜尋不到資料, 唯有放棄.       
我拿回你給我的第1個檔, 再按照第2個檔的程式碼敲打進去,       
發現這段有問題       
"  xU.AutoFilter Field:=3, Criteria1:=">=" & Ur1(3), Operator:=xlAnd, Criteria2:="<=" & Ur1(4)  "       
只要不寫上這段, 就可以使用.       
但日期的搜尋功能就不管用了       
例: 填上 From Date    01/ 01/2017     to Date    "Today()"       
但它 2015 - 2016 年的資料也跑出了???       
       
麻煩你再幫我看一看…謝謝!!       


[attach]29430[/attach][attach]29431[/attach]
作者: 准提部林    時間: 2018-9-23 10:33

回復 48# Qin


實在看不出原因, 或許日期格式有問題吧!
作者: Qin    時間: 2018-9-25 23:18

回復 49# 准提部林

准大
你給的提示, 我也去更改了多個日期格式
但是都是行不通…

後來, 嘗試只用上半句語法來執行, 想不到又可以哦!
xU.AutoFilter Field:=3, Criteria1:=">=" & Ur1(3)

也就是說, 鍵入 01/01/2016  它就只出現 2016 年至之後的資料 (雖然有些遺憾, 但至少, 是達到我想要的某部份需求)
我想唯有讓這下半句語法"Operator:=xlAnd, Criteria2:="<=" & Ur1(4)" 在一旁沉睡, 待找到厡因時, 才讓它重見天日.

因此, 請問准大,

1) 如果只用 "xU.AutoFilter Field:=3, Criteria1:=">=" & Ur1(3) " 這上半句語法, 在搜尋過程中, 對其他資料會不會有影響. (如: 資料搜尋出來不完整或搜尋速度緩慢等問題.)

2) 我用( .xls OR .xlsx) 共40萬筆資料搜尋時, 大概要花30秒的時間, 請問還可以加速嗎?

3) 在編號搜尋欄位, 例如編號是 " 20000350"  "11005710"  "10003210" 而我只需鍵入 " 2*350 " 或 " 11*5710"... 也可以把資料搜出來.
就好像 Excel 里的 find 功能, 只是不知道VBA 是否也可以做到?
作者: 准提部林    時間: 2018-9-26 10:48

回復 50# Qin


1) 如果只用 "xU.AutoFilter Field:=3, Criteria1:=">=" & Ur1(3) " 這上半句語法,
在搜尋過程中, 對其他資料會不會有影響. (如: 資料搜尋出來不完整或搜尋速度緩慢等問題.)
__只針對日期篩選,不會影響其它欄位

2) 我用( .xls OR .xlsx) 共40萬筆資料搜尋時, 大概要花30秒的時間, 請問還可以加速嗎?
__改用ARRAY或許可以快些,但未實測,無法確定

3) 在編號搜尋欄位, 例如編號是 " 20000350"  "11005710"  "10003210" 而我只需鍵入 " 2*350 " 或 " 11*5710"... 也可以把資料搜出來.
__編號是〔數值〕,〔篩選〕無法用文字比對
作者: 准提部林    時間: 2018-9-26 16:28

回復 50# Qin


試試看吧:
[attach]29450[/attach]
作者: Qin    時間: 2018-9-26 23:43

回復 52# 准提部林
     
     准大, 這段語法旁的附註亂碼, 麻煩你再將它寫在留言板上. 謝謝!

        ReDim Brr(1 To 60000, 1 To 10)    '­Y¸ê®Æ·|¶W¹L6¸Uµ§,¦Û¦æ§ó§ï
作者: 准提部林    時間: 2018-9-27 09:45

回復 53# Qin


如果篩選出來的資料會超過6萬筆, 將60000改為更大(多大? 自行斟酌)
作者: Qin    時間: 2018-9-30 18:02

回復 54# 准提部林

        准大               
                       
        我又想再請教你2個問題:               
        首先說清楚, 用你給的 "Data" 檔是沒有問題的, 但, 如使用我自己的文檔才會出現這問題.               
                       
1)        以"品名搜尋"               
        就會出現:  If Ur1(j) <> "" Then If Not Arr(i, Ur2(j)) Like Ur1(j) Then GoTo 102               
                       
        以"編號搜尋"               
        就會出現:  dd = Arr(i, 3)               
                       
        想請教是否又是因為"日期格式"的緣故.               
        如果"是", 可否請你再幫我修改, 只以"From Date" 搜尋就可以了               
                       
2)        准大, 你真的有求必應哦! 我要求以" * " 以星字鍵來做搜尋, 你也達成了我要求.               
        但是, 還有一個小小的問題,就是為何"編號 , 品名和廠商"搜尋時都必需使用 " 大字母" (Caps Lock)               
                       
        例:               
        h*1234               
        *french*               
        aa*               
        "找不到符合的資料"               
                       
        H*1234               
        *French*               
        AA*               
        搜尋結果沒問題               
                       
        可否修改成"大小字母"皆通用. 謝謝!               
                       
[attach]29472[/attach]
作者: 准提部林    時間: 2018-9-30 21:03

回復 55# Qin

Sub Search_Data(Ur1, Ur2)
Dim Sht As Worksheet, Arr, Brr, i&, j%, k%, N&, dd&
Dim Mybook As Workbook, xB As Workbook, xChk%
Call Clear_All
xN = "Data.xls": Set Mybook = ThisWorkbook
On Error Resume Next: Set xB = Workbooks(xN): On Error GoTo 0
If xB Is Nothing Then
   Application.ScreenUpdating = False
   Set xB = Workbooks.Open("C:\Users\Ms Tan\Desktop\Data.xls", , 1, , "1234")
   Mybook.Activate: xChk = 1
End If
'----------------------------
ReDim Brr(1 To 400000, 1 To 10) '若資料會超過6萬筆,自行更改
For Each Sht In xB.Sheets
    If LCase(Left(Sht.Name, 4)) <> "data" Then GoTo 101
    Arr = Range(Sht.[J2], Sht.Cells(Rows.Count, 1).End(xlUp))
    For i = 1 To UBound(Arr)
        For j = 0 To 2
            If Ur1(j) <> "" Then If LCase(Arr(i, Ur2(j))) Like LCase(Ur1(j)) = False Then GoTo 102
        Next j
        dd = 0
        If IsDate(Arr(i, 3)) Then dd = Arr(i, 3)
        If dd < Ur1(3) Then GoTo 102
        N = N + 1
        For k = 1 To UBound(Brr, 2): Brr(N, k) = Arr(i, k): Next
102: Next i
101: Next
If xChk = 1 Then xB.Close 0
'----------------------------
If N = 0 Then MsgBox "找不到符合資料!": Exit Sub
With [A8:J8].Resize(N)
     .Value = Brr
     .Sort Key1:=.Item(3), Order1:=xlDescending, Header:=xlNo
     [A4:J5].Copy
     .Cells.PasteSpecial Paste:=xlFormats
End With
[A6].Select
End Sub

Sub Clear_All()
With Sheets("Search")
     If .FilterMode Then .ShowAllData
     With .UsedRange.Offset(7, 0)
          .ClearContents
          .Interior.ColorIndex = xlNone
     End With
     .[A1,C1:C3].Interior.ColorIndex = 15
     .[B1:B3].Interior.ColorIndex = 35
     .[A6].Select
End With
End Sub

[attach]29473[/attach]
作者: GBKEE    時間: 2018-10-1 10:57

本帖最後由 GBKEE 於 2018-10-1 11:02 編輯

回復 55# Qin


    試試看
作者: Qin    時間: 2018-10-3 23:02

回復 57# GBKEE

謝謝! 我會參考..
作者: Qin    時間: 2018-10-3 23:05

本帖最後由 Qin 於 2018-10-3 23:17 編輯

回復 56# 准提部林

        准大
       
        我又遇到問題了….
       
1)        這次是"品名搜尋"問題, 當在B2輸入搜尋條件後,就會出現
         If Ur1(j) <> "" Then If LCase(Arr(i, Ur2(j))) Like LCase(Ur1(j)) = False Then GoTo 102
       
        因為之前受到"日期格式"的困擾, 以為這次又是什麼"文字格式"
        就跑到VBE 編輯器 Tools-> Options -> Editor Format -> Font 做修改
        無意中發現之前的亂碼現象, 可以在此獲得解決.
       
2)        在 B1, B2,B3 欄, 是以"雙摯觸動"來搜尋資料, 可否改成輸 入搜尋條件後,按 Enter 就可獲得搜尋結果.
        因為感覺比較好使用.至於多條件搜尋就保留原本的方式.
        准大, 如果這個修改會有"牽一髮而動全身"的大幅度更改, 那就免了吧!
       
        謝謝!!
[attach]29488[/attach][attach]29489[/attach][attach]29490[/attach]
作者: 准提部林    時間: 2018-10-4 10:06

本帖最後由 准提部林 於 2018-10-4 10:57 編輯

回復 59# Qin

品名搜尋會出現錯誤:
__看[data]表的 G2703 為#N/A,

For j = 0 To 2
    If IsError(Arr(i, Ur2(j))) Then GoTo 102 '在這位置加這一行
    If Ur1(j) <> "" Then If LCase(Arr(i, Ur2(j))) Like LCase(Ur1(j)) = False Then GoTo 102
Next j


至於想[雙按左鍵]改成[ENTER]執行, 不建議這樣做,
CHANGE觸發, 每改一次即執行一次, 不太環保,
輸入並確定要搜尋條件無誤, 再執行程式, 才是最妥當, 差不了多少時間,
資料處理者, 有時不要嫌麻煩~~
作者: Qin    時間: 2018-10-7 14:31     標題: VBA資料搜尋問題

本帖最後由 Qin 於 2018-10-7 14:35 編輯

回復 60# 准提部林

"歹勢" 啦! 不是嫌麻煩, 只是因為習慣使然.
當想到准大都不厭其煩, 幫我解決一個又一個問題時.
心裡除了感恩還有, 還有無限的感激….
言歸正傳, 為何在 Search Data 的過程中, 如果不開
作者: Qin    時間: 2018-10-9 00:37

回復 60# 准提部林

不曉得有何故障, 一直不能將全文完整貼上...
作者: Qin    時間: 2018-10-9 14:07

回復 60# 准提部林

言歸正傳, 為何在 Search Data 的過程中, 如果不打開 Data 檔, 就要用 1分鐘 的時間搜資料,
如果2檔同時打開, 只需 4秒-7秒, 就可以搜到答案. (40萬筆)

因為我的本意是 Search Data 的過程中, Data 檔是不要打開的.
又要再次麻煩准大幫我看看….

p/s:"日期格式"問題,已找到了解決的方法.
作者: 准提部林    時間: 2018-10-9 14:30

回復 63# Qin


單獨手動打開data檔, 看要花多少時間???
如果檔案中有很多公式, 開啟時會自動重算, 要花些時間的!

所謂[不開啟], 實際是用別種方式開啟, 只是肉眼看不到,
沒有實際檔案測試, 什麼也說不準!!!
_我只用office 2000, 所以, 可另行發帖, 請其他人幫忙吧~~
作者: Qin    時間: 2018-10-15 00:04

回復 64# 准提部林

謝謝你的提醒
原來 Data 檔案太大, 打開時, 需要花一點時間才是癥結所在.

現在問題又解決了,
因為我將它儲存為(.xlsb)
在搜尋速度上也令人滿意…

接下來, 還可以請你再幫我最後一個忙嗎?
我想將搜尋出來資料用 VBA 再做一個 [現存數量] Qty on Hand
請看附檔
[attach]29534[/attach]
作者: 准提部林    時間: 2018-10-15 17:41

回復 65# Qin

Sub Trans_Qty()
Dim R&
With Sheets("Qty on Hand")
     If .FilterMode Then .ShowAllData
     .UsedRange.Offset(1, 0).EntireRow.Delete
End With
R = Cells(Rows.Count, 1).End(xlUp).Row - 7
If R <= 0 Then Exit Sub
With ['Qty on Hand'!A2:I2].Resize(R)
     [A8:I8].Resize(R).Copy .Cells
     .Sort Key1:=.Item(6), Order1:=xlAscending, _
           Key2:=.Item(3), Order1:=xlAscending, Header:=xlNo
End With
With ['Qty on Hand'!I2].Resize(R)
     .Formula = "=IF(F2=F3,""A"",""B"")&TEXT(MID(I1,2,99),""0;-0;0;!0"")+N(H2)"
     .Value = .Value
     .Replace "A*", "", Lookat:=xlPart
     .Replace "B", ""
     .NumberFormatLocal = "#,##0;-#,##0"
End With
Application.Goto ['Qty on Hand'!A2]
End Sub
作者: 准提部林    時間: 2018-10-16 11:56

稍改
Sub Trans_Qty()
Dim R&
With Sheets("Qty on Hand")
     .AutoFilterMode = False
     .UsedRange.Offset(1, 0).EntireRow.Delete
End With
R = Cells(Rows.Count, 1).End(xlUp).Row - 7
If R <= 0 Then Exit Sub
With ['Qty on Hand'!A2:I2].Resize(R)
     [A8:I8].Resize(R).Copy .Cells
     .Sort Key1:=.Item(6), Order1:=xlAscending, _
           Key2:=.Item(3), Order1:=xlAscending, Header:=xlNo
End With
['Qty on Hand'!A1:I1].Resize(R + 1).AutoFilter
With ['Qty on Hand'!I2].Resize(R)
     .NumberFormatLocal = "#,##0;-#,##0"
     '.Formula = "=IF(F2=F3,""A"","""")&TEXT(MID(I1,2,99),""0;-0;0;!0"")+N(H2)" '公式(1)
     '.Formula = "=IF(F2=F3,""A"","""")&IF(ROW(A1)=1,0,MID(I1,2,99))+N(H2)"    '公式(2)
     .Formula = "=IF(F2=F3,"""",SUMIF(F:F,F2,H:H))"  '公式(3)
     '三種公式任選一個, 資料多, 看哪個快, 選哪個
     .Value = .Value
     .Replace "A*", "", Lookat:=xlPart '使用公式(3), 可省略這一行
End With
Application.Goto ['Qty on Hand'!A2]
End Sub
作者: Qin    時間: 2018-10-17 23:43

回復 67# 准提部林

准大
3個公式, 只有公式(3)可用
其他2個皆出錯.
[attach]29546[/attach]
作者: 准提部林    時間: 2018-10-18 10:35

回復 68# Qin

更正下:
With ['Qty on Hand'!I2].Resize(R)
     .NumberFormatLocal = "#,##0;-#,##0"
     .Formula = "=IF(F2=F3,""A"","""")&TEXT(MID(I1,2,99),""0;-0;0;!0"")*(F2=F1)+N(H2)"  '公式(1)
     '.Formula = "=IF(F2=F3,""A"","""")&IF(ROW(A1)=1,0,MID(I1,2,99))*(F2=F1)+N(H2)" '公式(2)
     '.Formula = "=IF(F2=F3,"""",SUMIF(F:F,F2,H:H))" '公式(3)
     .Value = .Value
     .Replace "A*", "", Lookat:=xlPart '公式(1)及(2), 需加這一行
End With
作者: Qin    時間: 2018-10-21 17:30

回復 69# 准提部林

幸好有准大不斷的幫忙, 符合我需求的程式碼終於可以使用了…
謝謝你,當我說資料太大, 搜尋速度慢時, 又幫我重新寫過一篇程式碼.
謝謝你,跟據我的要求幫我修修改改, 讓它適合我使用.
謝謝你,總在我遇到問題找不到原因時, 仍願意多敲幾個字給予指示和提醒.
你真的很棒很棒
還有真的真的真的很好…

准大, 謝謝你!!!





                   **學而不厭  誨人不倦**
作者: Qin    時間: 2018-10-21 17:40

回復 28# Kubi

在此之前, 我一真都在用你給我的程序碼(10萬筆搜尋)
它的確很快又很好用
只是我想把 "Data" (資料庫) & "Search" (搜尋)這2個檔分開用.
所以我很想知道, 你這篇程式碼的這整句語法是要如何寫的?
我想不同的語法是不是會有不同的寫法.
我只是想拿個參考…


Kubi 大大,謝謝你…
作者: Kubi    時間: 2018-10-21 20:23

回復 71# Qin

自從准大熱心幫忙後,我就沒有再follow此題了。
至於 "Data" (資料庫) & "Search" (搜尋)這2個檔分開用,意思是將Data(資料庫)拆解至另外1個檔案嗎?
若是如此的話,我的寫法可能會開啟Search(搜尋)這個檔的時候,順便讀入Data(資料庫)至暫存工作表,作為搜尋依據。
作者: Qin    時間: 2018-10-21 20:42

回復 72# Kubi

對,就是要分開2個檔.
你可以再幫我一次
讓我知道要怎樣寫嗎?
謝謝!!
作者: Kubi    時間: 2018-10-21 21:35

回復 73# Qin
壓縮檔內有下列兩個檔案:
1.主程式檔案:資料搜尋.xlsm
2.資料庫檔案:SearchData.xlsx
兩個檔案必須放在同個資料夾中。
資料庫檔案名稱必須為SearchData.xlsx
[attach]29576[/attach]
作者: Qin    時間: 2018-10-22 23:19

回復 74# Kubi

謝謝了...
作者: Andy2483    時間: 2022-11-28 16:23

本帖最後由 Andy2483 於 2022-11-28 16:31 編輯

回復 67# 准提部林

謝謝前輩常用不同方式的程式碼讓後輩學習
1.Application.Goto ['Qty on Hand'!A2]  同  Sheets("Qty on Hand").Activate: [A2].Activate
2.[~!~]的陳述方式會因為 Qty on Hand 之間有空格而無法辨識,所以要以單引號前後包住

以上心得若有錯,請前輩再指導!
作者: singo1232001    時間: 2023-3-7 10:06

本帖最後由 singo1232001 於 2023-3-7 10:20 編輯

感謝原PO 感謝各位大大  
這題很不錯
練習完畢 附上檔案

開啟"SQL搜尋"工作表
幾個簡易功能說明  
1.只在列7輸入 會模糊搜索
2.列6列7都輸入 會區間搜索
3.D,E,G欄 各為文字模糊搜索 可空格 例如:A 司 輸出 A公司
4.全部空白 為全頁搜索
5.A~J欄 同時輸入 會and搜索

限制
1.搜尋檔案 與 檔案來源 路徑目前沒有優化  暫定要在同一資料夾底下
2.很多小bug 只有做主體幾個大功能 過細的客製化功能與需求 尚未製作

Sub 關鍵字查詢()
With CreateObject("adodb.connection"): V = Application.Version
If V >= 12 Then V = "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0; "
If V < 12 Then V = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0; "
.Open V & "Data Source=" & ThisWorkbook.Path & "\SearchData.xlsx"

'excel 調用adodb 用 sql 時 欄位名稱有"."符號 須改為 "#"號
If Cells(7, 1) <> "" And Cells(6, 1) = "" Then sq = sq & " and  [No#] like  '%" & Replace(Cells(7, 1), " ", "%") & "%'"
If Cells(7, 1) <> "" And Cells(6, 1) <> "" Then sq = sq & " and  [No#] between " & Cells(6, 1) & " and " & Cells(7, 1) ' & "'"
If Cells(7, 2) <> "" And Cells(6, 2) = "" Then sq = sq & " and  [Inv#]  like '%" & Replace(Cells(7, 2), " ", "%") & "%'"
If Cells(7, 2) <> "" And Cells(6, 2) <> "" Then sq = sq & " and  [Inv#]  between '" & Cells(6, 2) & "' and '" & Cells(7, 2) & "'"
If IsDate(Cells(7, 3)) Then
If Cells(7, 3) <> "" And Cells(6, 3) = "" Then sq = sq & " and  [Date]  like '%" & Cells(7, 3) & "%'"
If Cells(7, 3) <> "" And Cells(6, 3) <> "" Then sq = sq & " and  Format(Date, 'yyyy-MM-dd')  between '" & Format(Cells(6, 3), "yyyy-MM-dd") & "' and '" & Format(Cells(7, 3), "yyyy-MM-dd") & "'"
End If
If Cells(7, 4) <> "" Then sq = sq & " and  [Supplier] like '%" & Replace(Cells(7, 4), " ", "%") & "%'"
If Cells(7, 5) <> "" Then sq = sq & " and  [Inv#(1)] like '%" & Replace(Cells(7, 5), " ", "%") & "%'"
If Cells(7, 6) <> "" And Cells(6, 6) = "" Then sq = sq & " and  [Part No#] like '%" & Replace(Cells(7, 6), " ", "%") & "%'"
If Cells(7, 6) <> "" And Cells(6, 6) <> "" Then sq = sq & " and  [Part No#]  between '" & Cells(6, 6) & "' and '" & Cells(7, 6) & "'"
If Cells(7, 7) <> "" Then sq = sq & " and  [Prod# Name] like '%" & Replace(Cells(7, 7), " ", "%") & "%'"
If Cells(7, 8) <> "" And Cells(6, 8) = "" Then sq = sq & " and  [Qty]  like '%" & Replace(Cells(7, 8), " ", "%") & "%'"
If Cells(7, 8) <> "" And Cells(6, 8) <> "" Then sq = sq & " and  [Qty]  between " & Cells(6, 8) & " and " & Cells(7, 8)
If Cells(7, 9) <> "" And Cells(6, 9) = "" Then sq = sq & " and  [Amt#]  like '%" & Replace(Cells(7, 9), " ", "%") & "%'"
If Cells(7, 9) <> "" And Cells(6, 9) <> "" Then sq = sq & " and  [Amt#]  between " & Cells(6, 9) & " and " & Cells(7, 9)
If Cells(7, 10) <> "" And Cells(6, 10) = "" Then sq = sq & " and  [Total]  like '%" & Replace(Cells(7, 10), " ", "%") & "%'"
If Cells(7, 10) <> "" And Cells(6, 10) <> "" Then sq = sq & " and  [Total]  between " & Cells(6, 10) & " and " & Cells(7, 10)

If sq <> "" Then sq = Mid(sq, 5, 99999)
If sq <> "" Then sq = "select * from [Data$A1:J] where " & sq
If sq = "" Then sq = "select * from [Data$A1:J] "
Sheets("SQL搜尋").Cells(9, 1).Resize(10000, 10).ClearContents
Sheets("SQL搜尋").Cells(9, 1).CopyFromRecordset .Execute(sq)
.Close: End With
End Sub

Sub 清除關鍵字()
Sheets("SQL搜尋").Range("a6:J7").ClearContents
End Sub




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)