返回列表 上一主題 發帖

[發問] 根據"料號欄"為依據,做排序

[發問] 根據"料號欄"為依據,做排序

大大們好,

請教如下....
來源檔為商品2!新月工作表       
我有許多的檔案都需要根據"料號欄"的料號順序為依據,做排序       
需排序的每個檔的表頭位置,及內容都不太同,       
目的檔排序的準則為整列排序,若有未出現的料號,則略過       
例:        標示黃底,都是目的檔庫存表沒有的品項,則目的檔的這些料號,就略過,跳下個料號繼續排序
        由於目的檔也會有些工作表與料號無關,不需排序,
        所以需排序的工作表,以"新月"M1:M2所指定的起迄工作表作為排序對象
        並且自動找尋表頭有"料號"字樣,就依"新月"的料號順序整列排序

依新月工作表_料號排序.rar (326.8 KB)

本帖最後由 PJChen 於 2021-4-6 23:16 編輯

不好意思,我想我表達得不夠清楚,補充如下:
目的檔的路徑如下,它沒有指定特定檔案,這個路徑底下的所有檔案,都是要以新月的料號欄排序的,
T:\0_自訂表單\日常表格\
檔案打開以後,以"新月"M1:M2所指定的起迄工作表作為排序對象,
EX:
1) 現在我只放一個範例檔"庫存表",以不指定檔名的方式開啟
2) 以"新月"M1:M2所指定的起迄工作表,為2~6,
3) 將庫存表從第2~第6的工作表的料號欄,比對新月的料號欄的順序來排序
4) 新月的料號欄是排序的準則,它的料號比較多,庫存表是要依新月的料號欄順序做排序,當新月的料號欄是目的檔料號欄所沒有的料號,則跳下個料號繼續排序

由於我有許多的檔案都需要同樣的排序方式,但各種檔案格式不相同,但需要排序的工作表,都指定在"新月"M1:M2為起迄,但因為格式不相同,打開檔案後,
除了依工作表起迄作排序,需要能自動找到"料號"字樣的功能,才能依據料號欄作整列排序

TOP

本帖最後由 軒云熊 於 2021-4-8 17:01 編輯

回復 1# PJChen
有空幫我試試看是不是你要的結果 會很慢因為迴圈太多了 看看有沒有大大願意幫忙 感謝
  1. Public Sub 跨工作簿比對並移動練習()
  2.     Application.ScreenUpdating = False
  3.    
  4.     Sheets.Copy After:=Sheets(Sheets.Count)
  5.     For X = [H65535].End(3).Row To 1 Step -1
  6.         If IsError(Cells(X, "H")) Then
  7.             Rows(X).Delete
  8.         End If
  9.     Next X
  10.     Range([A65535].End(3), [A4]).Sort [A4], 1, Header:=2
  11.    
  12.    
  13.     Set xD = CreateObject("Scripting.Dictionary")
  14.     Arr = Range([A65535].End(3), [A1])
  15.    
  16.     Application.DisplayAlerts = False
  17.     Sheets(Sheets.Count).Delete
  18.     Application.DisplayAlerts = True
  19.    
  20.     For X = 1 To UBound(Arr, 1)
  21.             xD(Arr(X, 1)) = Trim(xD(Arr(X, 1)) & " " & X)
  22.     Next X
  23.     Erase Arr
  24.    
  25.     A = Dir("T:\0_自訂表單\日常表格\*.xlsx")
  26.     Workbooks.Open "T:\0_自訂表單\日常表格\" & A & ""
  27.     Set W = Workbooks("商品2.xlsm").Sheets(1)
  28.    
  29.     For E = 1 To Sheets.Count
  30.         N = Sheets(E).Name: Sheets(E).Activate
  31.         If IsNumeric(N) Then
  32.             If Int(N) > W.[M2] Then Exit For
  33.             If Int(N) >= W.[M1] And Int(N) <= W.[M2] Then
  34.                 Arr = ActiveSheet.UsedRange
  35.                 For X = 1 To UBound(Arr, 1)
  36.                     For Y = 1 To UBound(Arr, 2)
  37.                         If Arr(X, Y) = "料號" Then
  38.                             Brr = Range(Cells(1, Y), Cells(Rows.Count, Y).End(3))
  39.                             GoTo A01
  40.                         End If
  41.                     Next Y
  42.                 Next X
  43. A01:            Y = Y: Erase Arr
  44.                
  45.                 For Each D In xD
  46.                 SR = Split(xD(D), " ")
  47.                     For Each S In SR
  48.                         SInt = Int(S)
  49.                         For Z = UBound(Brr) To 1 Step -1
  50.                         On Error Resume Next
  51.                             If D <> Empty Then
  52.                                 If D = Brr(Z, 1) Then
  53.                                     Rows(Z).Cut
  54.                                     Rows(SInt).Insert , 1
  55.                                     Brr = Range(Cells(1, Y), Cells(Rows.Count, Y).End(3))
  56.                                     Exit For
  57.                                 End If
  58.                             End If
  59.                         On Error GoTo 0
  60.                         Next Z
  61.                     Next S
  62.                 Next D
  63.         
  64.             End If
  65.         End If
  66.     Next E
  67.    
  68.     Application.ScreenUpdating = True
  69. End Sub
