Đối chiếu hàng tồn kho theo mã ,xác định các chênh lệch và đánh dấu (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

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
877
Giới tính
Nam
Nghề nghiệp
Kế toán
Em có 1 bảng tính đang đối chiếu dữ liệu, em cần đánh dấu vào cột G các dòng mà có các ô ở cột E, F xuất hiện giá trị False. Chi tiết em đã ghi chú trong bảng tính. Rất mong các anh , chị và các bạn giúp đỡ
Em xin cảm ơn
 

File đính kèm

Sao không dùng công thức này:

=IF(AND(A2=C2,B2=D2),"","x")

mà dùng 2 cột phụ và 1 cột kết quả (cột thứ 3)?
 
Upvote 0
Sao không dùng công thức này:

=IF(AND(A2=C2,B2=D2),"","x")

mà dùng 2 cột phụ và 1 cột kết quả (cột thứ 3)?
Cảm ơn anh
em muốn dùng code vì khi xuất hiện trường hợp (không xuất hiện mã hàng đối ứng)em sẽ chèn dòng ở chỗ đó (ví dụ dòng 55 trong bảng tính em gửi). Với lại Nếu dùng công thức thì khi ấn Ctrl+ xuống ;nó sẽ trôi tuột xuống dòng cuối của bảng, còn nếu chỉ đánh dấu theo vị trí thì khi ấn Ctrl+xuống; nó sẽ đến đúng vị trí bị lệch luôn
 
Upvote 0
Upvote 0
Bỏ 2 cột phụ, thử:
Mã:
Public Sub DanhDauX()
Dim i As Long
Dim lr As Long
Dim sArr, dArr
lr = Range("A" & Rows.Count).End(xlUp).Row
sArr = Range("A2:D" & lr).Value
lr = UBound(sArr, 1)
ReDim dArr(1 To lr, 1 To 1)
For i = 1 To lr
    If sArr(i, 1) <> sArr(i, 3) Or sArr(i, 2) <> sArr(i, 4) Then dArr(i, 1) = "X"
Next
Range("G2").Resize(lr, 1) = dArr
End Sub
 
Upvote 0
Em có 1 bảng tính đang đối chiếu dữ liệu, em cần đánh dấu vào cột G các dòng mà có các ô ở cột E, F xuất hiện giá trị False. Chi tiết em đã ghi chú trong bảng tính. Rất mong các anh , chị và các bạn giúp đỡ
Em xin cảm ơn
record macro + xào xáo dược code này
nhớ tháo auto filter trước khi chạy
Mã:
Option Explicit

Sub Macro1()
Dim rws
With Sheet1
    rws = .Range("A1000000").End(xlUp).Row
    Range("A1", "G" & rws).AutoFilter Field:=6, Criteria1:="FALSE"
    Range("G4:G10943") = "x"
    Range("A1", "G" & rws).AutoFilter Field:=6
    Range("A1", "G" & rws).AutoFilter Field:=5, Criteria1:="FALSE"
    Range("G4:G10943") = "x"
    Range("A1", "G" & rws).AutoFilter
End With
End Sub
 
Upvote 0
Cảm ơn anh phuocam nhiều. Code chạy đúng kết quả em mong muốn rồi ạ. Chúc anh ngày vui
Bài đã được tự động gộp:

record macro + xào xáo dược code này
nhớ tháo auto filter trước khi chạy
Cảm ơn bạn đã giúp đỡ, chúc bạn cuối tuần vui vẻ nhé
 
Upvote 0
Cảm ơn anh phuocam nhiều. Code chạy đúng kết quả em mong muốn rồi ạ. Chúc anh ngày vui
Bài đã được tự động gộp:


Cảm ơn bạn đã giúp đỡ, chúc bạn cuối tuần vui vẻ nhé
Thử một cách khác:
Mã:
Sub DanhDau()
Dim row As Integer
Dim DongCuoi As Long
DongCuoi = Sheet1.Range("B" & Rows.Count).End(xlUp).row
For row = 2 To DongCuoi
    If StrComp("TRUE", Cells(row, 5).Value, vbTextCompare) Or _
    StrComp("TRUE", Cells(row, 6).Value, vbTextCompare) Then
        Cells(row, 7).Value = "X"
    End If
Next row
End Sub
 
Upvote 0
Bỏ 2 cột phụ, thử:
Mã:
Public Sub DanhDauX()
Dim i As Long
Dim lr As Long
Dim sArr, dArr
lr = Range("A" & Rows.Count).End(xlUp).Row
sArr = Range("A2:D" & lr).Value
lr = UBound(sArr, 1)
ReDim dArr(1 To lr, 1 To 1)
For i = 1 To lr
    If sArr(i, 1) <> sArr(i, 3) Or sArr(i, 2) <> sArr(i, 4) Then dArr(i, 1) = "X"
Next
Range("G2").Resize(lr, 1) = dArr
End Sub
Anh ơi! em áp dụng code của anh, nhưng khi tăng số lượng cột so khớp lên thì code bị lỗi
Anh xem giúp em với nhé. Chi tiết em trình bày trong file
 

File đính kèm

Upvote 0
Tặng bạn file này, hiển thị % công việc hoàn thành.
Link download:
Mã:
https://www.mediafire.com/file/45qd15y5vg60g99/ProgreesBar.rar/file
Các bạn đăng ký theo dõi kênh để cập nhật các video bài học mới nhất về VBA nhé.
 
Upvote 0
Sửa thành:

If sArr(i, 1) <> sArr(i, 4) Or sArr(i, 2) <> sArr(i, 5) Or Round(sArr(i, 3) - sArr(i, 6), 10) <> 0 Then dArr(i, 1) = "x"
 
Lần chỉnh sửa cuối:
Upvote 0
Anh ơi! em áp dụng code của anh, nhưng khi tăng số lượng cột so khớp lên thì code bị lỗi
Anh xem giúp em với nhé. Chi tiết em trình bày trong file
Máy tính xử lý các con số gần đúng nên so sánh "=" hoặc "<>" có lúc loạn cào cào
Có thể chuyển thành chuổi
CStr(sArr(i, 3)) <> CStr(sArr(i, 6))
Hoặc qui định 1 sai số E
Abs(sArr(i, 3) - sArr(i, 6)) > E
 
Upvote 0
Sửa thành:

If sArr(i, 1) <> sArr(i, 4) Or sArr(i, 2) <> sArr(i, 5) Or Round(sArr(i, 3) - sArr(i, 6), 10) <> 0 Then dArr(i, 1) = "x"
Thêm một lần Cảm ơn anh. Nhưng mà cái này thú vị thật. Rõ ràng trên bảng tính , Excel xác nhận là 124409.36=124409.36 = TRUE nhưng khi đưa vào VBA lại False
 
Upvote 0
Anh ơi! em áp dụng code của anh, nhưng khi tăng số lượng cột so khớp lên thì code bị lỗi
Anh xem giúp em với nhé. Chi tiết em trình bày trong file
Sửa code bài 9 lại 1 tí:
Mã:
Sub DanhDau()
Dim row As Integer
Dim DongCuoi As Long
DongCuoi = Sheet1.Range("B" & Rows.Count).End(xlUp).row
For row = 2 To DongCuoi
    If StrComp("TRUE", Cells(row, 7).Value, vbTextCompare) Or _
    StrComp("TRUE", Cells(row, 8).Value, vbTextCompare) Or _
    StrComp("TRUE", Cells(row, 9).Value, vbTextCompare) Then
        Cells(row, 10).Value = "X"
    End If
Next row
End Sub
 
Upvote 0
Máy tính xử lý các con số gần đúng nên so sánh "=" hoặc "<>" có lúc loạn cào cào
Có thể chuyển thành chuổi
CStr(sArr(i, 3)) <> CStr(sArr(i, 6))
Hoặc qui định 1 sai số E
Abs(sArr(i, 3) - sArr(i, 6)) > E
Cảm ơn anh. Hôm nay gặp mới biết. Cái này đúng là ngoài tầm hiểu biết của em, rõ ràng trên bảng tính em đã xem đến hàng thập phân thứ 20 mà hai số vẫn cứ là 124409.36000000000000000000000000.
Bài đã được tự động gộp:

Sửa code bài 9 lại 1 tí:
Mã:
Sub DanhDau()
Dim row As Integer
Dim DongCuoi As Long
DongCuoi = Sheet1.Range("B" & Rows.Count).End(xlUp).row
For row = 2 To DongCuoi
    If StrComp("TRUE", Cells(row, 7).Value, vbTextCompare) Or _
    StrComp("TRUE", Cells(row, 8).Value, vbTextCompare) Or _
    StrComp("TRUE", Cells(row, 9).Value, vbTextCompare) Then
        Cells(row, 10).Value = "X"
    End If
Next row
End Sub
Vâng code này của anh ra đúng ạ
 
Upvote 0
Cảm ơn anh. Hôm nay gặp mới biết. Cái này đúng là ngoài tầm hiểu biết của em, rõ ràng trên bảng tính em đã xem đến hàng thập phân thứ 20 mà hai số vẫn cứ là 124409.36000000000000000000000000.
Bài đã được tự động gộp:


Vâng code này của anh ra đúng ạ
Sai số nầy nằm trong code, còn trên bảng tính có lẽ ngài Bil đã loại lỗi nầy
Thử code sẽ rỏ hơn
Mã:
Sub Button1_Click()
Dim i As Long
Dim lr As Long
Dim sArr, dArr
lr = Range("A" & Rows.Count).End(xlUp).Row
sArr = Range("A2:F" & lr).Value
lr = UBound(sArr, 1)
ReDim dArr(1 To lr, 1 To 1)
For i = 1 To lr
    '****
    If i = 1051 Then
      e = sArr(i, 3) - sArr(i, 6)
    End If
    '****
    If sArr(i, 1) <> sArr(i, 4) Or sArr(i, 2) <> sArr(i, 5) Or sArr(i, 3) <> sArr(i, 6) Then dArr(i, 1) = "x"
Next
Range("J2").Resize(lr, 1) = dArr
MsgBox (lr)
End Sub
 
Upvote 0
Sai số nầy nằm trong code, còn trên bảng tính có lẽ ngài Bil đã loại lỗi nầy
Thử code sẽ rỏ hơn
Mã:
Sub Button1_Click()
Dim i As Long
Dim lr As Long
Dim sArr, dArr
lr = Range("A" & Rows.Count).End(xlUp).Row
sArr = Range("A2:F" & lr).Value
lr = UBound(sArr, 1)
ReDim dArr(1 To lr, 1 To 1)
For i = 1 To lr
    '****
    If i = 1051 Then
      e = sArr(i, 3) - sArr(i, 6)
    End If
    '****
    If sArr(i, 1) <> sArr(i, 4) Or sArr(i, 2) <> sArr(i, 5) Or sArr(i, 3) <> sArr(i, 6) Then dArr(i, 1) = "x"
Next
Range("J2").Resize(lr, 1) = dArr
MsgBox (lr)
End Sub
Cảm ơn anh. Em vẫn đang làm so khớp cho phần còn lại của cái bảng tính này. Khi nào xong em sẽ nghiên cứu kiến thức mới của anh
Ngoài ra khi xong bảng tính này, em sẽ gửi kết quả và mong các anh giúp đỡ cách làm để ra được kết quả cuối cùng luôn. Như hiện nay là em đang áp dụng các code ở trên và thao tác khá nhiều lần trên bảng tính.
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn anh. Hôm nay gặp mới biết. Cái này đúng là ngoài tầm hiểu biết của em, rõ ràng trên bảng tính em đã xem đến hàng thập phân thứ 20 mà hai số vẫn cứ là 124409.36000000000000000000000000.
...
Số trên máy tính chỉ chính xác đến chữ số thứ 15. Hàng thập phân thứ 20 chỉ bằng thừa.
Máy tính nó như vậy. Cái này Biêu hay Biếc chả làm gì được (ngoài cách đi vòng, dùng kiểu Variant và hàm CDec, nới ra được thành khoảng gần 30 chữ số)
 
Upvote 0
Trước khi tiếp tục chủ đề này em xin cảm ơn các anh phuocam, be09, hieucd và bạn chaoquay. Bởi code và hỗ trợ của mọi người đã giúp em giảm khá nhiều thời gian để tìm ra kết quả mong muốn cho cái bảng tính ở trên #1.
Sau khi ra kết quả,vui mừng hơn là em còn thời gian để rủ bạn bè đi ăn uống (cuối tuần)
Ăn chơi , nghỉ ngơi xong; em xin phép được trở lại với vấn đề này.
Là từ bảng dữ liệu ban đầu; có phương án VBA nào để có thể cho ra được bảng kết quả (như file em gửi kèm dưới đây).
Các chi tiết về dữ liệu, thao tác làm em đã trình bày trong file gửi kèm.
Rất mong nhận được sự giúp đỡ của các anh và các bạn trên GPE
chúc cả nhà Chủ Nhật vui vẻ
 

File đính kèm

Upvote 0
Trước khi tiếp tục chủ đề này em xin cảm ơn các anh phuocam, be09, hieucd và bạn chaoquay. Bởi code và hỗ trợ của mọi người đã giúp em giảm khá nhiều thời gian để tìm ra kết quả mong muốn cho cái bảng tính ở trên #1.
Sau khi ra kết quả,vui mừng hơn là em còn thời gian để rủ bạn bè đi ăn uống (cuối tuần)
Ăn chơi , nghỉ ngơi xong; em xin phép được trở lại với vấn đề này.
Là từ bảng dữ liệu ban đầu; có phương án VBA nào để có thể cho ra được bảng kết quả (như file em gửi kèm dưới đây).
Các chi tiết về dữ liệu, thao tác làm em đã trình bày trong file gửi kèm.
Rất mong nhận được sự giúp đỡ của các anh và các bạn trên GPE
chúc cả nhà Chủ Nhật vui vẻ
Sao không đưa bài toàn từ thuở sơ khai (tức là đưa dữ liệu thô ban đầu) rồi xử lý để có kết quả cuối cùng là gì?

Ở sheets "KQ" e rằng vẫn chưa phải là kết quả cuối cùng, không biết cái mẫu báo cáo cuối cùng dzư lào?

Xem qua thì đây là bài toán đối chiếu 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 để đối chiếu số lượng tưng ứng với mỗi dòng trong 2 danh sách kia.

Vậy đưa luôn bài toàn từ đầu làm một lượt chứ việc oánh dấu "x" nó chỉ là môt phương án, mà cho tới bây giờ phương án ấy chưa chắc ổn/ tối ưu.
 
Upvote 0
Sao không đưa bài toàn từ thuở sơ khai (tức là đưa dữ liệu thô ban đầu) rồi xử lý để có kết quả cuối cùng là gì?
Cảm ơn anh befaint đã góp ý. Đúng như anh nói, đây không phải là dữ liệu thô ban đầu, nhưng mà nó cũng gần như thô rồi anh à; 6 cột của sheet Database được filter từ số dư đầu kỳ của bảng dữ liệu tồn kho năm 2017 và 2018. Và trước khi đưa vào file này em chỉ sort A-Z, trim (mã) thôi.
Vậy đưa luôn bài toàn từ đầu làm một lượt chứ việc oánh dấu "x" nó chỉ là môt phương án, mà cho tới bây giờ phương án ấy chưa chắc ổn/ tối ưu.
Vâng! đánh dấu x chỉ là phương pháp em làm thủ công để ra sheet Kết quả. Em xin gửi lại file
1 file là dữ liệu và kết quả mong muốn
1 file là cái em làm thủ công để ra kết quả mong muốn
Ở sheets "KQ" e rằng vẫn chưa phải là kết quả cuối cùng, không biết cái mẫu báo cáo cuối cùng dzư lào?
Anh ơi! cái này là kết quả cuối cùng mà em mong muốn của việc đối chiếu rồi anh à! Từ các chênh lệch này em sẽ tiến hành điều chỉnh dữ liệu tồn kho
Xem qua thì đây là bài toán đối chiếu 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 để đối chiếu số lượng tưng ứng với mỗi dòng trong 2 danh sách kia.
Vâng đây chính là bản chất của bài toán. Tại vì từ đầu em chưa biết cái kết quả cuối cùng nó hình thù ra sao , nên làm thủ công để ra kết quả trước, rồi sau đó gửi cái kết quả lên lên GPE mong các anh cho phương án.
Em rất vui nhận được sự quan tâm từ anh
Em gửi lại
1 file là dữ liệu và kết quả mong muốn
1 file là cái em làm thủ công để ra kết quả mong muốn
 

File đính kèm

Upvote 0
Cảm ơn anh befaint đã góp ý. Đúng như anh nói, đây không phải là dữ liệu thô ban đầu, nhưng mà nó cũng gần như thô rồi anh à; 6 cột của sheet Database được filter từ số dư đầu kỳ của bảng dữ liệu tồn kho năm 2017 và 2018. Và trước khi đưa vào file này em chỉ sort A-Z, trim (mã) thôi.

Vâng! đánh dấu x chỉ là phương pháp em làm thủ công để ra sheet Kết quả. Em xin gửi lại file
1 file là dữ liệu và kết quả mong muốn
1 file là cái em làm thủ công để ra kết quả mong muốn

Anh ơi! cái này là kết quả cuối cùng mà em mong muốn của việc đối chiếu rồi anh à! Từ các chênh lệch này em sẽ tiến hành điều chỉnh dữ liệu tồn kho

Vâng đây chính là bản chất của bài toán. Tại vì từ đầu em chưa biết cái kết quả cuối cùng nó hình thù ra sao , nên làm thủ công để ra kết quả trước, rồi sau đó gửi cái kết quả lên lên GPE mong các anh cho phương án.
Em rất vui nhận được sự quan tâm từ anh
Em gửi lại
1 file là dữ liệu và kết quả mong muốn
1 file là cái em làm thủ công để ra kết quả mong muốn
Chôm Code của bạn @befaint, thêm vài lệnh
Mã:
Sub SortedListFilter()
  Dim oSList As Object, sKey As String
  Dim sArr1(), sArr2(), Result(), S
  Dim i As Long, sRow As Long, n As Long, j As Long
 
  Set oSList = CreateObject("System.Collections.SortedList")
  With Sheets("database")
    sArr1 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
    For i = 1 To UBound(sArr1)
      sKey = Application.Trim(sArr1(i, 1))
      If sKey <> "" Then
        If oSList.ContainsKey(sKey) = False Then oSList.Add sKey, Array(i, 0)
      End If
    Next i
    
    sArr2 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
    For i = 1 To UBound(sArr2)
      sKey = Application.Trim(sArr2(i, 1))
      If sKey <> "" Then
        If oSList.ContainsKey(sKey) = False Then
          oSList.Add sKey, Array(0, i)
        Else
          oSList.Item(sKey) = Array(oSList.Item(sKey)(0), i)
        End If
      End If
    Next i
  End With
 
  n = oSList.Count - 1
  ReDim Result(0 To n, 1 To 6)
  For i = 0 To n
    S = oSList.GetByIndex(i)
    If S(0) > 0 Then
      For j = 1 To 3
        Result(i, j) = sArr1(S(0), j)
      Next j
    End If
    If S(1) > 0 Then
      For j = 1 To 3
        Result(i, j + 3) = sArr2(S(1), j)
      Next j
    End If
  Next i
 
  With Sheets("KQ")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    j = .Range("D" & Rows.Count).End(xlUp).Row
    If i < j Then i = j
    If i > 1 Then .Range("A2:F" & i).Clear
    .Range("A2").Resize(n + 1, 1).NumberFormat = "@"
    .Range("D2").Resize(n + 1, 1).NumberFormat = "@"
    .Range("A2").Resize(n + 1, 6) = Result
  End With
End Sub
 
Upvote 0
Code này chạy tốc độ không nhanh như của @HieuCD , sử dụng hoàn toàn các hàm tự tạo theo logic bạn nêu ra.
Sheet Database mình sửa tên thành "DATA" như một thói quen.
Link dowload file excel:
https://www.mediafire.com/file/236gyiwlc453bsw/Sapxedulieu.rar/file

Mã:
Sub main()
    Dim i As Integer
    Dim j   As Integer
   
    Dim rend As Integer
    Dim rend2   As Integer
   
    Dim darr    'all-du lieu tu cot A ->F

    Dim kqarr   'Du lieu de ghi ra sheet KQ
    Dim allarr  'Dieu lieu ma nxt all tren cot A,D
   
    Dim cota_arr    'du lieu cot A->C
    Dim cotd_arr    'du lieu cot D->F
   
   
    Dim outs    As String 'ghi lai toan bo ma nxt tren cot A va D
    Dim sfind   As String   ' ma nxt
    Dim cnt     As Integer
    Dim cnt1    As Integer  'cot A
    Dim cnt2    As Integer  'cot D
    Dim arrkq
 
    'Xac dinh dong cuoi cua du lieu
   
    rend = ThisWorkbook.Sheets("DATA").Range("A" & Rows.Count).End(xlUp).row
    rend2 = ThisWorkbook.Sheets("DATA").Range("D" & Rows.Count).End(xlUp).row
   
    If rend < rend2 Then rend = rend2
    If rend < 2 Then
        MsgBox "Have not data. Please reconfirm"
        Exit Sub
    End If
   
    ReDim kqarr(1 To 1, 1 To 6) 'Du lieu de ghi ra sheet KQ
   
    darr = ThisWorkbook.Sheets("DATA").Range("A2:F" & rend).Value
    'Xoa sach du lieu cot G truoc khi lam viec
    ThisWorkbook.Sheets("DATA").Range("G2:J" & rend).ClearContents
   
   
    ReDim allarr(1 To 1)    'Reset mang
    ReDim cota_arr(1 To 3, 1 To 1) 'Reset mang
    ReDim cotd_arr(1 To 3, 1 To 1) 'Reset mang
    ReDim kqarr(1 To 10, 1 To 1)
'    Call khoitaouserform
    outs = ";" 'Chua co data gi
    cnt = 0
    cnt1 = 0
    cnt2 = 0
   
    For i = LBound(darr, 1) To UBound(darr, 1) Step 1
        'neu ma don hang A khong phai la "" thi nap vao outs
        sfind = Trim(CStr(darr(i, 1))) 'Loai bo khoang trang dau va cuoi
        'co the khong can thiet neu nhu data duoc nap vao database da duoc xu ly khoang trang dau cuoi
        If sfind <> "" Then
            cnt1 = cnt1 + 1
            ReDim Preserve cota_arr(1 To 3, 1 To cnt1)
        
                cota_arr(1, cnt1) = Trim(CStr(darr(i, 1)))
                cota_arr(2, cnt1) = Val(CStr(darr(i, 2)))
                cota_arr(3, cnt1) = Val(CStr(darr(i, 3)))
               
            sfind = sfind & ";"
            If InStr(1, outs, sfind) = 0 Then
                outs = outs & sfind
                cnt = cnt + 1
                ReDim Preserve allarr(1 To cnt)
                allarr(cnt) = Trim(CStr(darr(i, 1)))
               
                ReDim Preserve kqarr(1 To 10, 1 To cnt)
                kqarr(1, cnt) = Trim(CStr(darr(i, 1)))
                kqarr(2, cnt) = cota_arr(2, cnt1)
                kqarr(3, cnt) = cota_arr(3, cnt1)
            End If
        End If
       
        'neu ma don hang D khong phai la "" thi nap vao outs
        sfind = Trim(CStr(darr(i, 4))) 'Loai bo khoang trang dau va cuoi
        'co the khong can thiet neu nhu data duoc nap vao database da duoc xu ly khoang trang dau cuoi
        If sfind <> "" Then
            cnt2 = cnt2 + 1
            ReDim Preserve cotd_arr(1 To 3, 1 To cnt2)
         
                cotd_arr(1, cnt2) = Trim(CStr(darr(i, 4)))
                cotd_arr(2, cnt2) = Val(CStr(darr(i, 5)))
                cotd_arr(3, cnt2) = Val(CStr(darr(i, 6)))
               
            sfind = sfind & ";"
            If InStr(1, outs, sfind) = 0 Then
                outs = outs & sfind
                cnt = cnt + 1
                ReDim Preserve allarr(1 To cnt)
                allarr(cnt) = Trim(CStr(darr(i, 4)))
               
                ReDim Preserve kqarr(1 To 10, 1 To cnt)
                kqarr(4, cnt) = Trim(CStr(darr(i, 4)))
                kqarr(5, cnt) = cotd_arr(2, cnt2)
                kqarr(6, cnt) = cotd_arr(3, cnt2)
              
            End If
        End If
       
       

       
       
    Next i

   
    For i = 1 To cnt Step 1
        'Cot A co ma nxt nhung cot D chua co thi tim kiem
        If CStr(kqarr(4, i)) = "" And CStr(kqarr(1, i)) <> "" Then
            j = findvitri(CStr(kqarr(1, i)), cotd_arr)
            If j > 0 Then
                kqarr(4, i) = cotd_arr(1, j)
                kqarr(5, i) = cotd_arr(2, j)
                kqarr(6, i) = cotd_arr(3, j)
            End If
        End If
        'Cot D co ma nxt nhung cot A chua co thi tim kiem
        If CStr(kqarr(4, i)) <> "" And CStr(kqarr(1, i)) = "" Then
            j = findvitri(CStr(kqarr(4, i)), cota_arr)
            If j > 0 Then
                kqarr(1, i) = cota_arr(1, j)
                kqarr(2, i) = cota_arr(2, j)
                kqarr(3, i) = cota_arr(3, j)
            End If
        End If
        'So sanh ma nxt
        If CStr(kqarr(4, i)) <> CStr(kqarr(1, i)) Then
            kqarr(7, i) = "FALSE"
            kqarr(10, i) = "X"
        Else
            kqarr(7, i) = "TRUE"
        End If
        'so sanh so luong
        If (Val(CStr(kqarr(5, i))) - Val(CStr(kqarr(2, i)))) <> 0 Then
            kqarr(8, i) = "FALSE"
            kqarr(10, i) = "X"
        Else
            kqarr(8, i) = "TRUE"
        End If
        'So sanh tien
        If (Val(CStr(kqarr(6, i))) - Val(CStr(kqarr(3, i)))) <> 0 Then
            kqarr(9, i) = "FALSE"
            kqarr(10, i) = "X"
        Else
            kqarr(9, i) = "TRUE"
        End If
       
    Next i
    arrkq = daochieumang(kqarr)
    ThisWorkbook.Sheets("KQ").Range("A2").Resize(cnt, 10) = arrkq
   
End Sub
Function findvitri(ByVal s As String, ByVal farr As Variant) As Integer
    Dim k   As Integer
    findvitri = 0
    For k = LBound(farr, 2) To UBound(farr, 2) Step 1
        If CStr(farr(1, k)) = s Then
            findvitri = k
            Exit Function
        End If
    Next k
   
End Function

Function daochieumang(ByVal farr As Variant) As Variant
    Dim arr
    Dim ro1     As Integer
    Dim co1     As Integer
    Dim ro2     As Integer
    Dim co2     As Integer
    Dim i1      As Integer
    Dim j1      As Integer
   
    ro1 = LBound(farr, 1)
    ro2 = UBound(farr, 1)
    co1 = LBound(farr, 2)
    co2 = UBound(farr, 2)
    ReDim arr(co1 To co2, ro1 To ro2)
    For i1 = ro1 To ro2 Step 1
        For j1 = co1 To co2 Step 1
            arr(j1, i1) = farr(i1, j1)
        Next j1
    Next i1
    daochieumang = arr
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Chôm Code của bạn @befaint, thêm vài lệnh
Mã:
Sub SortedListFilter()
  Dim oSList As Object, sKey As String
  Dim sArr1(), sArr2(), Result(), S
  Dim i As Long, sRow As Long, n As Long, j As Long

  Set oSList = CreateObject("System.Collections.SortedList")
  With Sheets("database")
    sArr1 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
    For i = 1 To UBound(sArr1)
      sKey = Application.Trim(sArr1(i, 1))
      If sKey <> "" Then
        If oSList.ContainsKey(sKey) = False Then oSList.Add sKey, Array(i, 0)
      End If
    Next i
  
    sArr2 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
    For i = 1 To UBound(sArr2)
      sKey = Application.Trim(sArr2(i, 1))
      If sKey <> "" Then
        If oSList.ContainsKey(sKey) = False Then
          oSList.Add sKey, Array(0, i)
        Else
          oSList.Item(sKey) = Array(oSList.Item(sKey)(0), i)
        End If
      End If
    Next i
  End With

  n = oSList.Count - 1
  ReDim Result(0 To n, 1 To 6)
  For i = 0 To n
    S = oSList.GetByIndex(i)
    If S(0) > 0 Then
      For j = 1 To 3
        Result(i, j) = sArr1(S(0), j)
      Next j
    End If
    If S(1) > 0 Then
      For j = 1 To 3
        Result(i, j + 3) = sArr2(S(1), j)
      Next j
    End If
  Next i

  With Sheets("KQ")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    j = .Range("D" & Rows.Count).End(xlUp).Row
    If i < j Then i = j
    If i > 1 Then .Range("A2:F" & i).Clear
    .Range("A2").Resize(n + 1, 1).NumberFormat = "@"
    .Range("D2").Resize(n + 1, 1).NumberFormat = "@"
    .Range("A2").Resize(n + 1, 6) = Result
  End With
End Sub
Em chỉ có thể nói là Tuyệt vời quá anh ơi! Cảm ơn các anh rất nhiều.
Chúc anh và gia đình mạnh khỏe
Bài đã được tự động gộp:

Code này chạy tốc độ không nhanh như của @HieuCD , sử dụng hoàn toàn các hàm tự tạo theo logic bạn nêu ra.
Sheet Database mình sửa tên thành "DATA" như một thói quen.
Link dowload file excel:
https://www.mediafire.com/file/236gyiwlc453bsw/Sapxedulieu.rar/file

Mã:
Sub main()
    Dim i As Integer
    Dim j   As Integer
 
    Dim rend As Integer
    Dim rend2   As Integer
 
    Dim darr    'all-du lieu tu cot A ->F

    Dim kqarr   'Du lieu de ghi ra sheet KQ
    Dim allarr  'Dieu lieu ma nxt all tren cot A,D
 
    Dim cota_arr    'du lieu cot A->C
    Dim cotd_arr    'du lieu cot D->F
 
 
    Dim outs    As String 'ghi lai toan bo ma nxt tren cot A va D
    Dim sfind   As String   ' ma nxt
    Dim cnt     As Integer
    Dim cnt1    As Integer  'cot A
    Dim cnt2    As Integer  'cot D
    Dim arrkq

    'Xac dinh dong cuoi cua du lieu
 
    rend = ThisWorkbook.Sheets("DATA").Range("A" & Rows.Count).End(xlUp).row
    rend2 = ThisWorkbook.Sheets("DATA").Range("D" & Rows.Count).End(xlUp).row
 
    If rend < rend2 Then rend = rend2
    If rend < 2 Then
        MsgBox "Have not data. Please reconfirm"
        Exit Sub
    End If
 
    ReDim kqarr(1 To 1, 1 To 6) 'Du lieu de ghi ra sheet KQ
 
    darr = ThisWorkbook.Sheets("DATA").Range("A2:F" & rend).Value
    'Xoa sach du lieu cot G truoc khi lam viec
    ThisWorkbook.Sheets("DATA").Range("G2:J" & rend).ClearContents
 
 
    ReDim allarr(1 To 1)    'Reset mang
    ReDim cota_arr(1 To 3, 1 To 1) 'Reset mang
    ReDim cotd_arr(1 To 3, 1 To 1) 'Reset mang
    ReDim kqarr(1 To 10, 1 To 1)
'    Call khoitaouserform
    outs = ";" 'Chua co data gi
    cnt = 0
    cnt1 = 0
    cnt2 = 0
 
    For i = LBound(darr, 1) To UBound(darr, 1) Step 1
        'neu ma don hang A khong phai la "" thi nap vao outs
        sfind = Trim(CStr(darr(i, 1))) 'Loai bo khoang trang dau va cuoi
        'co the khong can thiet neu nhu data duoc nap vao database da duoc xu ly khoang trang dau cuoi
        If sfind <> "" Then
            cnt1 = cnt1 + 1
            ReDim Preserve cota_arr(1 To 3, 1 To cnt1)
      
                cota_arr(1, cnt1) = Trim(CStr(darr(i, 1)))
                cota_arr(2, cnt1) = Val(CStr(darr(i, 2)))
                cota_arr(3, cnt1) = Val(CStr(darr(i, 3)))
             
            sfind = sfind & ";"
            If InStr(1, outs, sfind) = 0 Then
                outs = outs & sfind
                cnt = cnt + 1
                ReDim Preserve allarr(1 To cnt)
                allarr(cnt) = Trim(CStr(darr(i, 1)))
             
                ReDim Preserve kqarr(1 To 10, 1 To cnt)
                kqarr(1, cnt) = Trim(CStr(darr(i, 1)))
                kqarr(2, cnt) = cota_arr(2, cnt1)
                kqarr(3, cnt) = cota_arr(3, cnt1)
            End If
        End If
     
        'neu ma don hang D khong phai la "" thi nap vao outs
        sfind = Trim(CStr(darr(i, 4))) 'Loai bo khoang trang dau va cuoi
        'co the khong can thiet neu nhu data duoc nap vao database da duoc xu ly khoang trang dau cuoi
        If sfind <> "" Then
            cnt2 = cnt2 + 1
            ReDim Preserve cotd_arr(1 To 3, 1 To cnt2)
       
                cotd_arr(1, cnt2) = Trim(CStr(darr(i, 4)))
                cotd_arr(2, cnt2) = Val(CStr(darr(i, 5)))
                cotd_arr(3, cnt2) = Val(CStr(darr(i, 6)))
             
            sfind = sfind & ";"
            If InStr(1, outs, sfind) = 0 Then
                outs = outs & sfind
                cnt = cnt + 1
                ReDim Preserve allarr(1 To cnt)
                allarr(cnt) = Trim(CStr(darr(i, 4)))
             
                ReDim Preserve kqarr(1 To 10, 1 To cnt)
                kqarr(4, cnt) = Trim(CStr(darr(i, 4)))
                kqarr(5, cnt) = cotd_arr(2, cnt2)
                kqarr(6, cnt) = cotd_arr(3, cnt2)
            
            End If
        End If
     
     

     
     
    Next i

 
    For i = 1 To cnt Step 1
        'Cot A co ma nxt nhung cot D chua co thi tim kiem
        If CStr(kqarr(4, i)) = "" And CStr(kqarr(1, i)) <> "" Then
            j = findvitri(CStr(kqarr(1, i)), cotd_arr)
            If j > 0 Then
                kqarr(4, i) = cotd_arr(1, j)
                kqarr(5, i) = cotd_arr(2, j)
                kqarr(6, i) = cotd_arr(3, j)
            End If
        End If
        'Cot D co ma nxt nhung cot A chua co thi tim kiem
        If CStr(kqarr(4, i)) <> "" And CStr(kqarr(1, i)) = "" Then
            j = findvitri(CStr(kqarr(4, i)), cota_arr)
            If j > 0 Then
                kqarr(1, i) = cota_arr(1, j)
                kqarr(2, i) = cota_arr(2, j)
                kqarr(3, i) = cota_arr(3, j)
            End If
        End If
        'So sanh ma nxt
        If CStr(kqarr(4, i)) <> CStr(kqarr(1, i)) Then
            kqarr(7, i) = "FALSE"
            kqarr(10, i) = "X"
        Else
            kqarr(7, i) = "TRUE"
        End If
        'so sanh so luong
        If (Val(CStr(kqarr(5, i))) - Val(CStr(kqarr(2, i)))) <> 0 Then
            kqarr(8, i) = "FALSE"
            kqarr(10, i) = "X"
        Else
            kqarr(8, i) = "TRUE"
        End If
        'So sanh tien
        If (Val(CStr(kqarr(6, i))) - Val(CStr(kqarr(3, i)))) <> 0 Then
            kqarr(9, i) = "FALSE"
            kqarr(10, i) = "X"
        Else
            kqarr(9, i) = "TRUE"
        End If
     
    Next i
    arrkq = daochieumang(kqarr)
    ThisWorkbook.Sheets("KQ").Range("A2").Resize(cnt, 10) = arrkq
 
End Sub
Function findvitri(ByVal s As String, ByVal farr As Variant) As Integer
    Dim k   As Integer
    findvitri = 0
    For k = LBound(farr, 2) To UBound(farr, 2) Step 1
        If CStr(farr(1, k)) = s Then
            findvitri = k
            Exit Function
        End If
    Next k
 
End Function

Function daochieumang(ByVal farr As Variant) As Variant
    Dim arr
    Dim ro1     As Integer
    Dim co1     As Integer
    Dim ro2     As Integer
    Dim co2     As Integer
    Dim i1      As Integer
    Dim j1      As Integer
 
    ro1 = LBound(farr, 1)
    ro2 = UBound(farr, 1)
    co1 = LBound(farr, 2)
    co2 = UBound(farr, 2)
    ReDim arr(co1 To co2, ro1 To ro2)
    For i1 = ro1 To ro2 Step 1
        For j1 = co1 To co2 Step 1
            arr(j1, i1) = farr(i1, j1)
        Next j1
    Next i1
    daochieumang = arr
End Function
Cảm ơn bạn đã nhiệt tình giúp đỡ. Mình sẽ chú ý đến kênh của bạn hơn. Hy vọng sẽ học hỏi thêm kiến thức về VBA.
 
Lần chỉnh sửa cuối:
Upvote 0
Cuối cùng. Với mong muốn tiết kiệm thời gian , công sức của các bạn kế toán, thủ kho, thống kê khi đối chiếu các dạng bài có cấu trúc tương tự
.Em xin sửa tiêu đề và chia sẻ file hoàn thiện dựa trên code của anh HieuCD, anh befaint ,anh be09 .....
Xin cảm ơn sự giúp đỡ của các anh và mọi người
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em chỉ có thể nói là Tuyệt vời quá anh ơi! Cảm ơn các anh rất nhiều.
Chúc anh và gia đình mạnh khỏe
Bài đã được tự động gộp:


Cảm ơn bạn đã nhiệt tình giúp đỡ. Mình sẽ chú ý đến kênh của bạn hơn. Hy vọng sẽ học hỏi thêm kiến thức về VBA.
Nếu dữ liệu đã Sort và loại khoảng trắng, không cần dùng SortList, code gọn và tốc độ nhanh hơn nhiều
Mã:
Sub SoSanh()
  Dim sArr1(), sArr2(), Res()
  Dim k As Long, sRow As Long, n2 As Long
  Dim i As Long, j As Long, i2 As Long, j2 As Long
 
  With Sheets("database")
    If .Range("A2").Value <= .Range("A2").Value Then
      sArr1 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
      sArr2 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
      j = 1: j2 = 4
    Else
      sArr2 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
      sArr1 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
      j = 4: j2 = 1
    End If
  End With
  sRow = UBound(sArr1)
  ReDim Res(1 To sRow + UBound(sArr2), 1 To 6)
  n2 = 1
  For i = 1 To sRow
    If i < sRow Then tmp = sArr1(i + 1, 1) Else tmp = "zzz"
    k = k + 1
    Res(k, j) = sArr1(i, 1)
    Res(k, j + 1) = sArr1(i, 2)
    Res(k, j + 2) = sArr1(i, 3)
    For i2 = n2 To UBound(sArr2)
      If sArr2(i2, 1) < tmp Then
        If sArr2(i2, 1) > sArr1(i, 1) Then k = k + 1
        Res(k, j2) = sArr2(i2, 1)
        Res(k, j2 + 1) = sArr2(i2, 2)
        Res(k, j2 + 2) = sArr2(i2, 3)
      Else
        n2 = i2:        Exit For
      End If
    Next i2
  Next i
  With Sheets("KQ")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If i < i2 Then i = i2
    If i > 1 Then .Range("A2:F" & i).Clear
    .Range("A2").Resize(k).NumberFormat = "@"
    .Range("D2").Resize(k).NumberFormat = "@"
    .Range("A2").Resize(k, 6) = Res
  End With
End Sub
 
Upvote 0
Nếu dữ liệu đã Sort và loại khoảng trắng, không cần dùng SortList, code gọn và tốc độ nhanh hơn nhiều
Mã:
Sub SoSanh()
  Dim sArr1(), sArr2(), Res()
  Dim k As Long, sRow As Long, n2 As Long
  Dim i As Long, j As Long, i2 As Long, j2 As Long

  With Sheets("database")
    If .Range("A2").Value <= .Range("A2").Value Then
      sArr1 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
      sArr2 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
      j = 1: j2 = 4
    Else
      sArr2 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
      sArr1 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
      j = 4: j2 = 1
    End If
  End With
  sRow = UBound(sArr1)
  ReDim Res(1 To sRow + UBound(sArr2), 1 To 6)
  n2 = 1
  For i = 1 To sRow
    If i < sRow Then tmp = sArr1(i + 1, 1) Else tmp = "zzz"
    k = k + 1
    Res(k, j) = sArr1(i, 1)
    Res(k, j + 1) = sArr1(i, 2)
    Res(k, j + 2) = sArr1(i, 3)
    For i2 = n2 To UBound(sArr2)
      If sArr2(i2, 1) < tmp Then
        If sArr2(i2, 1) > sArr1(i, 1) Then k = k + 1
        Res(k, j2) = sArr2(i2, 1)
        Res(k, j2 + 1) = sArr2(i2, 2)
        Res(k, j2 + 2) = sArr2(i2, 3)
      Else
        n2 = i2:        Exit For
      End If
    Next i2
  Next i
  With Sheets("KQ")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If i < i2 Then i = i2
    If i > 1 Then .Range("A2:F" & i).Clear
    .Range("A2").Resize(k).NumberFormat = "@"
    .Range("D2").Resize(k).NumberFormat = "@"
    .Range("A2").Resize(k, 6) = Res
  End With
End Sub
Em thấy hình như code vẫn có động tác sortlist hay sao ấy ạ. Vì khi em áp dụng code này vào 1 bảng tương tự nhưng không ra kết quả như mong muốn. Anh xem giúp em với. Cảm ơn anh
 

File đính kèm

Upvote 0
Điều kiện để hai dữ liệu được xếp chung một hàng là gì hả bạn?
Cột A = Cột D
hay là:
Cột A = Cột D và cột B = cột E

Trước đây mình hiểu cột A = cột D thì xếp chung một hàng.
Và hiểu rằng mã data là tồn tại duy nhất, tuy nhiên data bạn đưa ra cho thấy mã 9786042085984 xuất hiện rất nhiều lần trên cột D.

217035
 
Upvote 0
Nguyên tắc đối chiếu vẫn là cột A = D, B= E, C= F => TRUE hoặc FALSE. Nếu A = D mà ra False tức là 2 mã không giống nhau thì nhảy dòng trống
Nếu A = D = True mà B =E , C = F mà ra True ;False; False; True hoặc False; False thì không tạo dòng trống
Trước khi đưa dữ liệu vào sheet Data, các dữ liệu số phiếu đã sort A-Z, cùng với sort mã A- Z, mã đã trim (mã). Mã có thể lặp lại do nghiệp vụ nhập kho ở các phiếu khác nhau
 

File đính kèm

Upvote 0
Em thấy hình như code vẫn có động tác sortlist hay sao ấy ạ. Vì khi em áp dụng code này vào 1 bảng tương tự nhưng không ra kết quả như mong muốn. Anh xem giúp em với. Cảm ơn anh
File dữ liệu chưa sort, phải dùng code bài #26
Bài đã được tự động gộp:

Em thấy hình như code vẫn có động tác sortlist hay sao ấy ạ. Vì khi em áp dụng code này vào 1 bảng tương tự nhưng không ra kết quả như mong muốn. Anh xem giúp em với. Cảm ơn anh
Dữ liệu Mã data có trùng, code bài #26 đã loại trùng mã
 
Upvote 0
File dữ liệu chưa sort, phải dùng code bài #26
Bài đã được tự động gộp:


Dữ liệu Mã data có trùng, code bài #26 đã loại trùng mã
Trước khi post bài , Em đã chạy code của #26 anh à. Nhưng file mới này của em không được phép loại trùng mã vì cần đối chiếu các phiếu Nhập kho (NK) với nhau. Và Em đã sort từ bên ngoài theo số phiếu nhập A-Z và sort mã A-Z.
Anh xem lại file này em gửi kèm nhé
 

File đính kèm

Upvote 0
Trước khi post bài , Em đã chạy code của #26 anh à. Nhưng file mới này của em không được phép loại trùng mã vì cần đối chiếu các phiếu Nhập kho (NK) với nhau. Và Em đã sort từ bên ngoài theo số phiếu nhập A-Z và sort mã A-Z.
Anh xem lại file này em gửi kèm nhé
Chỉ xét mã, chưa xét phiếu và số lượng
Mã:
Sub RoundedRectangle4_Click()
'Sub SoSanh()
  Dim sArr1(), sArr2(), Res()
  Dim k As Long, eRow As Long, sRow As Long, n2 As Long
  Dim i As Long, j As Long, i2 As Long, j2 As Long
  With Sheets("Data")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If i > i2 Then eRow = i Else eRow = i2
    Res = .Range("A2:F" & eRow).Value
  End With
  Application.ScreenUpdating = False
  With Sheets("KQ")
    .Range("A1").CurrentRegion.Offset(1).ClearContents
    .Range("A2").Resize(i + i2).NumberFormat = "@"
    .Range("D2").Resize(i + i2).NumberFormat = "@"
    .Range("A2:F" & eRow) = Res
    .Range("A1:C" & i).Sort .[A1], 1, .[B1], , 1, .[C1], , 1, Header:=xlYes
    .Range("D1:F" & i2).Sort .[D1], 1, .[E1], , 1, .[F1], , 1, Header:=xlYes
    
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If .Range("A2").Value <= .Range("A2").Value Then
      sArr1 = .Range("A2:C" & i).Value
      sArr2 = .Range("D2:F" & i2).Value
      j = 1: j2 = 4
    Else
      sArr2 = .Range("A2:C" & i).Value
      sArr1 = .Range("D2:F" & i2).Value
      j = 4: j2 = 1
    End If
  End With
  sRow = UBound(sArr1)
  ReDim Res(1 To sRow + UBound(sArr2), 1 To 6)
  n2 = 1
  For i = 1 To sRow
    k = k + 1
    Res(k, j) = sArr1(i, 1)
    Res(k, j + 1) = sArr1(i, 2)
    Res(k, j + 2) = sArr1(i, 3)
    If i < sRow Then tmp = sArr1(i + 1, 1) Else tmp = "zzz"
    If tmp > sArr1(i, 1) Then
      For i2 = n2 To UBound(sArr2)
        If sArr2(i2, 1) < tmp Then
          If sArr2(i2, 1) > sArr1(i, 1) Then k = k + 1
          Res(k, j2) = sArr2(i2, 1)
          Res(k, j2 + 1) = sArr2(i2, 2)
          Res(k, j2 + 2) = sArr2(i2, 3)
        Else
          n2 = i2:        Exit For
        End If
      Next i2
    Else
        If sArr2(n2, 1) = tmp Then
          Res(k, j2) = sArr2(n2, 1)
          Res(k, j2 + 1) = sArr2(n2, 2)
          Res(k, j2 + 2) = sArr2(n2, 3)
          n2 = n2 + 1
        End If
    End If
  Next i
  With Sheets("KQ")
    .Range("A2").Resize(k, 6) = Res
  End With
  Application.ScreenUpdating = True
End Sub
 
Upvote 0
Chỉ xét mã, chưa xét phiếu và số lượng
Mã:
Sub RoundedRectangle4_Click()
'Sub SoSanh()
  Dim sArr1(), sArr2(), Res()
  Dim k As Long, eRow As Long, sRow As Long, n2 As Long
  Dim i As Long, j As Long, i2 As Long, j2 As Long
  With Sheets("Data")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If i > i2 Then eRow = i Else eRow = i2
    Res = .Range("A2:F" & eRow).Value
  End With
  Application.ScreenUpdating = False
  With Sheets("KQ")
    .Range("A1").CurrentRegion.Offset(1).ClearContents
    .Range("A2").Resize(i + i2).NumberFormat = "@"
    .Range("D2").Resize(i + i2).NumberFormat = "@"
    .Range("A2:F" & eRow) = Res
    .Range("A1:C" & i).Sort .[A1], 1, .[B1], , 1, .[C1], , 1, Header:=xlYes
    .Range("D1:F" & i2).Sort .[D1], 1, .[E1], , 1, .[F1], , 1, Header:=xlYes

    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If .Range("A2").Value <= .Range("A2").Value Then
      sArr1 = .Range("A2:C" & i).Value
      sArr2 = .Range("D2:F" & i2).Value
      j = 1: j2 = 4
    Else
      sArr2 = .Range("A2:C" & i).Value
      sArr1 = .Range("D2:F" & i2).Value
      j = 4: j2 = 1
    End If
  End With
  sRow = UBound(sArr1)
  ReDim Res(1 To sRow + UBound(sArr2), 1 To 6)
  n2 = 1
  For i = 1 To sRow
    k = k + 1
    Res(k, j) = sArr1(i, 1)
    Res(k, j + 1) = sArr1(i, 2)
    Res(k, j + 2) = sArr1(i, 3)
    If i < sRow Then tmp = sArr1(i + 1, 1) Else tmp = "zzz"
    If tmp > sArr1(i, 1) Then
      For i2 = n2 To UBound(sArr2)
        If sArr2(i2, 1) < tmp Then
          If sArr2(i2, 1) > sArr1(i, 1) Then k = k + 1
          Res(k, j2) = sArr2(i2, 1)
          Res(k, j2 + 1) = sArr2(i2, 2)
          Res(k, j2 + 2) = sArr2(i2, 3)
        Else
          n2 = i2:        Exit For
        End If
      Next i2
    Else
        If sArr2(n2, 1) = tmp Then
          Res(k, j2) = sArr2(n2, 1)
          Res(k, j2 + 1) = sArr2(n2, 2)
          Res(k, j2 + 2) = sArr2(n2, 3)
          n2 = n2 + 1
        End If
    End If
  Next i
  With Sheets("KQ")
    .Range("A2").Resize(k, 6) = Res
  End With
  Application.ScreenUpdating = True
End Sub
Đúng là em chỉ cần so khớp mã để nhảy dòng. Nhưng Vì trước khi đưa dữ liệu vào sheet Data em đã làm sort từ các sheet gốc rồi, nên khi chạy code không muốn bị sort nữa, em đã xem code #36 , thử ngừng chạy các dòng liên quan đến sort như 2 dòng này:
.Range("A1:C" & i).Sort .[A1], 1, .[B1], , 1, .[C1], , 1, Header:=xlYes
.Range("D1:F" & i2).Sort .[D1], 1, .[E1], , 1, .[F1], , 1, Header:=xlYes
nhưng mà kết quả ra rất khác so với mong muốn.
Còn nếu để nguyên 2 dòng trên và chạy code thì cũng chưa ra được kết quả cuối cùng như bên sheet KQ (mong muốn)
Chi tiết trong file gửi kèm
Cảm ơn anh đã hỗ trợ em nhé. Chúc anh ngày vui
 

File đính kèm

Upvote 0
Đúng là em chỉ cần so khớp mã để nhảy dòng. Nhưng Vì trước khi đưa dữ liệu vào sheet Data em đã làm sort từ các sheet gốc rồi, nên khi chạy code không muốn bị sort nữa, em đã xem code #36 , thử ngừng chạy các dòng liên quan đến sort như 2 dòng này:

nhưng mà kết quả ra rất khác so với mong muốn.
Còn nếu để nguyên 2 dòng trên và chạy code thì cũng chưa ra được kết quả cuối cùng như bên sheet KQ (mong muốn)
Chi tiết trong file gửi kèm
Cảm ơn anh đã hỗ trợ em nhé. Chúc anh ngày vui
Kiểm tra lại
Mã:
Dim Res(), sArr2(), k As Long, j2 As Long
Sub RoundedRectangle6_Click()
  Dim sArr1(), tmp As String, dk As Boolean
  Dim i As Long, j As Long, q As Long, sRow As Long
  Dim i2 As Long, n2 As Long, q2 As Long
 
  With Sheets("Data")
    If .Range("A2").Value <= .Range("D2").Value Then
      sArr1 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
      sArr2 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
      j = 1: j2 = 4
    Else
      sArr2 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
      sArr1 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
      j = 4: j2 = 1
    End If
  End With
  Application.ScreenUpdating = False
  sRow = UBound(sArr1)
  ReDim Res(1 To sRow + UBound(sArr2), 1 To 6)
  k = 0: n2 = 1
  For i = 1 To sRow
    If Len(sArr1(i, 1)) Then
      k = k + 1
      Res(k, j) = sArr1(i, 1)
      Res(k, j + 1) = sArr1(i, 2)
      Res(k, j + 2) = sArr1(i, 3)
      tmp = "zzz"
      For q = i + 1 To sRow
        If Len(sArr1(q, 1)) Then tmp = sArr1(q, 1): Exit For
      Next q
      If tmp <> sArr1(i, 1) Then
        dk = False
        For i2 = n2 To UBound(sArr2)
          If sArr2(i2, 1) = sArr1(i, 1) And sArr2(i2, 2) = sArr1(i, 2) And sArr2(i2, 3) = sArr1(i, 3) Then
            If dk = True Then k = k + 1
            Call GanKetQua(i2)
            sArr2(i2, 1) = ""
            dk = True
          End If
          If sArr2(i2, 1) = tmp Then
            For q2 = n2 To i2 - 1
              If Len(sArr2(q2, 1)) Then
                If sArr2(q2, 1) <> sArr1(i, 1) Then k = k + 1
                Call GanKetQua(q2)
              End If
            Next q2
            n2 = i2:        Exit For
          End If
        Next i2
      Else
        If sArr2(n2, 1) = tmp Then
          Call GanKetQua(n2)
          n2 = n2 + 1
        End If
      End If
    End If
  Next i
  With Sheets("KQ")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If i2 > i Then i = i2
    If i > 1 Then .Range("A2:F" & i).ClearContents
    .Range("A2").Resize(k, 6) = Res
  End With
  Application.ScreenUpdating = True
End Sub

Private Sub GanKetQua(ByVal m As Long)
  Res(k, j2) = sArr2(m, 1)
  Res(k, j2 + 1) = sArr2(m, 2)
  Res(k, j2 + 2) = sArr2(m, 3)
End Sub
 
Upvote 0
Đúng là em chỉ cần so khớp mã để nhảy dòng. Nhưng Vì trước khi đưa dữ liệu vào sheet Data em đã làm sort từ các sheet gốc rồi, nên khi chạy code không muốn bị sort nữa, em đã xem code #36 , thử ngừng chạy các dòng liên quan đến sort như 2 dòng này:

nhưng mà kết quả ra rất khác so với mong muốn.
Còn nếu để nguyên 2 dòng trên và chạy code thì cũng chưa ra được kết quả cuối cùng như bên sheet KQ (mong muốn)
Chi tiết trong file gửi kèm
Cảm ơn anh đã hỗ trợ em nhé. Chúc anh ngày vui
Code bài #38 dòng đầu và cuối chưa chuẩn, khi rảnh mình viết thêm
 
Upvote 0
Kiểm tra lại
Mã:
Dim Res(), sArr2(), k As Long, j2 As Long
Sub RoundedRectangle6_Click()
  Dim sArr1(), tmp As String, dk As Boolean
  Dim i As Long, j As Long, q As Long, sRow As Long
  Dim i2 As Long, n2 As Long, q2 As Long

  With Sheets("Data")
    If .Range("A2").Value <= .Range("D2").Value Then
      sArr1 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
      sArr2 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
      j = 1: j2 = 4
    Else
      sArr2 = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row).Value
      sArr1 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
      j = 4: j2 = 1
    End If
  End With
  Application.ScreenUpdating = False
  sRow = UBound(sArr1)
  ReDim Res(1 To sRow + UBound(sArr2), 1 To 6)
  k = 0: n2 = 1
  For i = 1 To sRow
    If Len(sArr1(i, 1)) Then
      k = k + 1
      Res(k, j) = sArr1(i, 1)
      Res(k, j + 1) = sArr1(i, 2)
      Res(k, j + 2) = sArr1(i, 3)
      tmp = "zzz"
      For q = i + 1 To sRow
        If Len(sArr1(q, 1)) Then tmp = sArr1(q, 1): Exit For
      Next q
      If tmp <> sArr1(i, 1) Then
        dk = False
        For i2 = n2 To UBound(sArr2)
          If sArr2(i2, 1) = sArr1(i, 1) And sArr2(i2, 2) = sArr1(i, 2) And sArr2(i2, 3) = sArr1(i, 3) Then
            If dk = True Then k = k + 1
            Call GanKetQua(i2)
            sArr2(i2, 1) = ""
            dk = True
          End If
          If sArr2(i2, 1) = tmp Then
            For q2 = n2 To i2 - 1
              If Len(sArr2(q2, 1)) Then
                If sArr2(q2, 1) <> sArr1(i, 1) Then k = k + 1
                Call GanKetQua(q2)
              End If
            Next q2
            n2 = i2:        Exit For
          End If
        Next i2
      Else
        If sArr2(n2, 1) = tmp Then
          Call GanKetQua(n2)
          n2 = n2 + 1
        End If
      End If
    End If
  Next i
  With Sheets("KQ")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If i2 > i Then i = i2
    If i > 1 Then .Range("A2:F" & i).ClearContents
    .Range("A2").Resize(k, 6) = Res
  End With
  Application.ScreenUpdating = True
