Lọc và tách dữ liệu theo điều kiện?

Liên hệ QC

Hoàng Nhật Phương

Thành viên gắn bó
Tham gia
5/11/15
Bài viết
1,894
Được thích
1,213
Xin chào các Bạn,
Hiện tôi đang có dữ liệu trong Sheet "DuLieu" như sau:
222337

Nhờ các bạn giúp đỡ đoạn code xử lý tách dữ liệu trong cột MaID ngăn cách nhau bởi dấu "/" thành nhiều dòng
và lọc theo cột thời gian và cột ca, lọc duy nhất 4 cột cho ra Sheet"KQ" như sau:
222341
 

File đính kèm

  • Tach va Loc Duy Nhat.xlsx
    132.5 KB · Đọc: 25
Lần chỉnh sửa cuối:
Bước 1 là 'lọc' (AdvancedFilter), nếu bạn đồng ý ta tiếp phần 'tách'
 

File đính kèm

  • Filter.rar
    77.3 KB · Đọc: 20
Upvote 0
Bước 1 là 'lọc' (AdvancedFilter), nếu bạn đồng ý ta tiếp phần 'tách'
Con chào Bác SA,
Cách nào cũng được hết Bác ạ, miễn sao tốc độ nhanh nhanh là OK hết Bác ah, vì dữ liệu của con lấy từ SQL ra nên tương đối nhiều.
Nhờ Bác xem giúp ạ.
Chúc Bác ngày mới vui khỏe.
 
Upvote 0
Khoảng bao nhiêu dòng mà nhiều bạn OverTime ?

Chào Bạn,
Cảm ơn Bạn đã quan tâm,thực sự OT hay làm việc với bảng tính nhiều dữ liệu. Đối với dữ liệu thực trong file này nhiều khoảng 6 tháng và tất cả các khách hàng chắc tầm mấy chục ngàn dòng thôi ạ, vì dữ liệu lấy từ SQL vào nên cũng lấy theo từng thời điểm tùy thuộc nhu cầu người muốn lấy ạ.
Rất mong nhận được sự giúp đỡ của AnhCU :D
Bài đã được tự động gộp:

Xin lỗi mọi người, hỏi bài về khuya nên OT quên mất một điều kiện nữa là lọc duy nhất ạ.
Hiện đã bổ sung và gửi lại file ở bài 1.
Rất mong nhận được sự giúp đỡ của các Bạn.
 
Lần chỉnh sửa cuối:
Upvote 0
Cho hỏi thêm là lọc duy nhất (theo ca) rồi mới tách (theo cột MaiD) hay tách trước rồi lọc duy nhất?

Nếu lọc duy nhất trước thì chỉ sửa lại tí thôi:
Mã:
Sub LocToanBo()
' Keyboard Shortcut: Ctrl+Shift+L
Dim Rws As Long   ' +    '
Rws = Sheets("DuLieu").[B2].CurrentRegion.Rows.Count    ' +     '
Sheets("DuLieu").Range("A1:F" & Rws).AdvancedFilter Action:=xlFilterCopy, _
        CriteriaRange:=Range("G1:I2"), CopyToRange:=Range("A4:E4"), Unique:=True
End Sub
 
Upvote 0
Cho hỏi thêm là lọc duy nhất (theo ca) rồi mới tách (theo cột MaiD) hay tách trước rồi lọc duy nhất?

Nếu lọc duy nhất trước thì chỉ sửa lại tí thôi:
Mã:
Sub LocToanBo()
' Keyboard Shortcut: Ctrl+Shift+L
Dim Rws As Long   ' +    '
Rws = Sheets("DuLieu").[B2].CurrentRegion.Rows.Count    ' +     '
Sheets("DuLieu").Range("A1:F" & Rws).AdvancedFilter Action:=xlFilterCopy, _
        CriteriaRange:=Range("G1:I2"), CopyToRange:=Range("A4:E4"), Unique:=True
End Sub
Bác ơi, còn trường hợp tách MaID nữa Bác xem giúp con ạ. T_T
 
Upvote 0
Lý ra chuyện này phải tự làm mới phải, may mà hôm nay mát trời:
PHP:
Sub TachMaID()
Dim Rws As Long, J As Integer, W As Long, Col As Byte, VTr As Byte
Dim Arr():                                              Const FC As String = "/"
Dim MaID As String

