Board logo

標題: [發問] A表每單筆資料去查詢B表 得出多列資料 複製到C表 [0613]成功嚕 [打印本頁]

作者: milkpillow    時間: 2010-5-29 06:52     標題: A表每單筆資料去查詢B表 得出多列資料 複製到C表 [0613]成功嚕

本帖最後由 milkpillow 於 2010-6-14 23:54 編輯

各位前輩
這個標題想了十分鍾有... 不是很確切.請見諒~_~

A表 有很多筆資料 ID 是不重複的
B表 有很多筆資料 SID 會重複 但是值不會重複 (好像也不對... 應該是 ID+值 不會重複)
C表 是要輸出結果樣子 (我都用手做 一百筆資料就要兩小時...)

我手動的操作方式:
A表的第一筆資料 的 ST欄 複製該值
切換B表 使用進階篩選功能 得出三筆可用資料 (這個幾筆並不固定,基本上應該至少有一筆...)
切換C表 將三筆可用資料 複製到C表貼上 並且把A表的ID 跟PAGE資訊也複製過去
回A表的第二筆資料再繼續複製..
手動迴圈兩個鐘頭之後 一百筆完成...

真的很難用國語敘述... 而且做起來很費時間..
我準備了一個檔案 請前輩們指點一下.. 裡面我有寫註解..怕不明顯 所以用顯示 可能會礙眼..

我用網路查到 舊網站有篇文章很像有關係 但已經無法註冊跟觀看.. >"<
http://gb.twbts.com/index.php?topic=12801.0

以上 麻煩您(s)了
作者: PD961A    時間: 2010-5-29 08:44

回復 1# milkpillow

     http://gb.twbts.com/index.php?topic=12801.0
    主題: sheet2內容固定,比對sheet1後,將符合的列複製於sheet3  

  Hsieh版主   Re: sheet2內容固定,比對sheet1後,將符合的列複製於sheet3
&laquo; 回覆文章 #9 於: 2010-02-28, 18:07:56 &raquo;  
程式碼:
Sub nn()
Dim Rng As Range, A As Range, Cell As Range
With Sheet2
Set Rng = .Range(.[A1], .[A65536].End(xlUp))'設置比對的標準區域
End With
With Sheet1
For Each A In .Range(.[D1], .[D65536].End(xlUp))'在sheet1的d欄資料循環
  If Not Rng.Find(A, lookat:=xlWhole) Is Nothing Then'如果標準區找到d欄的值
    If Cell Is Nothing Then Set Cell = A Else Set Cell = Union(Cell, A)'如果變數Cell是不是物件就將d欄設給Cell否則Cell就會將原來範圍增加一儲存格A
  End If
Next
End With
Sheet3.Cells = ""'清空Sheet3內容
Cell.EntireRow.Copy Sheet3.[A1]'把Sheet1符合的列複製到Sheet3的A1
   
End Sub
作者: Hsieh    時間: 2010-5-29 09:01

回復 1# milkpillow
  1. Sub Q_Table()
  2. Dim A As Range, C As Range, Ar()
  3. With Sheets("B全部紀錄")
  4. For Each A In .Range(.[A2], .[A1048576].End(xlUp))
  5.    Set C = Sheets("A收集").Columns("C").Find(A, lookat:=xlWhole)
  6.      If Not C Is Nothing Then
  7.        ReDim Preserve Ar(s)
  8.        Ar(s) = Array(C.Offset(, -2).Value, C.Offset(, -1).Value, A.Offset(, 1).Value, A.Offset(, 2).Value, A.Offset(, 3).Value)
  9.        s = s + 1
  10.    End If
  11. Next
  12. End With
  13. Sheets("C輸出").[A2:E1048576].Clear
  14. If s > 0 Then Sheets("C輸出").[A2].Resize(s, 5) = Application.Transpose(Application.Transpose(Ar))
  15. Sheets("C輸出").Select
  16. End Sub
複製代碼
[attach]1066[/attach]
作者: milkpillow    時間: 2010-5-29 17:34

我已下載測試 完全符合要輸出的結果
而且好方便 瞬間減少我的笨方法手動迴圈 所耗費的時間與力氣...
突然覺得我好渺小... 這動作至少浪費我生命中的整整240個小時有..