End Sub

Private Sub GanKetQua(ByVal m As Long)
  Res(k, j2) = sArr2(m, 1)
  Res(k, j2 + 1) = sArr2(m, 2)
  Res(k, j2 + 2) = sArr2(m, 3)
End Sub
Em cảm ơn anh. Code của anh ra đúng với kết quả mong muốn ở bài này rồi ạ.
Nhưng khi cũng dạng dữ liệu này y hệt. Dữ liệu tăng lên tầm 18.000 dòng thì lại không được. Nhất là khi xuất hiện tình huống so le mã là bị sai
(cụ thể là KQ chạy code so với KQ mong muốn; bắt đầu không đúng từ dòng 317 trong file này anh à)
Tất cả dữ liệu em đã sort rồi. Nên khi chạy code Em chỉ mong muốn so khớp 2 cột với nhau thôi, không cần phải đi tìm các mã để khớp với nhau ở các vùng dưới nữa anh à
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em cảm ơn anh. Code của anh ra đúng với kết quả mong muốn ở bài này rồi ạ.
Nhưng khi cũng dạng dữ liệu này y hệt. Dữ liệu tăng lên tầm 18.000 dòng thì lại không được. Nhất là khi xuất hiện tình huống so le mã là bị sai
(cụ thể là KQ chạy code so với KQ mong muốn; bắt đầu không đúng từ dòng 317 trong file này anh à)
Tất cả dữ liệu em đã sort rồi. Nên khi chạy code Em chỉ mong muốn so khớp 2 cột với nhau thôi, không cần phải đi tìm các mã để khớp với nhau ở các vùng dưới nữa anh à
Kết quả mong muốn làm sao có vậy? Có thể phải xét thêm vài cột điều kiện mà trong file không có
 