With Sheets("KQ")
    Rws = .[A5].CurrentRegion.Rows.Count:    Arr() = .[A5].Resize(Rws, 4).Value
    ReDim dArr(1 To 9 * Rws, 1 To 4) As String
End With
For J = 1 To UBound(Arr())
    MaID = Arr(J, 1):                                  If MaID = "" Then Exit For
    VTr = InStr(MaID, FC)
    If VTr Then
        MaID = MaID & FC
        Do
            W = W + 1:                                 dArr(W, 1) = Left(MaID, VTr - 1)
            For Col = 2 To 4
                dArr(W, Col) = Arr(J, Col)
            Next Col
            MaID = Mid(MaID, VTr + 1, Len(MaID)):      VTr = InStr(MaID, FC)
            If VTr < 1 Then Exit Do
        Loop
    Else
        W = W + 1:
        For Col = 1 To 4
            dArr(W, Col) = Arr(J, Col)
        Next Col
    End If
Next J
MsgBox W
End Sub
 
Upvote 0
Chào Bạn,
Cảm ơn Bạn đã quan tâm,thực sự OT hay làm việc với bảng tính nhiều dữ liệu. Đối với dữ liệu thực trong file này nhiều khoảng 6 tháng và tất cả các khách hàng chắc tầm mấy chục ngàn dòng thôi ạ, vì dữ liệu lấy từ SQL vào nên cũng lấy theo từng thời điểm tùy thuộc nhu cầu người muốn lấy ạ.
Rất mong nhận được sự giúp đỡ của AnhCU :D
Bài đã được tự động gộp:

Xin lỗi mọi người, hỏi bài về khuya nên OT quên mất một điều kiện nữa là lọc duy nhất ạ.
Hiện đã bổ sung và gửi lại file ở bài 1.
Rất mong nhận được sự giúp đỡ của các Bạn.

Em có dùng Power Query không? Anh thấy có tính năng tách Chuỗi (phân cách nhau bằng các ký hiệu) trong Cell thành từng dòng rất nhanh đó.
 
Upvote 0
Lý ra chuyện này phải tự làm mới phải, may mà hôm nay mát trời:
Nếu sau khi lọc có kết quả

ID00000528 P0043 SP43 KH 280
ID00000529 P0043 SP43 KH 280
ID00000528/ID00000529 P0043 SP43 KH 280

thì sau khi chạy TachMaID sẽ có 4 kết quả - 2 kết quả bị lặp lại.
 
Upvote 0
Biết đâu nà. . . !, phải chờ ý của chủ bài đăng thôi!
 
Upvote 0
Em có dùng Power Query không? Anh thấy có tính năng tách Chuỗi (phân cách nhau bằng các ký hiệu) trong Cell thành từng dòng rất nhanh đó.
Xin chào Anh ongke0711,
Cảm ơn anh đã góp ý, cách nào cũng được anh ạ, miễn là kết quả xuất ra nhanh chóng và chính xác ạ.
Có thể có nhều cách làm và mỗi người một sở thích để tham khảo và lựa chọn anh ạ.
Anh có thể chỉ dẫn thêm được không ạ.

Lý ra chuyện này phải tự làm mới phải, may mà hôm nay mát trời:
PHP:
Sub TachMaID()
Dim Rws As Long, J As Integer, W As Long, Col As Byte, VTr As Byte
Dim Arr():                                              Const FC As String = "/"
Dim MaID As String

With Sheets("KQ")
    Rws = .[A5].CurrentRegion.Rows.Count:    Arr() = .[A5].Resize(Rws, 4).Value
    ReDim dArr(1 To 9 * Rws, 1 To 4) As String
End With
For J = 1 To UBound(Arr())
    MaID = Arr(J, 1):                                  If MaID = "" Then Exit For
    VTr = InStr(MaID, FC)
    If VTr Then
        MaID = MaID & FC
        Do
            W = W + 1:                                 dArr(W, 1) = Left(MaID, VTr - 1)
            For Col = 2 To 4
                dArr(W, Col) = Arr(J, Col)
            Next Col
            MaID = Mid(MaID, VTr + 1, Len(MaID)):      VTr = InStr(MaID, FC)
            If VTr < 1 Then Exit Do
        Loop
    Else
        W = W + 1:
        For Col = 1 To 4
            dArr(W, Col) = Arr(J, Col)
        Next Col
    End If
