So khớp dữ liệu 2 mảng , tạo ra mảng kết quả vẫn giữ nguyên trật tự

Liên hệ QC

Nguyễn Hồng Quang

Thành viên GPE Hà Nội
Tham gia
8/6/07
Bài viết
1,203
Được thích
876
Giới tính
Nam
Nghề nghiệp
Kế toán
Em có 2 mảng dữ liệu gồm mảng 1 và mảng 2 như trong File và kết quả mong muốn so sánh giữa 2 mảng này. Em mong anh (chị) trong diễn đàn giúp đỡ em bằng vba với. Em xin cảm ơn
 

File đính kèm

  • so sanh mang-.xlsb
    501.2 KB · Đọc: 25
Sao dài thế không biết..
PHP:
Sub sosanh_()
    Const maxR As Long = 1048500 'so dong ket qua'
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    Dim lR As Long, i As Long, ii As Long, j As Long, k As Long, idex As Long
    Dim a(), b(), kq(), scode As String
    With Sheet1
        lR = .Range("A" & Rows.Count).End(xlUp).Row
        If lR < 3 Then MsgBox "Khong co du lieu!": Exit Sub
        a = .Range("A3:F" & lR).Value2
        lR = UBound(a, 1)
    End With
    ReDim b(1 To lR)
    ReDim kq(1 To maxR, 1 To 6)
    For i = 1 To lR
        scode = a(i, 4) & "--" & a(i, 5) & "--" & a(i, 6)
        HTbl.Add i, scode
        b(i) = scode
    Next i
    idex = 1
    For i = 1 To lR
        scode = a(i, 1) & "--" & a(i, 2) & "--" & a(i, 3)
        '1/ bang nhau tuong ung
         'idex = idex + 1
        If scode = b(idex) Then
            j = j + 1
            For k = 1 To 3
                kq(j, k) = a(i, k)
            Next k
            For k = 4 To 6
                kq(j, k) = a(idex, k)
            Next k
            idex = idex + 1
            HTbl(i) = ""  '/xoa scode trong thu vien
        '2/ khong bang nhau tuong ung -> di tim trong thu vien
        Else
            '2.1/ khong tim thay trong thu vien
            If HTbl.ContainsValue(scode) = False Then
                'mang 1 giu nguyen
                j = j + 1
                For k = 1 To 3
                    kq(j, k) = a(i, k)
                Next k
                'tang 1 dong mang 2
                j = j + 1
                For k = 4 To 6
                    kq(j, k) = a(i, k)
                Next k
                idex = idex + 1
                HTbl(i) = ""  '/xoa scode trong thu vien
            '2.2/ tim thay trong thu vien
            Else
                j = j + 1 'dong tuong ung dau tien
                For k = 4 To 6
                    kq(j, k) = a(i, k)
                Next k
                ' tim tu vi tri i+1 toi cuoi cung
                For ii = i + 1 To UBound(a, 1)
                    If scode = b(ii) Then 'neu tim thay
                        j = j + 1
                        For k = 1 To 3
                            kq(j, k) = a(i, k)
                        Next k
                        For k = 4 To 6
                            kq(j, k) = a(ii, k)
                        Next k
                        idex = ii + 1
                        HTbl(i) = ""
                        Exit For 'thoat tim
                    Else    'neu chua tim thay
                        j = j + 1
                        For k = 4 To 6
                            kq(j, k) = a(ii, k)
                        Next k
                    End If
                Next ii
            End If
        End If
        If idex > lR Then Exit For
        If j >= maxR Then
            MsgBox "Nhieu ket qua >> " & maxR & vbNewLine & _
                    "Chi lay " & maxR & "ket qua."
            Exit For
        End If
    Next i
    Sheet2.Range("A3").Resize(maxR, 6).ClearContents
    If j > 0 Then Sheet2.Range("A3").Resize(j, 6).Value = kq
End Sub
 