複製代碼
商品20408.rar (38.23 KB)

TOP

本帖最後由 PJChen 於 2021-4-8 23:43 編輯

回復 3# 軒云熊
您好,
來源檔指定起迄工作表,這個寫法,會使它去尋找數字工作表,起迄工作表,希望能數第x~第x個工作表,
因為有些工作表是非數字的,請問要怎麼改?
    For E = 1 To Sheets.Count
        N = Sheets(E).Name: Sheets(E).Activate
        If IsNumeric(N) Then
            If Int(N) > W.[M2] Then Exit For
            If Int(N) >= W.[M1] And Int(N) <= W.[M2] Then

另外請問,這段如何解讀? 是否為來源檔的H欄? 來源檔除了A欄料號是用來作為排序準則,及M1、M2用來數工作表起迄外,其餘欄位都不能用的!
    For X = [H65535].End(3).Row To 1 Step -1
        If IsError(Cells(X, "H")) Then
            Rows(X).Delete
        End If
    Next X
    Range([A65535].End(3), [A4]).Sort [A4], 1, Header:=2

TOP

回復 4# PJChen

    For E = 1 To Sheets.Count
        N = Sheets(E).Name: Sheets(E).Activate
        If IsNumeric(N) Then
            If Int(N) > W.[M2] Then Exit For
            If Int(N) >= W.[M1] And Int(N) <= W.[M2] Then
可以改成
    For E = 1 To Sheets.Count
        Sheets(E).Activate
        If E > W.[M2] Then Exit For
        If E >= W.[M1] And E <= W.[M2] Then

這段
    For X = [H65535].End(3).Row To 1 Step -1
        If IsError(Cells(X, "H")) Then
            Rows(X).Delete
        End If
    Next X
    Range([A65535].End(3), [A4]).Sort [A4], 1, Header:=2

是用 H欄 做排序後的依據 因為可以排除沒有的資料
或著 你可以改成

    Sheets.Copy After:=Sheets(Sheets.Count)
    For X = [H65535].End(3).Row To 1 Step -1
        If IsError(Cells(X, "A")) Then
            Rows(X).Delete
        End If
    Next X
    Range([A65535].End(3), [A4]).Sort [A4], 1, Header:=2
其實也沒差 因為 If D = Brr(Z, 1) Then 已經可以跳過了

我有稍微修改了一下這段

            For Each D In xD
                SR = Split(xD(D), " ")
                For Each S In SR
                    SInt = Int(S)
                    If D = Empty Then Exit For
                    With Range(Cells(1, Y), Cells(Rows.Count, Y).End(3))
                        On Error Resume Next
                        Set C = .Find(D)
                        G = .FindNext(C).Address
                        If C = D Then
                            If Not C Is Nothing Then
                                Rows(C.Row).Cut
                                Set C = .FindNext(G)
                                Rows(SInt).Insert , 1
                            End If
                        End If
                        On Error GoTo 0
                    End With
                Next S
            Next D