Next J
MsgBox W
End Sub

Xin chào Bác SA_DQ,
Cảm ơn Bác đã dành thời gian giúp đỡ ạ. Thực sự vấn đề này con chưa thể thực hiện được.
Code này hiện chưa ra kết quả con mong muốn Bác ạ.
Hiện con đang làm thủ công như sau lọc theo ngày và ca cần lấy thông tin sau đó tách từng mã trong cột MaID, mỗi mã một dòng, rồi cuối cùng là lọc duy nhất 4 cột cho ra kết quả như ảnh và file kèm bài 1 ạ. Nếu không phiền mong Bác xử lý thêm cho con ạ.

lọc duy nhất 4 cột cho ra Sheet"KQ" như sau
Xin chào Bác Siwtom
Cảm ơn Bác đã luôn quan tâm và giúp đỡ.
Đúng như vậy Bác ạ,tiện đây nếu Bác có thời gian và hứng thú mong Bác chỉ dẫn thêm một cách làm khác ạ.
 
Upvote 0
Bạn thử test xem đúng ý không. Tôi làm với lọc duy nhất. Có đúng lọc duy nhất không hay liệt kê hết?

Code đòi hỏi MaID, MaSP, TenSP, MaKH đều có độ dài cố định. Dài bao nhiêu cũng được miễn là luôn như thế. Vd. MaID luôn có 12 ký tự, MaSP - luôn 7, TenSP - luôn 6, MaKH - luôn 8. Hiện thời chúng luôn có 10, 5, 5, 5 ký tự. Nếu khác thì sửa trong code.

Dấu phân cách các MaID có thể bất kỳ, thậm chí chỗ này là "/", chỗ khác là "," - dấu phẩy, chỗ khác nữa là ";" - dấu chấm phẩy, chỗ nọ lại là "*". Yêu cầu chỉ là không được có dấu cách trong chuỗi. Vd. ID00001729<dấu cách>/ID00001730 là không hợp lệ.

Tôi viết cho tập tin đính kèm của bạn. Vd. cho 3 ca thì bạn dùng "All".

Tôi viết xong chỉ test 1 lần. Thấy ra kết quả nhưng ngại dò xem kết quả đúng hay không. Vậy bạn tự kiểm tra. Thuật toán thì rõ ràng rồi. Chỉ sợ nhầm lẫn khi viết code thôi.

Nếu bạn có tầm trăm, vài trăm ngàn dòng dữ liệu thì báo cáo tốc độ nhé. Tôi hơi tò mò.
Mã:
Sub FilterAndUnique()
Dim lastRow As Long, r As Long, ngay As Long, pos As Long, size As Long, currRow As Long
Dim MaID As String, s As String, ca As String, text As String, data(), dic As Object
    With ThisWorkbook.Worksheets("DuLieu")
        lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
        If lastRow < 2 Then Exit Sub
        data = .Range("A2:F" & lastRow).Value
    End With
    text = String(25, "a")
    With ThisWorkbook.Worksheets("KQ")
        ngay = .Range("C1").Value
        ca = LCase(.Range("C2").Value)
        .Range("A5:D10000").ClearContents
    End With
    
    Set dic = CreateObject("Scripting.Dictionary")
    currRow = 0
    For r = 1 To UBound(data)
        If (CDbl(data(r, 4)) >= ngay) And (CDbl(data(r, 4)) <= ngay + 1) Then
            If ca = "all" Or ca = LCase(data(r, 5)) Then
                s = data(r, 1)
                pos = 1
                size = Len(s)
                Mid(text, 11, 5) = data(r, 2)
                Mid(text, 16, 5) = data(r, 3)
                Mid(text, 21, 5) = data(r, 6)
                Do While pos < size
                    MaID = Mid(s, pos, 10)
                    Mid(text, 1, 10) = MaID
                    pos = pos + 11
                    If Not dic.exists(text) Then
                        currRow = currRow + 1
                        dic.Add text, ""
                        data(currRow, 1) = MaID
                        data(currRow, 2) = data(r, 2)
                        data(currRow, 3) = data(r, 3)
                        data(currRow, 4) = data(r, 6)
                    End If
                Loop
            End If
        End If
    Next r
    ThisWorkbook.Worksheets("KQ").Range("A5").Resize(currRow, 4).Value = data
    Set dic = Nothing
End Sub
 