Upvote 0
Sao dài thế không biết..
PHP:
Sub sosanh_()
    Const maxR As Long = 1048500 'so dong ket qua'
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    Dim lR As Long, i As Long, ii As Long, j As Long, k As Long, idex As Long
    Dim a(), b(), kq(), scode As String
    With Sheet1
        lR = .Range("A" & Rows.Count).End(xlUp).Row
        If lR < 3 Then MsgBox "Khong co du lieu!": Exit Sub
        a = .Range("A3:F" & lR).Value2
        lR = UBound(a, 1)
    End With
    ReDim b(1 To lR)
    ReDim kq(1 To maxR, 1 To 6)
    For i = 1 To lR
        scode = a(i, 4) & "--" & a(i, 5) & "--" & a(i, 6)
        HTbl.Add i, scode
        b(i) = scode
    Next i
    idex = 1
    For i = 1 To lR
        scode = a(i, 1) & "--" & a(i, 2) & "--" & a(i, 3)
        '1/ bang nhau tuong ung
         'idex = idex + 1
        If scode = b(idex) Then
            j = j + 1
            For k = 1 To 3
                kq(j, k) = a(i, k)
            Next k
            For k = 4 To 6
                kq(j, k) = a(idex, k)
            Next k
            idex = idex + 1
            HTbl(i) = ""  '/xoa scode trong thu vien
        '2/ khong bang nhau tuong ung -> di tim trong thu vien
        Else
            '2.1/ khong tim thay trong thu vien
            If HTbl.ContainsValue(scode) = False Then
                'mang 1 giu nguyen
                j = j + 1
                For k = 1 To 3
                    kq(j, k) = a(i, k)
                Next k
                'tang 1 dong mang 2
                j = j + 1
                For k = 4 To 6
                    kq(j, k) = a(i, k)
                Next k
                idex = idex + 1
                HTbl(i) = ""  '/xoa scode trong thu vien
            '2.2/ tim thay trong thu vien
            Else
                j = j + 1 'dong tuong ung dau tien
                For k = 4 To 6
                    kq(j, k) = a(i, k)
                Next k
                ' tim tu vi tri i+1 toi cuoi cung
                For ii = i + 1 To UBound(a, 1)
                    If scode = b(ii) Then 'neu tim thay
                        j = j + 1
                        For k = 1 To 3
                            kq(j, k) = a(i, k)
                        Next k
                        For k = 4 To 6
                            kq(j, k) = a(ii, k)
                        Next k
                        idex = ii + 1
                        HTbl(i) = ""
                        Exit For 'thoat tim
                    Else    'neu chua tim thay
                        j = j + 1
                        For k = 4 To 6
                            kq(j, k) = a(ii, k)
                        Next k
                    End If
                Next ii
            End If
        End If
        If idex > lR Then Exit For
        If j >= maxR Then
            MsgBox "Nhieu ket qua >> " & maxR & vbNewLine & _
                    "Chi lay " & maxR & "ket qua."
            Exit For
        End If
    Next i
    Sheet2.Range("A3").Resize(maxR, 6).ClearContents
    If j > 0 Then Sheet2.Range("A3").Resize(j, 6).Value = kq
