Dấu "|" trong nạp key cho Dic

Liên hệ QC

DMQ

Thành viên dốt
Tham gia
21/3/12
Bài viết
703
Được thích
53
Giới tính
Nam
Chào các anh, em có đoạn code như sau:
Mã:
Temp = Trim(dArr(1, 1)) & "|" & Trim(dArr(1, 2)) & "|" & Trim(dArr(1, 3)) ' XAC d?nh key cho dic
Sao em thay "|" bằng "-" thì code không chạy và cái dấu "|" lấy ở đâu tren bàn phím vậy các anh??
 
Chào các anh, em có đoạn code như sau:
Mã:
Temp = Trim(dArr(1, 1)) & "|" & Trim(dArr(1, 2)) & "|" & Trim(dArr(1, 3)) ' XAC d?nh key cho dic
Sao em thay "|" bằng "-" thì code không chạy và cái dấu "|" lấy ở đâu tren bàn phím vậy các anh??
Bạn ở diến đàn này 12 năm rồi, viết cả mấy trăm bài rồi mà còn hỏi "code không chạy"?
Không chạy có nghĩa là sao?
- Sub/Function chạy đến dòng ấy rồi ngừng
- VBA báo lỗi.
- Chẳng thấy vấn đề gì nhưng code không cho kết quả mong muốn

Copy cả cái Sub/Function ấy - ohieen bản sau khi bạn sửa "|" thành "-" đưa lên đây mới có thể thấy chỗ sai và chỉ cho bạn.

Dấu "|" nằm ở cái phím "\", trên phím "Enter". Vì ngày xưa, ký tự này có khoảng đứt ở giữa (giống như hai dấu trừ dựng đứng) cho nên nhiều bàn phím vẫn còn vẽ trên phím như vậy. Bạn gõ sẽ thấy bây giờ màn hình và máy in không còn khoảng đứt ở giữa.
 
Upvote 0
Em thấy dấu này ("|") rất nhiều người dùng trong các trường hợp nạp Key cho Dic, mà không dùng dấu khác.
Code đây bác @VetMini
Mã:
Private Sub Worksheet_Change(ByVal Target As Range) 

Application.ScreenUpdating = False
Application.EnableEvents = False
On Error GoTo Thoat

If Not Intersect(Target, Range("K6:K100000")) Is Nothing Then    ' nêu có su thay dôi o K6-K100000  thi
d = Target.Row   ' xác dinh dong có thay dôi
If IsArray(Target) Then   ' kiêm tra xem thay dôi co phai là mang không (truong hop copy nhiêu  dong paste vào ), nêu là mang thi
        dong = Target.Rows.Count     ' tính sô dong cua mang
        Arr = Range("E6:K" & d + dong - 1).Value  ' gán vung target (tu E6 dên K d+dong-1) là mang Arr
    Else      'neu target không là mang (truong hop go vao 1 ô)  thi
        dong = 1
        Arr = Range("E6:K" & d).Value   ' gan dong tu E6 dên K là mang Arr
End If
R1 = UBound(Arr)
If DicMR Is Nothing Then Call Add_DicMR  ' kiêm tra DicMR da có chua nêu chua thi chay code nap DicMR
For j = 1 To dong
If j > 1 Then d = d + 1   ' truong hop target là mang (dong>1)
        dArr = Range(Cells(d, 5), Cells(d, 11)).Value    ' xet tùng dong cua vung target gán thành mang dArr( chi co 1 dong)
    If dArr(1, 1) = Empty And dArr(1, 2) = Empty Then  'xet mang dArr nêu dArr(1,i)=Rông (chính là E(d)=rông) và dArr(i,2)=Rông (chính là F(d)=rong) thi hiên thông báo
        If MsgBox(" Xuât không có Job và NoDocument", vbYesNo, "THÔNG BÁO") = vbNo Then  ' nêu Click No  thi
            Target = ""   'Ô G(d)= rông
            GoTo Thoat    ' thoat khoi code
        Else                ' neu chon Yes thi Nhay xuong doan code Chay (có nghia là cho phep xuat khong có Job và noDocu..)
            GoTo Chay
        End If
    Else                    ' nêu co Job va NoDoCu thi nhay dên Chay
            GoTo Chay
    End If