Upvote 0
Bạn thử test xem đúng ý không. Tôi làm với lọc duy nhất. Có đúng lọc duy nhất không hay liệt kê hết?

Code đòi hỏi MaID, MaSP, TenSP, MaKH đều có độ dài cố định. Dài bao nhiêu cũng được miễn là luôn như thế. Vd. MaID luôn có 12 ký tự, MaSP - luôn 7, TenSP - luôn 6, MaKH - luôn 8. Hiện thời chúng luôn có 10, 5, 5, 5 ký tự. Nếu khác thì sửa trong code.

Dấu phân cách các MaID có thể bất kỳ, thậm chí chỗ này là "/", chỗ khác là "," - dấu phẩy, chỗ khác nữa là ";" - dấu chấm phẩy, chỗ nọ lại là "*". Yêu cầu chỉ là không được có dấu cách trong chuỗi. Vd. ID00001729<dấu cách>/ID00001730 là không hợp lệ.

Tôi viết cho tập tin đính kèm của bạn. Vd. cho 3 ca thì bạn dùng "All".

Tôi viết xong chỉ test 1 lần. Thấy ra kết quả nhưng ngại dò xem kết quả đúng hay không. Vậy bạn tự kiểm tra. Thuật toán thì rõ ràng rồi. Chỉ sợ nhầm lẫn khi viết code thôi.

Nếu bạn có tầm trăm, vài trăm ngàn dòng dữ liệu thì báo cáo tốc độ nhé. Tôi hơi tò mò.
Mã:
Sub FilterAndUnique()
Dim lastRow As Long, r As Long, ngay As Long, pos As Long, size As Long, currRow As Long
Dim MaID As String, s As String, ca As String, text As String, data(), dic As Object
    With ThisWorkbook.Worksheets("DuLieu")
        lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
        If lastRow < 2 Then Exit Sub
        data = .Range("A2:F" & lastRow).Value
    End With
    text = String(25, "a")
    With ThisWorkbook.Worksheets("KQ")
        ngay = .Range("C1").Value
        ca = LCase(.Range("C2").Value)
        .Range("A5:D10000").ClearContents
    End With
   
    Set dic = CreateObject("Scripting.Dictionary")
    currRow = 0
    For r = 1 To UBound(data)
        If (CDbl(data(r, 4)) >= ngay) And (CDbl(data(r, 4)) <= ngay + 1) Then
            If ca = "all" Or ca = LCase(data(r, 5)) Then
                s = data(r, 1)
                pos = 1
                size = Len(s)
                Mid(text, 11, 5) = data(r, 2)
                Mid(text, 16, 5) = data(r, 3)
                Mid(text, 21, 5) = data(r, 6)
                Do While pos < size
                    MaID = Mid(s, pos, 10)
                    Mid(text, 1, 10) = MaID
                    pos = pos + 11
                    If Not dic.exists(text) Then
                        currRow = currRow + 1
                        dic.Add text, ""
                        data(currRow, 1) = MaID
                        data(currRow, 2) = data(r, 2)
                        data(currRow, 3) = data(r, 3)
                        data(currRow, 4) = data(r, 6)
                    End If
                Loop
            End If
        End If
    Next r
    ThisWorkbook.Worksheets("KQ").Range("A5").Resize(currRow, 4).Value = data
    Set dic = Nothing
End Sub

Con cảm ơn Bác Siwtom nhiều ạ,
Code nhanh quá và kết quả đúng ý con rồi, tuy nhiên trường hợp ở đây là số lý tự (độ dài các ký tự ở trong cùng cột và ở giữa các cột trong thực tế sẽ không giống nhau ạ),sản phẩm này mã dài tên dài, sản phẩm khác tên dài mã ngắn v.v... Nếu phải chỉnh lại trong code thì chỉnh lại như thế nào để với độ dài bất kỳ của mã sản phẩm hoặc tên sản phẩm napf cũng có thể xử lý được ạ Bác
Con gửi file dữ liệu giả lập trên 200k dòng ạ. Tốc độ thực sự rất nhanh ạ.

Chúc Bác nhiều sức khỏe.
 