Upvote 0
Kết quả mong muốn làm sao có vậy? Có thể phải xét thêm vài cột điều kiện mà trong file không có
Cảm ơn anh đã hỗ trợ em trong thời gian qua. Em cũng không biết diễn đạt sao cho ra vấn đề. Có lẽ để em làm 1 clip mô tả lại quá trình em làm thủ công. Và gửi lại sau anh nhé. Chúc anh sức khỏe dồi dào và gặp nhiều niềm vui.
 
Upvote 0
Cảm ơn anh đã hỗ trợ em trong thời gian qua. Em cũng không biết diễn đạt sao cho ra vấn đề. Có lẽ để em làm 1 clip mô tả lại quá trình em làm thủ công. Và gửi lại sau anh nhé. Chúc anh sức khỏe dồi dào và gặp nhiều niềm vui.
Dữ liệu phải sort theo ưu tiên: Phiếu, Mã
Dữ liệu không có dòng trống
Kết quả mong muốn của bạn thiếu nhiều dòng
Kiểm tra code
Mã:
  Dim Res(), sArr(), sArr2()
  Dim Phieu As String, Ma As String, sRow As Long, sRow2 As Long
  Dim i As Long, i2 As Long, n2 As Long, k As Long
 
Sub Button1_Click1()
  With Sheets("Data")
      sArr = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row + 1).Value
      sArr2 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
  End With
  Application.ScreenUpdating = False
  sRow = UBound(sArr) - 1
  sRow2 = UBound(sArr2)
  ReDim Res(1 To sRow + sRow2, 1 To 6)
  k = 0: n2 = 1
  For i = 1 To sRow
    Phieu = UCase(sArr(i, 2))
    If Phieu > UCase(sArr2(n2, 2)) Then
      Call Nho
    ElseIf Phieu = UCase(sArr2(n2, 2)) Then
      Call Bang
    Else
      Call Lon
    End If
    If k = UBound(Res) - 1 Then Exit For
  Next i
  With Sheets("KQ")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If i2 > i Then i = i2
    If i > 1 Then .Range("A2:F" & i).ClearContents
    .Range("A2").Resize(k, 6) = Res
  End With
  Application.ScreenUpdating = True