這麼顯著的減少手動操作..
讓小妹對於VBA更有興趣了..
雖然很多指令不了解 我太淺了...但是我會去查的..
先感謝兩位大大的回覆..

網路上有這個論壇真好~
世界上有兩位前輩真好~

作者: milkpillow    時間: 2010-6-10 12:26

本帖最後由 milkpillow 於 2010-6-10 12:48 編輯

請教 Hsieh 與 各位前輩.
實際應用後發現 重複的值 他不會處理出來.(如附件)
我看了幾個小時 實在是不甚了解...



Sub AA_Table()
Dim A As Range, C As Range, Ar() //定義變數
With Sheets("B全部紀錄")      //用B表
For Each A In .Range(.[A2], .[A1048576].End(xlUp)) //A欄 逐列處理
   Set C = Sheets("A收集").Columns("C").Find(A, lookat:=xlWhole) //在A收集的c欄 尋找A . 是不是這邊應該要反過來寫  在B全部紀錄A欄 尋找A?
     If Not C Is Nothing Then
       ReDim Preserve Ar(s)
       Ar(s) = Array(C.Offset(, -2).Value, C.Offset(, -1).Value, A.Offset(, 1).Value, A.Offset(, 2).Value, A.Offset(, 3).Value) //設定 C輸出五欄的值
       s = s + 1
   End If
Next
End With
Sheets("C輸出").[A2:E1048576].Clear
If s > 0 Then Sheets("C輸出").[A2].Resize(s, 5) = Application.Transpose(Application.Transpose(Ar))
Sheets("C輸出").Select
End Sub
作者: Hsieh    時間: 2010-6-10 23:02

回復 5# milkpillow


    這樣2個表的關聯性不足
並不知道每筆確定的比對對象
請說明2表資料的比對規則
重新思考邏輯
作者: milkpillow    時間: 2010-6-10 23:29

Hsieh 大

這個 是製造新商品選項用的SQL用的..
有袖女上衣 有長T 短T 但是各有白色粉紅藍色,另外一個情況 則背心A 只有黃色黑色.
那麼各種商品 有的顏色並不一定.
目前做的是從舊的型號 去取得這個商品有什麼色的選項.(就是A收集的C欄位  對應  B全部紀錄 得出多列可用資料)
並將產生的 新的選項塞到資料庫中.
那麼在實際應用上面 每個新商品都至少會有一個選項(集).

所以目前的問題是. (下面敘述請查看上面的附檔QQ)
新型號A01~A05 都需要同一個顏色選項集555.(該集合有1、5、6、18、25、30、75的顏色)
但是他只會抓到A01 的 顏色選項集555
實際上A02~A05 應該要分別產生出 顏色選項集555.(該集合有1、5、6、18、25、30、75的顏色)
↑因為他們擁有相同的顏色集555

請您再幫我費神一下 謝先
作者: Hsieh    時間: 2010-6-11 11:28

回復 7# milkpillow


    A收集的品名跟B全部資料的OS_NAME有甚麼關連對應索引?
或是確定數量會相同?
作者: milkpillow    時間: 2010-6-11 17:00

本帖最後由 milkpillow 於 2010-6-12 16:15 編輯

我將檔案全部整理成口語話的欄位名稱
並且刪去沒有用到的.
加上了箭頭跟顏色說明
希望這樣可以比較好理解...
勞煩了 謝謝您∼

如附件
[attach]1220[/attach]


沒有做什麼的編輯 只是沒有人看見我..
作者: Hsieh    時間: 2010-6-12 20:52

回復 9# milkpillow