Upvote 0
tuy nhiên trường hợp ở đây là số lý tự (độ dài các ký tự ở trong cùng cột và ở giữa các cột trong thực tế sẽ không giống nhau ạ),sản phẩm này mã dài tên dài, sản phẩm khác tên dài mã ngắn v.v...
Thực ra code bài trước của tôi có lỗi mà bạn không phát hiện ra.
Do tôi không nghĩ kỹ nên dùng 1 mảng data. Do code ghi kết quả vào mảng nguồn data nên có thể (không luôn luôn) ở vòng lặp nào đó dữ liệu đọc ra từ mảng nguồn data sẽ sai và dẫn tới lỗi.

Bây giờ tôi dùng thêm mảng kết quả.

Điều kiện: MaID, MaSP, TenSP có ít nhất là 1 ký tự, nhiều nhất là 15 ký tự, và MaKH có nhiều nhất là 10 ký tự. Tôi nghĩ là quá đủ. Nếu chưa đủ thì bạn hãy cho biết mỗi trường có thể có nhiều nhất là bao nhiêu ký tự. Cứ cho dư ra cũng được.

Hãy test kỹ.

Mã:
Sub FilterAndUnique()
Dim lastRow As Long, k As Long, r As Long, ngay As Long, pos As Long, size As Long, currRow As Long
Dim MaID As String, s As String, ca As String, text As String, data(), result(), dic As Object
    With ThisWorkbook.Worksheets("DL")
        lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
        If lastRow < 2 Then Exit Sub
        data = .Range("A2:F" & lastRow).Value
    End With
    ReDim result(1 To 10000, 1 To 4)
    With ThisWorkbook.Worksheets("KQ")
        ngay = .Range("C1").Value
        ca = LCase(.Range("C2").Value)
        .Range("A5:D10000").ClearContents
    End With

    Set dic = CreateObject("Scripting.Dictionary")
    currRow = 0
    For r = 1 To UBound(data)
        If (CDbl(data(r, 4)) >= ngay) And (CDbl(data(r, 4)) <= ngay + 1) Then
            If ca = "all" Or ca = LCase(data(r, 5)) Then
                s = data(r, 1) & "/"
                pos = 1
                size = Len(s)
                text = String(58, Chr(0))
                
                Mid(text, 17, Len(data(r, 2))) = data(r, 2)
                Mid(text, 33, Len(data(r, 3))) = data(r, 3)
                Mid(text, 49, Len(data(r, 6))) = data(r, 6)
                Do While pos < size
                    k = InStr(pos, s, "/")
                    MaID = Mid(s, pos, k - pos)
                    Mid(text, 1, Len(MaID)) = MaID
                    pos = k + 1
                    If Not dic.exists(text) Then
                        currRow = currRow + 1
                        dic.Add text, ""
                        result(currRow, 1) = MaID
                        result(currRow, 2) = data(r, 2)
                        result(currRow, 3) = data(r, 3)
                        result(currRow, 4) = data(r, 6)
                    End If
                Loop
            End If
        End If
    Next r
    If currRow Then ThisWorkbook.Worksheets("KQ").Range("A5").Resize(currRow, 4).Value = result
    Set dic = Nothing
End Sub
 
Upvote 0
Thực ra code bài trước của tôi có lỗi mà bạn không phát hiện ra.
Do tôi không nghĩ kỹ nên dùng 1 mảng data. Do code ghi kết quả vào mảng nguồn data nên có thể (không luôn luôn) ở vòng lặp nào đó dữ liệu đọc ra từ mảng nguồn data sẽ sai và dẫn tới lỗi.

Bây giờ tôi dùng thêm mảng kết quả.

Điều kiện: MaID, MaSP, TenSP có ít nhất là 1 ký tự, nhiều nhất là 15 ký tự, và MaKH có nhiều nhất là 10 ký tự. Tôi nghĩ là quá đủ. Nếu chưa đủ thì bạn hãy cho biết mỗi trường có thể có nhiều nhất là bao nhiêu ký tự. Cứ cho dư ra cũng được.

Hãy test kỹ.