End Sub
Hình như chưa ổn vì ở ví dụ không quan tâm ký tự sau của số phiếu. Ví dụ ở K8:K10 so với N8:N10.
Sáng giờ cũng chưa tìm ra thuật toán :(
 
Upvote 0
Hình như chưa ổn vì ở ví dụ không quan tâm ký tự sau của số phiếu. Ví dụ ở K8:K10 so với N8:N10.
Sáng giờ cũng chưa tìm ra thuật toán :(
Không tìm được thuật toán, vì người hỏi không mô tả rõ ràng cách chèn dòng trắng sao?
Đẩy dòng trắng ưu tiên bên mảng 1 hay mảng 2 trước (hay theo điều kiện khác) - vì nó quyết định đến bước so sánh tiếp (có nhiều phương án đẩy/chèn dòng trắng)
Cứ nhìn cách đẩy (thêm dòng trắng) ở dữ liệu dòng 6 và dòng 11 (dữ liệu gốc) sẽ thấy trái nhau rồi.
 
Upvote 0
Em có 2 mảng dữ liệu gồm mảng 1 và mảng 2 như trong File và kết quả mong muốn so sánh giữa 2 mảng này. Em mong anh (chị) trong diễn đàn giúp đỡ em bằng vba với. Em xin cảm ơn
Ví dụ ở K8:K10 so với N8:N10 => không dựa vào 3 ký tự cuối của số phiếu. Nếu tuân theo quy tắc này thì ví dụ sai hoàn toàn, vì có rất nhiều mã trùng, và trùng 7 ký tự đầu của số phiếu.
 
Upvote 0
Ví dụ ở K8:K10 so với N8:N10 => không dựa vào 3 ký tự cuối của số phiếu. Nếu tuân theo quy tắc này thì ví dụ sai hoàn toàn, vì có rất nhiều mã trùng, và trùng 7 ký tự đầu của số phiếu.
hình như chủ topic chỉ đề nghị căn theo mã thôi
mã trùng không sao, cứ chèn dòng trắng vào, rồi so sánh dòng tương đương giống thì nhặt, không thì chèn trắng cả 2 bên, nhưng chèn thế nào thì lại vấn đề và hậu của việc chèn nữa(?)
tóm lại bài toán đa đáp số --> không giải là thượng sách
 
Upvote 0
Ví dụ ở K8:K10 so với N8:N10 => không dựa vào 3 ký tự cuối của số phiếu. Nếu tuân theo quy tắc này thì ví dụ sai hoàn toàn, vì có rất nhiều mã trùng, và trùng 7 ký tự đầu của số phiếu.
Bài này em chỉ so khớp phần mã hàng thôi anh à. Phần ký tự phiếu không cần so khớp à
 
Upvote 0
Bài này em chỉ so khớp phần mã hàng thôi anh à. Phần ký tự phiếu không cần so khớp à
Xem lại quy tắc so sánh, nếu chỉ so sánh mã hàng thì so sánh trong bao nhiêu dòng (kiểu như từng tháng, quý, group gì đó), còn nếu so luôn cột thì nhiều dòng trùng lắm.
 
Upvote 0
Không tìm được thuật toán, vì người hỏi không mô tả rõ ràng cách chèn dòng trắng sao?
Đẩy dòng trắng ưu tiên bên mảng 1 hay mảng 2 trước (hay theo điều kiện khác) - vì nó quyết định đến bước so sánh tiếp (có nhiều phương án đẩy/chèn dòng trắng)
Cứ nhìn cách đẩy (thêm dòng trắng) ở dữ liệu dòng 6 và dòng 11 (dữ liệu gốc) sẽ thấy trái nhau rồi.
Vì phần kết quả em phải làm bằng thủ công; nhanh tay, nhanh mắt nên có thể bị sót anh à. Về nguyên tắc thì mã nào nhỏ hơn thì ưu tiên chèn dòng trắng trước.
Bài đã được tự động gộp:

Xem lại quy tắc so sánh, nếu chỉ so sánh mã hàng thì so sánh trong bao nhiêu dòng (kiểu như từng tháng, quý, group gì đó), còn nếu so luôn cột thì nhiều dòng trùng lắm.
Dữ liệu trước khi đưa vào mảng 1 và 2 em đã sort theo số phiếu nhập kho và đồng thời sort theo mã hàng. Nên dữ liệu trong 2 mảng này luôn tuân theo nguyên tắc là số phiếu NK là từ nhỏ đến lớn và trong từng phiếu NK các mã hàng cũng theo trật tự từ nhỏ đến lớn rồi anh à.
Đây là dữ liệu nhập kho trong 1 năm do 2 người khác nhau theo dõi. Về lý thuyết là nó phải y hệt nhau (ví dụ phiếu NK1801/001 của người A có 1,2,3 mã hàng, số lượng 1,2,3 thì số phiếu NK1801/001 của người B cũng phải tương ứng) tuy nhiên thực tế lại có chênh lệch.
Trước mắt Em muốn so sánh ngang dòng (phần mã hàng) để nhanh chóng nhìn ra chênh lệch liên quan đến mã hàng (người A có mà người B không có)
theo kiểu đối chiếu (ngang hàng) mã - có trong A mà không có trong B và ngược lại - đưa ra 2 danh sách có số lượng phần tử như nhau tương ứng , trật tự A và B giữ nguyên
 
Lần chỉnh sửa cuối:
Upvote 0
Hình như chưa ổn vì ở ví dụ không quan tâm ký tự sau của số phiếu. Ví dụ ở K8:K10 so với N8:N10.
Sáng giờ cũng chưa tìm ra thuật toán :(
Nhòm nhòm.. một lúc tưởng chủ thớt muốn so sánh cả 3 cột giống nhau. :D

***
Chủ thớt nêu quy tắc dò xem nào? Rồi tự chỉnh chỗ nối 3 cột lại để tạo key so sánh chắc là được.
 
Upvote 0
Sao dài thế không biết..
PHP:
Sub sosanh_()
    Const maxR As Long = 1048500 'so dong ket qua'
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    Dim lR As Long, i As Long, ii As Long, j As Long, k As Long, idex As Long
    Dim a(), b(), kq(), scode As String
    With Sheet1
        lR = .Range("A" & Rows.Count).End(xlUp).Row
        If lR < 3 Then MsgBox "Khong co du lieu!": Exit Sub
        a = .Range("A3:F" & lR).Value2
        lR = UBound(a, 1)
    End With
    ReDim b(1 To lR)
    ReDim kq(1 To maxR, 1 To 6)
    For i = 1 To lR
        scode = a(i, 4) & "--" & a(i, 5) & "--" & a(i, 6)
        HTbl.Add i, scode
        b(i) = scode
    Next i
    idex = 1
    For i = 1 To lR
        scode = a(i, 1) & "--" & a(i, 2) & "--" & a(i, 3)
        '1/ bang nhau tuong ung
         'idex = idex + 1
        If scode = b(idex) Then
            j = j + 1
            For k = 1 To 3
                kq(j, k) = a(i, k)
            Next k
            For k = 4 To 6
                kq(j, k) = a(idex, k)
            Next k
            idex = idex + 1
            HTbl(i) = ""  '/xoa scode trong thu vien
        '2/ khong bang nhau tuong ung -> di tim trong thu vien
        Else
            '2.1/ khong tim thay trong thu vien
            If HTbl.ContainsValue(scode) = False Then
                'mang 1 giu nguyen
                j = j + 1
                For k = 1 To 3
                    kq(j, k) = a(i, k)
                Next k
                'tang 1 dong mang 2
                j = j + 1
                For k = 4 To 6
                    kq(j, k) = a(i, k)
                Next k
                idex = idex + 1
                HTbl(i) = ""  '/xoa scode trong thu vien
            '2.2/ tim thay trong thu vien
            Else
                j = j + 1 'dong tuong ung dau tien
                For k = 4 To 6
                    kq(j, k) = a(i, k)
                Next k
                ' tim tu vi tri i+1 toi cuoi cung
                For ii = i + 1 To UBound(a, 1)
                    If scode = b(ii) Then 'neu tim thay
                        j = j + 1
                        For k = 1 To 3
                            kq(j, k) = a(i, k)
                        Next k
                        For k = 4 To 6
                            kq(j, k) = a(ii, k)
                        Next k
                        idex = ii + 1
                        HTbl(i) = ""
                        Exit For 'thoat tim
                    Else    'neu chua tim thay
                        j = j + 1
                        For k = 4 To 6
                            kq(j, k) = a(ii, k)
                        Next k
                    End If
                Next ii
            End If
        End If
        If idex > lR Then Exit For
        If j >= maxR Then
            MsgBox "Nhieu ket qua >> " & maxR & vbNewLine & _
                    "Chi lay " & maxR & "ket qua."
            Exit For
        End If
    Next i
    Sheet2.Range("A3").Resize(maxR, 6).ClearContents
    If j > 0 Then Sheet2.Range("A3").Resize(j, 6).Value = kq
End Sub
Anh ơi ! nhờ anh xem lại giúp. Kết quả sau khi chạy code , bắt đầu bị lệch ở dòng số 6 anh à.
 

File đính kèm

  • Untitled2.png
    Untitled2.png
    90.1 KB · Đọc: 5
  • so sanh mang- - Copy.xlsb
    975.5 KB · Đọc: 6
Upvote 0
Nhòm nhòm.. một lúc tưởng chủ thớt muốn so sánh cả 3 cột giống nhau. :D

***
Chủ thớt nêu quy tắc dò xem nào? Rồi tự chỉnh chỗ nối 3 cột lại để tạo key so sánh chắc là được.
Để em suy nghĩ về quy tắc dò và viết ra, hoặc tìm cách quay 1 cái clip và gửi lên. Cái này thực sự khó diễn tả bằng lời lắm anh à. Nên em cố gắng làm ra cái kết quả để hy vọng mọi người có thể hiểu ý tưởng
 
Lần chỉnh sửa cuối:
Upvote 0
Vì phần kết quả em phải làm bằng thủ công; nhanh tay, nhanh mắt nên có thể bị sót anh à. Về nguyên tắc thì mã nào nhỏ hơn thì ưu tiên chèn dòng trắng trước.
Bài đã được tự động gộp:


Dữ liệu trước khi đưa vào mảng 1 và 2 em đã sort theo số phiếu nhập kho và đồng thời sort theo mã hàng. Nên dữ liệu trong 2 mảng này luôn tuân theo nguyên tắc là số phiếu NK là từ nhỏ đến lớn và trong từng phiếu NK các mã hàng cũng theo trật tự từ nhỏ đến lớn rồi anh à.
Đây là dữ liệu nhập kho trong 1 năm do 2 người khác nhau theo dõi. Về lý thuyết là nó phải y hệt nhau (ví dụ phiếu NK1801/001 của người A có 1,2,3 mã hàng, số lượng 1,2,3 thì số phiếu NK1801/001 của người B cũng phải tương ứng) tuy nhiên thực tế lại có chênh lệch.
Trước mắt Em muốn so sánh ngang dòng (phần mã hàng) để nhanh chóng nhìn ra chênh lệch liên quan đến mã hàng (người A có mà người B không có)
theo kiểu đối chiếu (ngang hàng) mã - có trong A mà không có trong B và ngược lại - đưa ra 2 danh sách có số lượng phần tử như nhau tương ứng , trật tự A và B giữ nguyên
Hiện file dữ liệu của bạn chưa được sắp xếp như bạn nói:
Dữ liệu trước khi đưa vào mảng 1 và 2 em đã sort theo số phiếu nhập kho và đồng thời sort theo mã hàng. Nên dữ liệu trong 2 mảng này luôn tuân theo nguyên tắc là số phiếu NK là từ nhỏ đến lớn và trong từng phiếu NK các mã hàng cũng theo trật tự từ nhỏ đến lớn rồi anh à.
vậy hiểu sao?
Để em suy nghĩ về quy tắc dò và viết ra, hoặc tìm cách quay 1 cái clip và gửi lên. Cái này thực sự khó diễn tả bằng lời lắm anh à. Nên em cố gắng làm ra cái kết quả để hy vọng mọi người có thể hiểu ý tưởng
Đã mô tả xong chưa?
 
Upvote 0
Web KT
Back
Top Bottom