但還是很慢 ..如果資料量大會非常慢... .看看有沒有大大可以幫忙

TOP

回復 5# 軒云熊
不好意思
我原來想得很多,結果程式就變得很複雜,我想改為單純化,只要
1) 依來源檔"商品2"的A欄作為排序依據
2) 以庫存檔的"整月統計"(意思是指定單一工作表就好)",搜尋料號欄來整列排序
3) 庫存檔的料號與來源檔對不上時,一律排在下方
4) 若料號相同,則以來源的料號順序來排序
5) 能否在程式中註解,我想了解程式作用

現在可以排序,但結果是錯誤的,而且會將"整月統計"中表格的最後一列踢到第77列,能否幫忙看看?
我把排序後的正確結果放在"整月統計"

依新月工作表_料號排序.rar (287.38 KB)

TOP

回復 6# PJChen

有空再幫我試試看是不是你要的結果謝謝
  1. Public Sub 跨工作簿比對並移動練習0409()
  2.     Application.ScreenUpdating = False
  3.     '新增一個工作表排列後 存到陣列在刪除工作表
  4.     Sheets.Copy After:=Sheets(Sheets.Count)
  5.     Range([A65535].End(3), [A4]).Sort [A4], 1, Header:=2

  6.     Set xD = CreateObject("Scripting.Dictionary")
  7.     Arr = Range([A65535].End(3), [A1])
  8.    
  9.     Application.DisplayAlerts = False
  10.     Sheets(Sheets.Count).Delete
  11.     Application.DisplayAlerts = True
  12. '--------------------------------------------------------
  13.     '把排列後的資料存到字典裡
  14.     For X = 1 To UBound(Arr, 1)
  15.         xD(Arr(X, 1)) = Trim(xD(Arr(X, 1)) & " " & X)
  16.     Next X
  17.     Erase Arr
  18. '--------------------------------------------------------
  19.     '尋找檔案的位置然後開啟
  20.     A = Dir(ThisWorkbook.Path & "\" & "*.xlsx")
  21.     Workbooks.Open ThisWorkbook.Path & "\" & A
  22. '--------------------------------------------------------
  23.     '切換到指定工作表 把含有"料號"的那一欄位置記下來
  24.     Sheets("整月統計").Activate '這裡可以指定要排列的工作表的位置 "整月統計" 或 "3"
  25.     Arr = ActiveSheet.UsedRange
  26.     For X = 1 To UBound(Arr, 1)
  27.         For Y = 1 To UBound(Arr, 2)
  28.             If Arr(X, Y) = "料號" Then
  29.                 Y = Y
  30.                 X = X + 1
  31.                 GoTo A01
  32.             End If
  33.         Next Y
  34.     Next X
  35. A01: Erase Arr
  36. '--------------------------------------------------------
  37.     '尋找比對後並重新排列
  38.     For Each D In xD
  39.         SR = Split(xD(D), " ")
  40.         For Each S In SR
  41.             If D = Empty Then Exit For
  42.             With Range(Cells(1, Y), Cells(Rows.Count, Y).End(3))
  43.                 On Error Resume Next
  44.                 Set C = .Find(D)
  45.                 G = .FindNext(C).Address
  46.                 If C = D Then
  47.                     If Not C Is Nothing Then
  48.                         Rows(C.Row).Cut
  49.                         Set C = .FindNext(G)
  50.                         K = K + 1
  51.                         Rows(X + K).Insert , 1
  52.                     End If
  53.                 End If
  54.                 Application.CutCopyMode = False
  55.                 On Error GoTo 0
  56.             End With
  57.         Next S
  58.     Next D
  59.     Set C = Nothing
  60.    
  61.     Application.ScreenUpdating = True
  62. End Sub
複製代碼
0409.rar (287.7 KB)

TOP

        靜思自在 : 為人處世要小心細心,但不要「小心眼」。
返回列表 上一主題