Mã:
Sub FilterAndUnique()
Dim lastRow As Long, k As Long, r As Long, ngay As Long, pos As Long, size As Long, currRow As Long
Dim MaID As String, s As String, ca As String, text As String, data(), result(), dic As Object
    With ThisWorkbook.Worksheets("DL")
        lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
        If lastRow < 2 Then Exit Sub
        data = .Range("A2:F" & lastRow).Value
    End With
    ReDim result(1 To 10000, 1 To 4)
    With ThisWorkbook.Worksheets("KQ")
        ngay = .Range("C1").Value
        ca = LCase(.Range("C2").Value)
        .Range("A5:D10000").ClearContents
    End With

    Set dic = CreateObject("Scripting.Dictionary")
    currRow = 0
    For r = 1 To UBound(data)
        If (CDbl(data(r, 4)) >= ngay) And (CDbl(data(r, 4)) <= ngay + 1) Then
            If ca = "all" Or ca = LCase(data(r, 5)) Then
                s = data(r, 1) & "/"
                pos = 1
                size = Len(s)
                text = String(58, Chr(0))
                Mid(text, 17, Len(data(r, 2))) = data(r, 2)
                Mid(text, 33, Len(data(r, 3))) = data(r, 3)
                Mid(text, 49, Len(data(r, 6))) = data(r, 6)

                Do While pos < size
                    k = InStr(pos, s, "/")
                    MaID = Mid(s, pos, k - pos)
                    Mid(text, 1, Len(MaID)) = MaID
                    pos = k + 1
                    If Not dic.exists(text) Then
                        currRow = currRow + 1
                        dic.Add text, ""
                        result(currRow, 1) = MaID
                        result(currRow, 2) = data(r, 2)
                        result(currRow, 3) = data(r, 3)
                        result(currRow, 4) = data(r, 6)
                    End If
                Loop
            End If
        End If
    Next r
    If currRow Then ThisWorkbook.Worksheets("KQ").Range("A5").Resize(currRow, 4).Value = result
    Set dic = Nothing
End Sub
Xin chào Bác Siwtom
Cảm ơn Bác đã giúp đỡ con ạ, code chạy nhanh và kết quả OK so với dữ liệu con gửi lên ạ.Hiện đối với mã sản phẩm thì quy định tối thiểu là 18 ký tự và tối đa là 25.Còn tên sản phẩm thì không có quy định có lúc thì dưới 10 có tên thì dài nhưng không quá 35 ký tự nếu số ký tự bị vượt quá trong code quy định thì con cần phải sửa con số nào trong code vậy Bác, nhờ Bác chú thích giúp con các con số 58,17,33,49 trong các dòng code sau với ạ.
Mã:
text = String(58, Chr(0))
Mid(text, 17, Len(data(r, 2))) = data(r, 2)
Mid(text, 33, Len(data(r, 3))) = data(r, 3)
Mid(text, 49, Len(data(r, 6))) = data(r, 6)
Chúc Bác nhiều sức khỏe.
 
Upvote 0
Xin chào Bác Siwtom
Cảm ơn Bác đã giúp đỡ con ạ, code chạy nhanh và kết quả OK so với dữ liệu con gửi lên ạ.Hiện đối với mã sản phẩm thì quy định tối thiểu là 18 ký tự và tối đa là 25.Còn tên sản phẩm thì không có quy định có lúc thì dưới 10 có tên thì dài nhưng không quá 35 ký tự nếu số ký tự bị vượt quá trong code quy định thì con cần phải sửa con số nào trong code vậy Bác, nhờ Bác chú thích giúp con các con số 58,17,33,49 trong các dòng code sau với ạ.

Em xem lại qui định tạo mã các trường làm khoá. Đúng ra là phải cố định số ký tự đó em, chỉ có trường tên, diễn giải là không cố định thôi.

@batman1: Em nghĩ không cần dùng tới trường TenSP đâu anh, MaSP là đủ đại diện rồi.
 
Upvote 0
Xin chào Bác Siwtom
Cảm ơn Bác đã giúp đỡ con ạ, code chạy nhanh và kết quả OK so với dữ liệu con gửi lên ạ.Hiện đối với mã sản phẩm thì quy định tối thiểu là 18 ký tự và tối đa là 25.Còn tên sản phẩm thì không có quy định có lúc thì dưới 10 có tên thì dài nhưng không quá 35 ký tự nếu số ký tự bị vượt quá trong code quy định thì con cần phải sửa con số nào trong code vậy Bác, nhờ Bác chú thích giúp con các con số 58,17,33,49 trong các dòng code sau với ạ.
Mã:
text = String(58, Chr(0))
Mid(text, 17, Len(data(r, 2))) = data(r, 2)
Mid(text, 33, Len(data(r, 3))) = data(r, 3)
Mid(text, 49, Len(data(r, 6))) = data(r, 6)
Chúc Bác nhiều sức khỏe.
Mã:
text = String("độ lớn", Chr(0))