End Sub
Private Sub Bang()
      Ma = sArr(i, 1)
      For i2 = n2 To sRow2
        If UCase(sArr2(i2, 2)) = Phieu Then
          If Len(sArr2(i2, 1)) > 0 Then
            If Ma > sArr2(i2, 1) Then
              k = k + 1: Call GanKetQua2(i2)
              sArr2(i2, 1) = ""
            ElseIf Ma = sArr2(i2, 1) Then
              k = k + 1:  Call GanKetQua1(i)
              If sArr2(i2, 1) = sArr(i, 1) And UCase(sArr2(i2, 2)) = UCase(sArr(i, 2)) And sArr2(i2, 3) = sArr(i, 3) Then
                Call GanKetQua2(i2)
                sArr2(i2, 1) = "": Exit For
              End If
            Else
              Exit For
            End If
          End If
        Else
          Exit For
        End If
      Next i2
      If Phieu <> UCase(sArr(i + 1, 2)) Then
        For i2 = n2 To sRow2
          If UCase(sArr2(i2, 2)) = Phieu Then
            If Len(sArr2(i2, 1)) > 0 Then
              k = k + 1: Call GanKetQua2(i2)
            End If
          Else
            n2 = i2: Exit For
          End If
        Next i2
      End If
End Sub
Private Sub Lon()
  Dim ik As Long
  For ik = i To UBound(sArr1)
    If Phieu = sArr1(ik, 2) Then
      If Len(sArr1(ik, 1)) > 0 Then
        k = k + 1
        Call GanKetQua1(ik)
      End If
    Else
      i = ik - 1: Exit For
    End If
  Next ik