試試看是不是這樣的意思
  1. Sub matchdata()
  2. Dim Ay()
  3. Set d = CreateObject("Scripting.Dictionary")
  4. With Sheet2
  5.   For Each A In .Range(.[A2], .[A65536].End(xlUp))
  6.      If d.exists(A.Value) = False Then
  7.         d(A.Value) = Join(Array(A, A.Offset(, 1), A.Offset(, 2), A.Offset(, 3)), ",")
  8.         Else
  9.         d(A.Value) = d(A.Value) & ";" & Join(Array(A, A.Offset(, 1), A.Offset(, 2), A.Offset(, 3)), ",")
  10.      End If
  11.     Next
  12. End With
  13. With Sheet1
  14.    For Each A In .Range(.[C2], .[C65536].End(xlUp))
  15.       If d.exists(A.Value) = True Then
  16.          Ar = Split(d(A.Value), ";")
  17.          For i = 0 To UBound(Ar)
  18.          ReDim Preserve Ay(s)
  19.          Ay(s) = Split(A.Offset(, -2) & "," & A.Offset(, -1) & "," & Ar(i), ",")
  20.          s = s + 1
  21.          Next
  22.          Else
  23.          If mystr = "" Then mystr = A Else mystr = mystr & "," & A
  24.         End If
  25.     Next
  26. End With
  27. With Sheet3
  28. .[A2:F65536] = ""
  29. .[A2].Resize(s, 6) = Application.Transpose(Application.Transpose(Ay))
  30. MsgBox mystr & "沒找到"
  31. End With
  32. End Sub
複製代碼

作者: milkpillow    時間: 2010-6-13 21:18

  1. Sub matchdata()
  2. Dim Ay() '全域變數Ay用來放最終結果
  3. Set d = CreateObject("Scripting.Dictionary") '創立一個 二維陣列的物件d
  4. With Sheet2
  5.   For Each A In .Range(.[A2], .[A65536].End(xlUp)) '第二張表的A欄 逐列 =暫存變數A
  6.      If d.exists(A.Value) = False Then '用Dictionary的Exists函數 來檢查比對A的值如果沒有則執行下一行
  7.         d(A.Value) = Join(Array(A, A.Offset(, 1), A.Offset(, 2), A.Offset(, 3)), ",") '取值?? 橫向的 1A,1B,1C 醬
  8.         Else '如果有
  9.         d(A.Value) = d(A.Value) & ";" & Join(Array(A, A.Offset(, 1), A.Offset(, 2), A.Offset(, 3)), ",") '串聯起來用;隔開 變成1A,1B,1C;2A,2B,2C 取出的時候會變成兩列或更多列的三欄資料
  10.      End If
  11.     Next
  12. End With
  13. With Sheet1
  14.    For Each A In .Range(.[C2], .[C65536].End(xlUp)) '第一張表的C欄 逐列 =暫存變數A
  15.       If d.exists(A.Value) = True Then '二維陣列d的物件 若有包含這次的變數a
  16.          Ar = Split(d(A.Value), ";") '取出可用的數筆資料 直向的 可用筆數 X ABC三欄  
  17.          For i = 0 To UBound(Ar) '0到 陣列Ar的最大值
  18.          ReDim Preserve Ay(s) '保存動態陣列的內容 (為什麼儲存寫在前面 處理方式寫在下一行?)
  19.          Ay(s) = Split(A.Offset(, -2) & "," & A.Offset(, -1) & "," & Ar(i), ",")
  20.          s = s + 1 '目前列+1
  21.          Next
  22.          Else
  23.          If mystr = "" Then mystr = A Else mystr = mystr & "," & A '若d.exists(A.Value) = false 寫入一個警告顯示目前變數A
  24.         End If
  25.     Next
  26. End With
  27. With Sheet3
  28. .[A2:F65536] = "" '清空第三張表
  29. .[A2].Resize(s, 6) = Application.Transpose(Application.Transpose(Ay)) '第三張表 的A2欄 開始寫入轉換過的行列 轉換了兩次 超深奧 無法想像..
  30. MsgBox mystr & "沒找到" '彈出警告視窗
  31. End With
  32. End Sub
複製代碼
Hsieh 大大 目前應用正確了
這是我目前自己寫的注解 不知道是不是正確..
另外想請問一下
為什麼要先讀入全部的Sheet2的欄位,若Sheet2有好幾萬筆的時候 有沒有效能問題呀?
處理過程中 有把變數拆開 Split 又組合 Join 我不是很了解那些
有沒有什麼辦法 可以看到d(A.Value) 的值是怎麼變化的呢?

(我真的是超超超新手,旁邊的不要笑 )
作者: Hsieh    時間: 2010-6-13 21:48

效能如何就看你記憶體夠不夠
如果變數都完成宣告就會好一點




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