Next j       ' kêt thuc xet tung dong target
End If         ' ket thuc su kien thay doi côt K
Chay:
        Temp = Trim(dArr(1, 1)) & "|" & Trim(dArr(1, 2)) & "|" & Trim(dArr(1, 3)) ' XAC d?nh key cho dic
         For i = 1 To R1    ' xet tung dong cua mang Arr   tu E6 dên K dong+d-1
           If Temp = Trim(Arr(i, 1)) & "|" & Trim(Arr(i, 2)) & "|" & Trim(Arr(i, 3)) Then 'so sanh voi key vói cac thanh phân cua mang Arr nêu = (giông nhau) thi
                If DicMR.Exists(Temp) Then  ' kiem tra trong Thu vien MR (dicMR) nêu da ton tai thi
                    t = t + 1           'sô lân xuât hiên key trong mang Arr
                    X = X + Arr(i, 7)   ' Tông sô da xuat (công dôn)
                    If X > MR(DicMR.Item(Temp), 2) Then     ' so sanh tông so da xuat voi sô liêu cua MR nêu lon hon thi
'                        MsgBox "Ma hàng này " & Temp & "da xuât " & t & " lân=" & X & Chr(10) & " Xuât lon hon MR. " & "(MR= " & MR(DicMR.Item(Temp), 2) & ")"
                        MsgBox " Job " & Temp & Chr(10) & " So luong MR = " & MR(DicMR.Item(Temp), 2) & Chr(10) & " So luong da xuat =" & X & Chr(10) & " So luong xuat nhieu hon MR =  " & X - MR(DicMR.Item(Temp), 2)
                        Range("K" & d) = ""    ' Xóa du liêu mói nhap vao côt K
                        GoTo Thoat             ' Chay dên thoat
                    End If
                End If
            End If
        Next i
Thoat:
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub

Option Explicit
Public ChkMR As Boolean, DicMR As Object, MR()
Sub Add_DicMR() 
Dim i&, t&, k&, R&, Lr&
    Dim Arr(), key
        Dim Sh As Worksheet
Set Sh = Sheets("MR")
    Lr = Sh.Cells(Rows.Count, 9).End(xlUp).Row
    Arr = Sh.Range("D6:Q" & Lr).Value
    R = UBound(Arr)
Set DicMR = CreateObject("Scripting.Dictionary")

ReDim MR(1 To R, 1 To 3)

For i = 1 To R
    If (Arr(i, 1)) <> Empty Then
        key = Trim(Arr(i, 1)) & "|" & Trim(Arr(i, 3)) & "|" & Trim(Arr(i, 5))
        If Not DicMR.Exists(key) Then
            t = t + 1
            DicMR.Add (key), t
            If Arr(i, 6) <> Empty Then MR(t, 1) = Arr(i, 6)
                MR(t, 2) = Arr(i, 7)
            If Arr(i, 14) <> Empty Then MR(t, 3) = Arr(i, 14)
        Else
            MR(DicMR.Item(key), 2) = MR(DicMR.Item(key), 2) + Arr(i, 7)
        End If
    End If
Next i
End Sub
Cứ chổ nào có dấu "|" là em thay "-".
 