End Sub
Private Sub Nho()
  For i2 = n2 To UBound(sArr2)
    If Phieu > sArr2(i2, 2) Then
      If Len(sArr2(i2, 1)) > 0 Then
        k = k + 1
        Call GanKetQua2(i2)
      End If
    Else
      n2 = i2: Exit For
    End If
  Next i2
End Sub
Private Sub GanKetQua1(ByVal m As Long)
  Res(k, 1) = sArr(m, 1)
  Res(k, 2) = sArr(m, 2)
  Res(k, 3) = sArr(m, 3)
End Sub
Private Sub GanKetQua2(ByVal m As Long)
  Res(k, 4) = sArr2(m, 1)
  Res(k, 5) = sArr2(m, 2)
  Res(k, 6) = sArr2(m, 3)
End Sub
 
Upvote 0
Dữ liệu phải sort theo ưu tiên: Phiếu, Mã
Dữ liệu không có dòng trống
Kết quả mong muốn của bạn thiếu nhiều dòng
Kiểm tra code
Mã:
  Dim Res(), sArr(), sArr2()
  Dim Phieu As String, Ma As String, sRow As Long, sRow2 As Long
  Dim i As Long, i2 As Long, n2 As Long, k As Long

Sub Button1_Click1()
  With Sheets("Data")
      sArr = .Range("A2:C" & .Range("A" & Rows.Count).End(xlUp).Row + 1).Value
      sArr2 = .Range("D2:F" & .Range("D" & Rows.Count).End(xlUp).Row).Value
  End With
  Application.ScreenUpdating = False
  sRow = UBound(sArr) - 1
  sRow2 = UBound(sArr2)
  ReDim Res(1 To sRow + sRow2, 1 To 6)
  k = 0: n2 = 1
  For i = 1 To sRow
    Phieu = UCase(sArr(i, 2))
    If Phieu > UCase(sArr2(n2, 2)) Then
      Call Nho
    ElseIf Phieu = UCase(sArr2(n2, 2)) Then
      Call Bang
    Else
      Call Lon
    End If
    If k = UBound(Res) - 1 Then Exit For
  Next i
  With Sheets("KQ")
    i = .Range("A" & Rows.Count).End(xlUp).Row
    i2 = .Range("D" & Rows.Count).End(xlUp).Row
    If i2 > i Then i = i2
    If i > 1 Then .Range("A2:F" & i).ClearContents
    .Range("A2").Resize(k, 6) = Res
  End With
  Application.ScreenUpdating = True