với "độ lớn" = max(MaID) + max(MaSP) + max(TenSP) + max(MaKH) + 3 (3 ký tự 0 phân cách 4 thành phần)

Với max(MaID) = max(MaSP) = max(TenSP) = 15 và max(MaKH) = 10 thì "độ lớn " = 58

text có dạng: = <MaID><một loạt ký tự 0 thứ nhất><ký tự 0 phân cách><MaSP><một loạt ký tự 0 thứ hai><ký tự 0 phân cách><TenSP><một loạt ký tự 0 thứ ba><ký tự 0 phân cách><MaKH><một loạt ký tự 0 thứ tư>

Trong đó:

<MaID><một loạt ký tự 0 thứ nhất> = max(MaID)
<MaSP><một loạt ký tự 0 thứ hai> = max(MaSP)
<TenSP><một loạt ký tự 0 thứ ba> = max(TenSP)
<MaKH><một loạt ký tự 0 thứ tư> = max(MaKH)

Mã:
Mid(text, max(MaID) + 2, Len(data(r, 2))) = data(r, 2)
Mid(text, max(MaID) + max(MaSP) + 3, Len(data(r, 3))) = data(r, 3)
Mid(text, max(MaID) + max(MaSP) + max(TenSP) + 4, Len(data(r, 6))) = data(r, 6)
 
Upvote 0
Em xem lại qui định tạo mã các trường làm khoá. Đúng ra là phải cố định số ký tự đó em, chỉ có trường tên, diễn giải là không cố định thôi.

@batman1: Em nghĩ không cần dùng tới trường TenSP đâu anh, MaSP là đủ đại diện rồi.
Xin chào anh ongke0711,
Cảm ơn Anh đã quan tâm ạ.
Đúng là xét trong csdl thì mã phần mềm cần phải qui định chuẩn 10 là 10 và 18 là 18 không có chuyện 10~18 ạ. Ocn tên sản phẩm là phần diễn giải (cột phụ đi kèm) như anh đã nêu đó ạ.
Và cái mã OT gửi lên là theo quy định mã phần mềm, còn theo mã khách hàng thì giao động trong khoảng 18~25 ký tự anh ạ, từ ký tự 18 trở đi họ có các ký tự khác để phân biệt, do đó OT muôn hỏi thêm nếu trong trường hợp lọc theo mã khách hàng hoặc tên sản phẩm có số ký tự giao động lớn hơn code quy định thì sẽ xử lý chỗ nào ạ. Về cơ bản code của Bác Siwtom đã xử lý được vấn đề của OT rồi ạ, nhưng cần chuẩn hóa lại dữ liệu về độ dài ký tự mã và tên sản phẩm.
Bài đã được tự động gộp:

Mã:
text = String("độ lớn", Chr(0))

với "độ lớn" = max(MaID) + max(MaSP) + max(TenSP) + max(MaKH) + 3 (3 ký tự 0 phân cách 4 thành phần)

Với max(MaID) = max(MaSP) = max(TenSP) = 15 và max(MaKH) = 10 thì "độ lớn " = 58

text có dạng: = <MaID><một loạt ký tự 0 thứ nhất><ký tự 0 phân cách><MaSP><một loạt ký tự 0 thứ hai><ký tự 0 phân cách><TenSP><một loạt ký tự 0 thứ ba><ký tự 0 phân cách><MaKH><một loạt ký tự 0 thứ tư>

Trong đó:

<MaID><một loạt ký tự 0 thứ nhất> = max(MaID)
<MaSP><một loạt ký tự 0 thứ hai> = max(MaSP)
<TenSP><một loạt ký tự 0 thứ ba> = max(TenSP)
<MaKH><một loạt ký tự 0 thứ tư> = max(MaKH)

Mã:
Mid(text, max(MaID) + 2, Len(data(r, 2))) = data(r, 2)
Mid(text, max(MaID) + max(MaSP) + 3, Len(data(r, 3))) = data(r, 3)
Mid(text, max(MaID) + max(MaSP) + max(TenSP) + 4, Len(data(r, 6))) = data(r, 6)
Cảm ơn Bác Siwtom nhiều ạ,
Đến đây con có thể tự xử lý theo ý mình được rồi ạ.
 
Upvote 0
Web KT
Back
Top Bottom