Lần chỉnh sửa cuối:
Upvote 0
Em thấy dấu này ("|") rất nhiều người dùng trong các trường hợp nạp Key cho Dic, mà không dùng dấu khác.
...
Vì dấu này rất ít khi dùng trong chuỗi thật cho nên người ta chọn nó để là,m dấu ngăn cách hai chuỗi khác nhau.
Tưởng tượng, nếu chuỗi của bạn có chứa "-"
chuỗi 1: "Máy xúc đất-5 tấn"
chuỗi 2: "đất sét loại dẻo"
Nối lại: "Máy xúc đất-5 tấn-đất sét loại dẻo"
Đọc chuỗi nối này làm sao bạn biết 5 tấn thuộc về phần trước hay phần sau?
Chuỗi nối bằng "|": "Máy xúc đất-5 tấn|đất sét loại dẻo"
Nhìn rõ hơn, phải không?

Cứ chổ nào có dấu "|" là em thay "-".
Bạn chưa biết làm cách gõ ký tự "|". Vậy thì lúc thay thế bạn làm cách nào? Có phải bạn chọn dấu ấy, copy, mở hộp thoại Find/Replace lên và dán vào Find what?
Vì vậy, tôi nói gởi code "sau khi đã thay thế"

Tôi cũng có hỏi "không chạy" nghĩa là gì.
 
Upvote 0
Nó không chạy nghĩa là nó không hiện MsgBox khi có sự thay đổi cột K.
Lúc cột K mà em gõ số lượng vào lớn hơn số lượng "MR" thì có MsgBox hiện 4 dòng như sau:
1/job(Arr1)|(Arr2)|(Arr3)
2/so luong MR =
3/so luong da xuat =
4/so luong nhieu hon MR =
giờ em thay "|" bằng "-" cốt để dong 1 là : job(Arr1)-(Arr2)-(Arr3) nhìn cho dễ.loi98754.png
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi nhìn chỗ lòi ra trong bảng dữ liệu thì thấy dữ liệu của bạn có thể chứa dấu "-". Trường hợp này, code của bạn không thể dùng "-" để nối chuỗi.

Cách dễ nhất là cứ để yên code như vậy, lúc trình bày MsgBox thì dòng
MsgBox " Job " & Temp & Chr(10) & " So luong MR = " & MR(DicMR.Item(Temp), 2) & Chr(10) & " So luong da xuat =" & X & Chr(10) & " So luong xuat nhieu hon MR = " & X - MR(DicMR.Item(Temp), 2)
Bạn sửa thành:
MsgBox " Job " & Replace(Temp, "|", "-") & Chr(10) & " So luong MR = " & MR(DicMR.Item(Temp), 2) & Chr(10) & " So luong da xuat =" & X & Chr(10) & " So luong xuat nhieu hon MR = " & X - MR(DicMR.Item(Temp), 2)

Chú thích:
Code này viết theo dạng kinh điển GPE, có nhiều chỗ trong coding style (kiểu cách viết) tôi không đồng quan điểm cho nên tôi lười đọc và phân tích chi tiết.
 
  • Yêu thích
Reactions: DMQ
Upvote 0
giờ em thay "|" bằng "-" cốt để dong 1 là : job(Arr1)-(Arr2)-(Arr3) nhìn cho dễ.
Thay vào chỗ nào thì không nói! Sau khi thay nó như thế nào cũng không chịu cho xem!
Anh @VetMini hỏi 2 việc (1 việc anh ấy cố tình bôi đậm) là có lý do. Bạn cần, chứ không phải anh ấy cần, mà để anh ấy phải hỏi tới hỏi lui mãi.
 
Upvote 0
Nếu muốn tìm ra lỗi "không hiện MsgBox, thì cách tìm như sau:
- Nội dung mong muốn xuất hiện đang có gía trị gì
- MsgBox nằm trong mấy cái If, những cái If đó có thỏa không?

Cụ thể:
- click trên lề trái sao cho câu lệnh For sau câu Temp = Trim(Arr(i, 1)) & "-" & Trim(Arr(i, 2)) & "-" & Trim(Arr(i, 3)) bị tô đỏ
- Chạy code đến đó cho ngưng lại
- Xem temp có giá trị gì. Ghi nhớ nó
- nhấn F8 chạy từng dòng lệnh. Tới câu lệnh If Temp = Trim(Arr(i, 1)) & "-" & Trim(Arr(i, 2)) & "-" & Trim(Arr(i, 3)), xem lại giá trị Temp có thỏa If hay không
- đến câu lệnh If X > MR... xem lại temp có giá trị bao nhiêu và If có thỏa hay không