End Sub
Private Sub Bang()
      Ma = sArr(i, 1)
      For i2 = n2 To sRow2
        If UCase(sArr2(i2, 2)) = Phieu Then
          If Len(sArr2(i2, 1)) > 0 Then
            If Ma > sArr2(i2, 1) Then
              k = k + 1: Call GanKetQua2(i2)
              sArr2(i2, 1) = ""
            ElseIf Ma = sArr2(i2, 1) Then
              k = k + 1:  Call GanKetQua1(i)
              If sArr2(i2, 1) = sArr(i, 1) And UCase(sArr2(i2, 2)) = UCase(sArr(i, 2)) And sArr2(i2, 3) = sArr(i, 3) Then
                Call GanKetQua2(i2)
                sArr2(i2, 1) = "": Exit For
              End If
            Else
              Exit For
            End If
          End If
        Else
          Exit For
        End If
      Next i2
      If Phieu <> UCase(sArr(i + 1, 2)) Then
        For i2 = n2 To sRow2
          If UCase(sArr2(i2, 2)) = Phieu Then
            If Len(sArr2(i2, 1)) > 0 Then
              k = k + 1: Call GanKetQua2(i2)
            End If
          Else
            n2 = i2: Exit For
          End If
        Next i2
      End If
End Sub
Private Sub Lon()
  Dim ik As Long
  For ik = i To UBound(sArr1)
    If Phieu = sArr1(ik, 2) Then
      If Len(sArr1(ik, 1)) > 0 Then
        k = k + 1
        Call GanKetQua1(ik)
      End If
    Else
      i = ik - 1: Exit For
    End If
  Next ik
End Sub
Private Sub Nho()
  For i2 = n2 To UBound(sArr2)
    If Phieu > sArr2(i2, 2) Then
      If Len(sArr2(i2, 1)) > 0 Then
        k = k + 1
        Call GanKetQua2(i2)
      End If
    Else
      n2 = i2: Exit For
    End If
  Next i2
End Sub
Private Sub GanKetQua1(ByVal m As Long)
  Res(k, 1) = sArr(m, 1)
  Res(k, 2) = sArr(m, 2)
  Res(k, 3) = sArr(m, 3)
End Sub
Private Sub GanKetQua2(ByVal m As Long)
  Res(k, 4) = sArr2(m, 1)
  Res(k, 5) = sArr2(m, 2)
  Res(k, 6) = sArr2(m, 3)
End Sub
Cảm ơn anh; em sẽ kiểm tra rồi báo anh sau.
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom