Board logo

標題: [發問] 如何將ARR資料轉入B欄的驗證清單 [打印本頁]

作者: dou10801    時間: 2022-12-19 15:12     標題: 如何將ARR資料轉入B欄的驗證清單

如何將去重的ARR資料轉入B欄的驗證清單中,感恩.
作者: Andy2483    時間: 2022-12-19 15:49

回復 1# dou10801


    謝謝前輩發表此主題與範例
是這意思嗎?
[attach]35622[/attach]

.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(arr, ",")
作者: Andy2483    時間: 2022-12-19 16:40

回復 1# dou10801


    以下是後學藉此題練習字典去除重複的心得與註解
Option Explicit
Sub 資料以字典去除重複轉為驗證清單()
Dim i&, Y, arr
'↑宣告變數:i是長整數,(Y,arr)是通用型變數
Set Y = CreateObject("Scripting.Dictionary")
'↑令Y是 字典
For i = 1 To [A65536].End(xlUp).Row
'↑設順迴圈!i從1到A欄有內容儲存格最後列號
   Y(Trim(Cells(i, "A"))) = ""
   '↑令迴圈儲存格的值去除頭尾的空白字元後當key,item是空字元,放入字典中
Next
arr = Application.Transpose(Application.Transpose(Y.KEYS))
'↑令arr是一維陣列!用Y字典的key轉置兩次的值放入這陣列中
With [工作表1!B:B].Validation
      .Delete
      .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(arr, ",")
      '因為Formula1:=後面要給一個","符號可分割的字串,所以JOIN() 就可以了
      'https://learn.microsoft.com/zh-tw/office/vba/language/reference/user-interface-help/join-function

End With
Set Y = Nothing
Erase arr
End Sub
作者: dou10801    時間: 2022-12-21 09:03

感謝兩位前輩指導.
TO:Andy2483=arr = Application.Transpose(Application.Transpose(Y.KEYS))
                             '↑令arr是一維陣列!用Y字典的key轉置兩次的值放入這陣列中
經測試 arr=Y.KEYS    即可.
作者: Andy2483    時間: 2022-12-21 10:19

回復 4# dou10801


   謝謝前輩回復
太好了,又學到一個經驗,後學將字典與一維陣列搞混了!謝謝分享測試心得
作者: singo1232001    時間: 2022-12-21 11:01

本帖最後由 singo1232001 於 2022-12-21 11:15 編輯

回復 5# Andy2483


1.字典本身是物件

2.創建字典d後,字典本身會順便創建   d.keys  跟d.items 兩個一維陣列

3.這兩個陣列可直接取用
   但與一般的陣列不同
   無法直接修改(可讀不可改)
  
   要修改一樣得從字典物件去修
   或者
   如前幾樓的方式 先把資料匯入新的arr陣列 改用arr修改處理資料  


補充:在字典與陣列互相欠套的各種方式中  ( 物件包陣列 物件包物件  陣列包物件  陣列包陣列)
         只要陣列在物件之下,皆不能修改 只能讀取,所以只有第一次整組匯入的機會,一進去就不能再改
         只有陣列存在陣列下,才能修改子陣列   
         例如:二維陣列ar(1,1) 或 第二層陣列ar(1)(1)
         這兩種陣列也都可以叫二維陣列 不容易區分 實務上並沒有特別區分講法
          因為在維度的概念上,是一樣的 ,只有效率上會有些許差別,跟應用上有些取差別
作者: Andy2483    時間: 2022-12-21 11:27

本帖最後由 Andy2483 於 2022-12-21 11:30 編輯

回復 6# singo1232001


    謝謝前輩指導
後學感覺好幸運,能得到前輩的回覆指導
後學學到前輩指導的心得,用立體停車場比喻:
1.一般陣列是駕駛自己開進停車,自己取車開出 (Array)
2.字典像是自動立體停車場機器,將車輸送到立體停車格,機器取出車子
3.停車格s是陣列,車子是陣列值 (items)
4.輸送的機器s也是陣列 (keys)
5.自動立體停車場的車子要透過機器才能進出

請前輩再指導,謝謝
作者: Andy2483    時間: 2022-12-21 11:44

本帖最後由 Andy2483 於 2022-12-21 11:56 編輯

回復 6# singo1232001


    前輩的補充知識包含很廣,有些後學還不會用,請前輩以後再提點
至於字典裡的陣列大小不能改,後學有學到先將字典裡放入一個夠用的空陣列,就可以變通使用
謝謝前輩再指導

補充心得:
字典可透過Add,Remove,RemoveAll做字典增減
作者: 准提部林    時間: 2022-12-21 19:35

Formula1:=Join(Y.keys, ",")
本身即是陣列, 不須再轉給其它陣列變數
作者: dou10801    時間: 2022-12-22 11:11

感謝各位前輩指導,如何將Y.KEYS作排序,謝謝.
作者: singo1232001    時間: 2022-12-22 12:15

回復 10# dou10801


    Sub SortArray()
  arr = Array("a", "b", "c", "d", "e", "C", "b")
  'arr = Y.keys()
  QuickSort arr, LBound(arr), UBound(arr)
  Debug.Print Join(arr, ",")
End Sub

Function QuickSort(ByRef ar, ByVal iLo As Long, ByVal iHi As Long)
  Dim pivot As Variant, lo, hi As Long
  
  lo = iLo: hi = iHi
  pivot = UCase(ar((lo + hi) \ 2))
  
  While lo <= hi
    While (UCase(ar(lo)) < pivot And UCase(lo) < UCase(iHi)): lo = lo + 1: Wend
    While (UCase(ar(hi)) > pivot And UCase(hi) > UCase(iLo)): hi = hi - 1: Wend
    If (lo <= hi) Then
      tmp = ar(lo): ar(lo) = ar(hi): ar(hi) = tmp
      lo = lo + 1: hi = hi - 1: tmp = ""
    End If
  Wend
  
  If hi > iLo Then QuickSort ar, iLo, hi
  If lo < iHi Then QuickSort ar, lo, iHi
End Function
作者: dou10801    時間: 2022-12-24 20:50

回復 11# singo1232001 感謝指導,收下,慢慢消化.
作者: Andy2483    時間: 2022-12-26 13:46

本帖最後由 Andy2483 於 2022-12-26 13:56 編輯

回復 11# singo1232001


    謝謝前輩指導
後學藉此帖習得陣列排序相關知識,請前輩再指導

執行結果:
[attach]35658[/attach]

程式碼心得註解如下:

Option Explicit
Sub SortArray()
Dim Arr, Y, i
'↑宣告變數:Arr,Y,i是通用變數
Arr = Array("4A", "5A", "6A", "7A", "2A", "4A", "6A", "1A", "2A", "3A")
'↑令Arr是一維陣列
Set Y = CreateObject("Scripting.Dictionary")
'↑令Y是 字典
For Each i In Arr
'↑設順迴圈!令i是 Arr陣列裡的一員,從前面輪到後面
   Y(i) = ""
   '↑令以i變數值為key,item是空字元,放入Y字典中
Next
Arr = Y.KEYS()
'↑令Arr倒調原來陣列值,換裝Y字典key組成的陣列值
QuickSort Arr, LBound(Arr), UBound(Arr)
'↑給QuickSort這自訂函數3個 變數令其回傳值
'1.ar變數: Arr陣列
'2.iLo&: LBound(Arr):Arr陣列最小索引號數
'3.iHi&: UBound(Arr):Arr陣列最大索引號數

Debug.Print Join(Arr, ",")
'↑在即時運算窗顯示: 以","符號連結 Arr陣列值的字串結果
End Sub


Function QuickSort(ByRef ar, ByVal iLo As Long, ByVal iHi As Long)
'宣告ar是通用型變數,ByRef_指定傳遞引數的方式是呼叫程式可以變更呼叫程式內引數基礎的變數值。
'宣告iLo, iHi 是長整數,ByVal指定引數是以 傳值方式傳遞

Dim pivot As Variant, tmp As Variant, lo As Long, hi As Long
'↑宣告變數:(pivot,tmp)是通用型變數,(lo,hi)是長整數
lo = iLo
'↑令lo這通用型變數是iLo變數代的值 (Arr陣列最小索引號數)
hi = iHi
'↑令hi這通用型變數是iHi變數代的值 (Arr陣列最大索引號數)
pivot = UCase(ar((lo + hi) \ 2))
'↑令pivot是 ((Arr陣列最小索引號數+最大索引號數)/2 去尾整數值)索引號的ar陣列值再轉為大寫英文字
While lo <= hi
'↑設當lo變數<= hi變數 條件成立執行的迴圈
   While (UCase(ar(lo)) < pivot And lo < iHi)
   '↑設當lo變數陣列值再轉大寫 < pivot變數,而且lo變數 < iHi變數,條件成立執行的迴圈
      lo = lo + 1
      '↑令lo變數累加 1
   Wend
   While (UCase(ar(hi)) > pivot And hi > iLo)
   '↑設當hi變數陣列值再轉大寫 > pivot變數,而且hi變數 > iLo變數,條件成立執行的迴圈
      hi = hi - 1
      '↑令hi變數逐次減 1
   Wend
   If lo <= hi Then
   '↑如果 lo變數 <= hi變數
      tmp = ar(lo)
      '↑令tmp這通用型變數是 lo變數索引號的ar陣列值
      ar(lo) = ar(hi)
      '↑令lo變數索引號的ar陣列值是 hi變數索引號的ar陣列值
      ar(hi) = tmp
      '↑令hi變數索引號的ar陣列值是 tmp這通用型變數值
      lo = lo + 1
      '↑令lo變數累加 1
      hi = hi - 1
      '↑令hi變數逐次減 1
      tmp = ""
      '↑令tmp這通用型變數是 空字元
   End If
Wend
If hi > iLo Then QuickSort ar, iLo, hi
'↑如果hi變數 > iLo變數,給QuickSort這自訂函數3個 變數令其回傳值
'1.ar變數: ar陣列
'2.iLo&: iLo變數
'3.iHi&: hi變數

If lo < iHi Then QuickSort ar, lo, iHi
'↑如果lo變數 < iHi變數,給QuickSort這自訂函數3個 變數令其回傳值
'1.ar變數: ar陣列
'2.iLo&: lo變數
'3.iHi&: iHi變數

End Function
作者: Scott090    時間: 2023-3-2 08:19

回復 13# Andy2483

太精采了也學習了
謝謝
作者: singo1232001    時間: 2023-3-2 09:40

本帖最後由 singo1232001 於 2023-3-2 09:44 編輯

回復 14# Scott090

也有調用SQL的寫法   此種寫法要創一張名為"sortSQL"的工作表,表可隱藏  檔案要有檔名
Sub SortArray()
arr = Array("a", "b", "c", "d", "e", "C", "b")
orderSQL arr
Debug.Print Join(arr, ",")
End Sub

Function orderSQL(ar)
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.FullName
Set s = Sheets("sortSQL"): s.[A:A].ClearContents: s.[a1] = "sort"
s.[a2].Resize(UBound(ar) + 1, 1) = Application.Transpose(ar)
q = "select * from [sortSQL$A:A] order by sort"
ar = Application.Index(.Execute(q).getrows, 1, 0): End With
End Function
作者: Scott090    時間: 2023-3-3 06:51

回復 15# singo1232001

感恩 再次深入地說明




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