Tới đây xác định các thứ đều thỏa thì bắt buộc Msgbox phải chạy, sai 1 trong 5 thứ trên thì không chạy phải rồi.

Tôi nhìn chỗ lòi ra trong bảng dữ liệu thì thấy dữ liệu của bạn có thể chứa dấu "-".
Anh chỉ cách Replace là chỉ cách trị cái ngọn, là do không biết code sau khi thay | bằng - nó ra làm sao. Chứ tôi đoán rằng tác giả thay chưa triệt để. Chẳng hạn như thay vào khi gán giá trị cho biến temp, nhưng không thay khi tạo giá trị mới để so sánh với biến. Hoặc ngược lại.
 
Lần chỉnh sửa cuối:
Upvote 0
...
Anh chỉ cách Replace là chỉ cách trị cái ngọn, là do không biết code sau khi thay | bằng - nó ra làm sao. Chứ tôi đoán rằng tác giả thay chưa triệt để. Chẳng hạn như thay vào khi gán giá trị cho biến temp, nhưng không thay khi tạo giá trị mới để so sánh với biến. Hoặc ngược lại.
Nếu mục đích của thớt là "hiển thị dễ nhìn" thì trị cái ngọn là đúng đường lối - If it aint broke, dont fix it.

Về sau này, có muốn dùng chuỗi ngăn/delimiter là cái gì ("%$#") cũng không sao. Chỉ tiếc là code này viết theo kiểu thịnh hành của GPE:
- Sử dụng "magic numbers". Đáng lẽ phải đặt Const DELIM.
- Sử dụng tên Temp quá đáng. Theo luật không thành văn của dân viết code thì các tên Temp, Tmp chỉ dùng cho mục đích "temporary/tạm bợ". Đời sống của nó chỉ trong vòng 2-3 dòng code, điển hình là code hoán đổi/swap trị của hai biến (tm = a, a = b, b = tm). Chạy luôn bấy dòng code làm sao gọi là tạm bợ được? Người đầu tiên viết code dùng Temp này nghèo từ ngữ cho nên đặt đại tên rồi về sau người khác cứ theo.
 
Upvote 0
Tôi nhìn chỗ lòi ra trong bảng dữ liệu thì thấy dữ liệu của bạn có thể chứa dấu "-". Trường hợp này, code của bạn không thể dùng "-" để nối chuỗi.
Dạ đúng bác @VetMini ạ, nếu em thay dấu "-" thì Dic tìm không ra.
Em thay code của Bác vào đã đúng ạ.
 
Upvote 0
Dạ đúng bác @VetMini ạ, nếu em thay dấu "-" thì Dic tìm không ra.
Em thay code của Bác vào đã đúng ạ.
thử các phương án thế này
thay tất cả | thành
"||"
hoặc
"#"
hoặc
1 dấu cách " "
hoặc chữ
"a"
Xem cái nào chạy cái nào không, tại sao, cứ thử sẽ biết --> sau đó tại sao hiểu sao thì viết bài ra đây
Khi đó bạn sẽ .... hỏi tới hỏi lui, giải thích hoài không biết đang mắc gì hỏi gì (?)
 
Upvote 0
Dạ đúng bác @VetMini ạ, nếu em thay dấu "-" thì Dic tìm không ra.
Em thay code của Bác vào đã đúng ạ.
Dù sửa xong đã đúng thì cũng phải tìm hiểu tại sao tự mình sửa thì lại sai. Khi biết tại sao sai thì mới tránh cho lần sau và tiến bộ.
 
Upvote 0
Web KT
Back
Top Bottom