Tính toán và đếm hàng hóa xuất nhập khẩu dùng Dictionary

Liên hệ QC

hoahuongduong1986

Thành viên thường trực
Tham gia
14/11/18
Bài viết
346
Được thích
40
Kính gửi anh chị,
Em mới tham khảo và làm được code lọc cột C, D, E tại sheet DIC.
=> Nhờ a chị và các bạn hỗ trợ tính, đếm thêm cột F và G như ví dụ em có làm cho mã WLD với điều kiện trường Reporter ISO tại sheet Data bỏ toàn bộ các khách mã có ký tự bắt đầu bằng chữ A và kết quả xuất ra theo thứ tự lớn giảm dần của tổng Trade Value (US$). Em cảm ơn ạ !
 

File đính kèm

  • Tinh toan XNK - DICTIONARY.xlsm
    1.7 MB · Đọc: 46
Không phải thêm 4 trường, mà là thêm 4 keys, mỗi key có item là số thứ tự cột. Bài này tác giả dùng 1 Dic cho 2 nội dung: 1 là trade flow và 1 là Partner ISO.
(Khi gán vào mảng kết quả, thì key nào sẽ gắn vào cột là item của key đó (4, 5, 6, 7)
Bạn phải đọc lại giải thích bên trên, trên đó ghi rõ là kết quả cuối chỉ cần 5 cột, nhưng tạo mảng tới 11 cột. 8 cột phía sau chỉ dùng để tính toán, sau đó ghi đè 2 cột 4, 5 còn 6 cột thì bỏ, không đưa xuống.
* Nói rồi, xài gộp Dic khổ như vậy đấy.
Vậy bài này để tường mình phải xơi 2 cái đít xần rồi nối lại với nhau sư phụ nhỉ?
 
Upvote 0
Vậy bài này để tường mình phải xơi 2 cái đít xần rồi nối lại với nhau sư phụ nhỉ?
Hai cái là hai cái, nối lại làm gì. Nếu đặt tên tường minh thì 1 cái tên là DicTradeflow, 1 cái tên là DicPartner. Bài này cũng không quá khó, code ở mức đơn giản vừa phải, thì Dic1 Dic2 cũng chấp nhận được.
Khi tôi viết cho 1 chương trình tương đối lớn thì dùng đến 5, 7 Dics cho các danh mục, 2 Dic cho việc liệt kê lỗi (cụ thể là lỗi mặt hàng chưa tồn tại, khách hàng chưa tồn tại). Bắt buộc phải khai báo tường minh và đặt tên tường minh.

Cụ thể là khai báo Public các danh mục để chạy nhiều thủ tục:

1631930594860.png

Khai báo Dic chứa lỗi trong từng thủ tục:
1631930641013.png

Kết quả từng thủ tục có thống kê lỗi:

1631930678048.png

Và liệt kê danh mục lỗi (không tồn tại) để người dùng bổ sung:

1631930729331.png

Mỗi Dic danh mục lên đến hàng ngàn, 7 cái lên đến hàng chục ngàn, gộp lại mà tìm kiếm trong đống gộp chung đó cho chết!
Thống kê phải lấy Dic.Count, Liệt kê xuống sheet phải liệt kê bằng Dic.Keys và Dic.Items. Gộp rồi thì làm sao có được.
 
Lần chỉnh sửa cuối:
Upvote 0
Hai cái là hai cái, nối lại làm gì. Nếu đặt tên tường minh thì 1 cái tên là DicTradeflow, 1 cái tên là DicPartner. Bài này cũng không quá khó, code ở mức đơn giản vừa phải, thì Dic1 Dic2 cũng chấp nhận được.
Khi tôi viết cho 1 chương trình tương đối lớn thì dùng đến 4, 5 Dics cho các danh mục, 2 Dic cho việc liệt kê lỗi (cụ thể là lỗi mặt hàng chưa tồn tại, khách hàng chưa tồn tại). Bắt buộc phải khai báo tường minh và đặt tên tường minh.
Vâng, ý em chỉ là lấy kết quả nối lại với nhau để như đề bài.
Mà bài này kết quả nên tách ra thành các cột khác nhau. Chứ kiểu chập lại thế này, mẫy bữa nữa rồi lại tách ra :D
 
Upvote 0
Vâng, ý em chỉ là lấy kết quả nối lại với nhau để như đề bài.
Mà bài này kết quả nên tách ra thành các cột khác nhau. Chứ kiểu chập lại thế này, mẫy bữa nữa rồi lại tách ra :D
Nếu tách ra các cột khác nhau thì chỉ cần pivot table thông thường, chưa cần đến power query :p :p
 
Upvote 0
Đấy, như gợi ý của sư phụ @ptm0412, tác giả @hoahuongduong1986 thử làm tường minh xem sao. Đây là cách học tốt nhất.
Vì không phải đơn giản để sử dụng đích sừn uyển chuyển như bác @HieuCD được.
 
Upvote 0
Upvote 0
Dạ, Dic quá mạnh nhưng với em hiện mới chỉ dừng ở tìm hiểu cấp độ mẫu giáo thôi ạ. Em sẽ học hỏi và tìm hiểu thêm ạ!
Mình mạn phép góp ý chút nha. Không nên gộp chung lại. Tách ra từng cột là tối ưu nhất. Gom lại sẽ gặp nhiều rắc rối
 
Upvote 0
Vậy bài này để tường mình phải xơi 2 cái đít xần rồi nối lại với nhau sư phụ nhỉ?
Chỉ cần 1 dic thôi em kèm theo mảng kết quả. Mảng kq có số dòng bằng số dòng mảng ban đầu. Key là tiêu chí cần group là partner iso, value là vị trí (số thứ tự dòng) key đó trong mảng kết quả. Đọc từng dòng mảng source, gặp key mới thì thêm vào cuối mảng kết quả, key cũ thì cộng vào vị trí của hàng value thôi.
 
Upvote 0
Chỉ cần 1 dic thôi em kèm theo mảng kết quả. Mảng kq có số dòng bằng số dòng mảng ban đầu. Key là tiêu chí cần group là partner iso, value là vị trí (số thứ tự dòng) key đó trong mảng kết quả. Đọc từng dòng mảng source, gặp key mới thì thêm vào cuối mảng kết quả, key cũ thì cộng vào vị trí của hàng value thôi.
Đó là code của bác @concogia đó @Cá ngừ F1. Hai Dic truy xuất gọn hơn 1 tẹo thay vì 1 cái If ElseIf 4 giá trị.
 
Upvote 0
Đó là code của bác @concogia đó @Cá ngừ F1. Hai Dic truy xuất gọn hơn 1 tẹo thay vì 1 cái If ElseIf 4 giá trị.
Vâng, tại em không tải file nên không rõ. Nói chung em hay làm thì bao nhiêu tiêu chí cần nhóm thì sẽ có ngần ấy dic hoặc phải nối lại thành 1 cột và dùng 1 dic. Value thì lưu kết quả ngay nếu có ít tiêu chí cần tính tổng; nhiều tiêu chí như trong bài này thì value chứa chỉ số của key còn tính toán trên mảng.
 
Upvote 0
Đó là code của bác @concogia đó @Cá ngừ F1. Hai Dic truy xuất gọn hơn 1 tẹo thay vì 1 cái If ElseIf 4 giá trị.
Bài này vui quá, muốn tìm chỉ số cột đó ( theo mình ) có 3 cách:
1) Nạp vào Dic vô tư, đếch sợ em nào vì lần lượt các em Ex, Im, Re_Ex, Re_Im đó là duy nhất, tạo ra bảng dò, dạng này hình như trên diễn đàn có một vài bài xử dụng
2) Dùng IF cũng tạo ra bảng dò ( nhưng không thấy nó thôi) chỉ số cột
3) Tạo một bảng vào Sheet, 4 dòng 2 cột, 2 dòng 4 cột ( tuỳ) dò tìm chỉ số cột
Túm lại, dùng kiểu nào mục đích cũng là tìm chỉ số Cột để Công & Đếm
Tới đây thì chia 2 nhánh
1) Tìm được chỉ số cột thì gán luôn vào mảng Kết Quả ==> phang xuống Sheet
2) Đếm đếm, công cộng xong để dành đó, chạy hết 1 vòng rồi chạy tiếp vòng 2 gán kết quả ==> phang xuống Sheet
Thấy vui viết chơi, miễn tranh luận, để đầu óc thảnh thơi.......chống dịch
Thân
 
Upvote 0
Thấy vui viết chơi, miễn tranh luận, để đầu óc thảnh thơi.......chống dịch
Bàn luận cho hết thì giờ ấy mà anh, dịch rảnh quá. Anh không viết thì bàn luận với ai? Có 2 anh em (với @Cá ngừ F1), bàn mãi cũng chán, em í chỉ có dạ thôi.
Bài đã được tự động gộp:

Vâng, tại em không tải file nên không rõ. Nói chung em hay làm thì bao nhiêu tiêu chí cần nhóm thì sẽ có ngần ấy dic hoặc phải nối lại thành 1 cột và dùng 1 dic. Value thì lưu kết quả ngay nếu có ít tiêu chí cần tính tổng; nhiều tiêu chí như trong bài này thì value chứa chỉ số của key còn tính toán trên mảng.
item chứa chỉ số của key đúng rồi, bài này 2 Dic (hoặc 1 Dic gộp như anh @HieuCD) thì 1 dic chỉ số dòng, 1 dic chỉ số cột.
 
Upvote 0
Bài này vui quá, muốn tìm chỉ số cột đó ( theo mình ) có 3 cách:
1) Nạp vào Dic vô tư, đếch sợ em nào vì lần lượt các em Ex, Im, Re_Ex, Re_Im đó là duy nhất, tạo ra bảng dò, dạng này hình như trên diễn đàn có một vài bài xử dụng
2) Dùng IF cũng tạo ra bảng dò ( nhưng không thấy nó thôi) chỉ số cột
3) Tạo một bảng vào Sheet, 4 dòng 2 cột, 2 dòng 4 cột ( tuỳ) dò tìm chỉ số cột
Túm lại, dùng kiểu nào mục đích cũng là tìm chỉ số Cột để Công & Đếm
Tới đây thì chia 2 nhánh
1) Tìm được chỉ số cột thì gán luôn vào mảng Kết Quả ==> phang xuống Sheet
2) Đếm đếm, công cộng xong để dành đó, chạy hết 1 vòng rồi chạy tiếp vòng 2 gán kết quả ==> phang xuống Sheet
Thấy vui viết chơi, miễn tranh luận, để đầu óc thảnh thơi.......chống dịch
Thân
Dạo này chả được PHANG í bác Cò, bí bách quá nghĩ cách PHANG xuống Sheet cho đỡ khó chịu ạ.
 
Upvote 0
Với tinh thần cần 2 Dic để tường minh của sư phụ @ptm0412
Cả ý kiến của anh @Quang_Hải là tách cột kết quả tránh những rắc rối không cần thiết sau này.
Tôi làm thử với kết quả là 5 cột (như hình). Kết quả các cột khác bạn tự thêm nhé. Vì tôi thấy dùng 2 Dic như này là rất tường minh rồi.
Thực tế thì việc nối chuỗi chỉ gọi là thêm chút gia vị.

Snag_215da0.png
Mã:
Sub GPE()
On Error Resume Next
Dim Data(), DicTradeFlow As Object, DicPartner As Object, i&, k&, j&, KQ(), ItmTradeFlow, ItmPartner, KQ1, KQ2, sRow
Data = Range(Sheets("Data").[D2], Sheets("Data").[J1000000].End(3))
sRow = UBound(Data)
ReDim KQ(1 To sRow, 1 To 5)
ReDim KQ1(1 To sRow, 1 To 2)
ReDim KQ2(1 To sRow, 1 To 3)
Set DicTradeFlow = CreateObject("Scripting.Dictionary")
Set DicPartner = CreateObject("Scripting.Dictionary")
For i = 1 To sRow
    If Mid(Data(i, 3), 1, 1) <> "A" Then
        ItmTradeFlow = Data(i, 1) & Data(i, 5)
        ItmPartner = Data(i, 5)
        If Not DicTradeFlow.Exists(ItmTradeFlow) Then
            k = k + 1
            DicTradeFlow(ItmTradeFlow) = k
            KQ1(k, 1) = 1
            KQ1(k, 2) = Data(i, 7)
        Else
            KQ1(DicTradeFlow.Item(ItmTradeFlow), 1) = KQ1(DicTradeFlow.Item(ItmTradeFlow), 1) + 1
            KQ1(DicTradeFlow.Item(ItmTradeFlow), 2) = KQ1(DicTradeFlow.Item(ItmTradeFlow), 2) + Data(i, 7)
        End If
        If Not DicPartner.Exists(ItmPartner) Then
            j = j + 1
            DicPartner(ItmPartner) = j
            KQ2(j, 1) = j
            KQ2(j, 2) = Data(i, 5)
            KQ2(j, 3) = Data(i, 7)
        Else
            KQ2(DicPartner.Item(ItmPartner), 3) = KQ2(DicPartner.Item(ItmPartner), 3) + Data(i, 7)
        End If
    End If
Next
For i = 1 To j
    KQ(i, 1) = KQ2(i, 1)
    KQ(i, 2) = KQ2(i, 2)
    KQ(i, 3) = KQ2(i, 3)
    KQ(i, 4) = KQ1(DicTradeFlow.Item("Export" & KQ(i, 2)), 1)
    KQ(i, 5) = KQ1(DicTradeFlow.Item("Export" & KQ(i, 2)), 2)
Next
With Sheet8 'Thay ten sheet can gan KQ vo day
    .[A3].Resize(j, 5) = KQ
    .[B2:E100000].Sort .[C2], 2, Header:=xlYes
End With
End Sub
Chúc cả nhà cuối tuần VUI VẺ !!!
 
Upvote 0
Tham gia 1 bài cho vui. Nhìn hơi quái chút.
Mã:
Sub Loc_DIC()
Dim du_lieu(), ket_qua(), Dic As Object, tmp As String
Dim sKey As String, i As Long, k As Long, n As Long
du_lieu = Sheet2.Range("D2", Sheet2.Range("D" & Rows.Count).End(3)).Resize(, 7).Value
ReDim ket_qua(1 To UBound(du_lieu), 1 To 13)
Set Dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(du_lieu)
    sKey = du_lieu(i, 5)
    If Not IsEmpty(sKey) Then
        tmp = UCase(du_lieu(i, 1))
        If Not Dic.Exists(sKey) Then
            k = k + 1
            Dic.Add sKey, k
            ket_qua(k, 1) = k
            ket_qua(k, 2) = du_lieu(i, 5)
            ket_qua(k, 3) = du_lieu(i, 7)
            'If Left(du_lieu(i, 3), 1) <> "A" Then
                If tmp = "EXPORT" Then
                    ket_qua(k, 6) = 1
                    ket_qua(k, 10) = du_lieu(i, 7)
                ElseIf tmp = "IMPORT" Then
                    ket_qua(k, 7) = 1
                    ket_qua(k, 11) = du_lieu(i, 7)
                ElseIf tmp = "RE-EXPORT" Then
                    ket_qua(k, 8) = 1
                    ket_qua(k, 12) = du_lieu(i, 7)
                ElseIf tmp = "RE-IMPORT" Then
                    ket_qua(k, 13) = du_lieu(i, 7)
                End If
            'End If
        Else
            n = Dic.Item(sKey)
            ket_qua(n, 3) = ket_qua(n, 3) + du_lieu(i, 7)
            'If Left(du_lieu(i, 3), 1) <> "A" Then
                If tmp = "EXPORT" Then
                    ket_qua(n, 6) = ket_qua(n, 6) + 1
                    ket_qua(n, 10) = ket_qua(n, 10) + du_lieu(i, 7)
                ElseIf tmp = "IMPORT" Then
                    ket_qua(n, 7) = ket_qua(n, 7) + 1
                    ket_qua(n, 11) = ket_qua(n, 11) + du_lieu(i, 7)
                ElseIf tmp = "RE-EXPORT" Then
                    ket_qua(n, 8) = ket_qua(n, 8) + 1
                    ket_qua(n, 12) = ket_qua(n, 12) + du_lieu(i, 7)
                ElseIf tmp = "RE-IMPORT" Then
                    ket_qua(n, 9) = ket_qua(n, 9) + 1
                    ket_qua(n, 13) = ket_qua(n, 13) + du_lieu(i, 7)
                End If
            'End If
        End If
    End If
Next i

For i = 1 To k
    ket_qua(i, 4) = "Export: " & ket_qua(i, 6) & "/Import: " & ket_qua(i, 7) & " /Re-Export: " & ket_qua(i, 8) & "/Re-Import: " & ket_qua(i, 9)
    ket_qua(i, 5) = "Export: " & ket_qua(i, 10) & "/Import: " & ket_qua(i, 11) & " /Re-Export: " & ket_qua(i, 12) & "/Re-Import: " & ket_qua(i, 13)
Next
Sheet1.Range("C2").Resize(k, 5).Value = ket_qua
End Sub
 
Upvote 0
Với tinh thần cần 2 Dic để tường minh của sư phụ @ptm0412
Cả ý kiến của anh @Quang_Hải là tách cột kết quả tránh những rắc rối không cần thiết sau này.
Tôi làm thử với kết quả là 5 cột (như hình). Kết quả các cột khác bạn tự thêm nhé. Vì tôi thấy dùng 2 Dic như này là rất tường minh rồi.
Thực tế thì việc nối chuỗi chỉ gọi là thêm chút gia vị.

View attachment 266290
Mã:
Sub GPE()
On Error Resume Next
Dim Data(), DicTradeFlow As Object, DicPartner As Object, i&, k&, j&, KQ(), ItmTradeFlow, ItmPartner, KQ1, KQ2, sRow
Data = Range(Sheets("Data").[D2], Sheets("Data").[J1000000].End(3))
sRow = UBound(Data)
ReDim KQ(1 To sRow, 1 To 5)
ReDim KQ1(1 To sRow, 1 To 2)
ReDim KQ2(1 To sRow, 1 To 3)
Set DicTradeFlow = CreateObject("Scripting.Dictionary")
Set DicPartner = CreateObject("Scripting.Dictionary")
For i = 1 To sRow
    If Mid(Data(i, 3), 1, 1) <> "A" Then
        ItmTradeFlow = Data(i, 1) & Data(i, 5)
        ItmPartner = Data(i, 5)
        If Not DicTradeFlow.Exists(ItmTradeFlow) Then
            k = k + 1
            DicTradeFlow(ItmTradeFlow) = k
            KQ1(k, 1) = 1
            KQ1(k, 2) = Data(i, 7)
        Else
            KQ1(DicTradeFlow.Item(ItmTradeFlow), 1) = KQ1(DicTradeFlow.Item(ItmTradeFlow), 1) + 1
            KQ1(DicTradeFlow.Item(ItmTradeFlow), 2) = KQ1(DicTradeFlow.Item(ItmTradeFlow), 2) + Data(i, 7)
        End If
        If Not DicPartner.Exists(ItmPartner) Then
            j = j + 1
            DicPartner(ItmPartner) = j
            KQ2(j, 1) = j
            KQ2(j, 2) = Data(i, 5)
            KQ2(j, 3) = Data(i, 7)
        Else
            KQ2(DicPartner.Item(ItmPartner), 3) = KQ2(DicPartner.Item(ItmPartner), 3) + Data(i, 7)
        End If
    End If
Next
For i = 1 To j
    KQ(i, 1) = KQ2(i, 1)
    KQ(i, 2) = KQ2(i, 2)
    KQ(i, 3) = KQ2(i, 3)
    KQ(i, 4) = KQ1(DicTradeFlow.Item("Export" & KQ(i, 2)), 1)
    KQ(i, 5) = KQ1(DicTradeFlow.Item("Export" & KQ(i, 2)), 2)
Next
With Sheet8 'Thay ten sheet can gan KQ vo day
    .[A3].Resize(j, 5) = KQ
    .[B2:E100000].Sort .[C2], 2, Header:=xlYes
End With
End Sub
Chúc cả nhà cuối tuần VUI VẺ !!!
Không ngờ bài của em được nhiều anh quan tâm và chỉ bảo đến như này ạ ! Cảm ơn các anh nhiều ạ !
Bài đã được tự động gộp:

Tham gia 1 bài cho vui. Nhìn hơi quái chút.
Mã:
Sub Loc_DIC()
Dim du_lieu(), ket_qua(), Dic As Object, tmp As String
Dim sKey As String, i As Long, k As Long, n As Long
du_lieu = Sheet2.Range("D2", Sheet2.Range("D" & Rows.Count).End(3)).Resize(, 7).Value
ReDim ket_qua(1 To UBound(du_lieu), 1 To 13)
Set Dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(du_lieu)
    sKey = du_lieu(i, 5)
    If Not IsEmpty(sKey) Then
        tmp = UCase(du_lieu(i, 1))
        If Not Dic.Exists(sKey) Then
            k = k + 1
            Dic.Add sKey, k
            ket_qua(k, 1) = k
            ket_qua(k, 2) = du_lieu(i, 5)
            ket_qua(k, 3) = du_lieu(i, 7)
            'If Left(du_lieu(i, 3), 1) <> "A" Then
                If tmp = "EXPORT" Then
                    ket_qua(k, 6) = 1
                    ket_qua(k, 10) = du_lieu(i, 7)
                ElseIf tmp = "IMPORT" Then
                    ket_qua(k, 7) = 1
                    ket_qua(k, 11) = du_lieu(i, 7)
                ElseIf tmp = "RE-EXPORT" Then
                    ket_qua(k, 8) = 1
                    ket_qua(k, 12) = du_lieu(i, 7)
                ElseIf tmp = "RE-IMPORT" Then
                    ket_qua(k, 13) = du_lieu(i, 7)
                End If
            'End If
        Else
            n = Dic.Item(sKey)
            ket_qua(n, 3) = ket_qua(n, 3) + du_lieu(i, 7)
            'If Left(du_lieu(i, 3), 1) <> "A" Then
                If tmp = "EXPORT" Then
                    ket_qua(n, 6) = ket_qua(n, 6) + 1
                    ket_qua(n, 10) = ket_qua(n, 10) + du_lieu(i, 7)
                ElseIf tmp = "IMPORT" Then
                    ket_qua(n, 7) = ket_qua(n, 7) + 1
                    ket_qua(n, 11) = ket_qua(n, 11) + du_lieu(i, 7)
                ElseIf tmp = "RE-EXPORT" Then
                    ket_qua(n, 8) = ket_qua(n, 8) + 1
                    ket_qua(n, 12) = ket_qua(n, 12) + du_lieu(i, 7)
                ElseIf tmp = "RE-IMPORT" Then
                    ket_qua(n, 9) = ket_qua(n, 9) + 1
                    ket_qua(n, 13) = ket_qua(n, 13) + du_lieu(i, 7)
                End If
            'End If
        End If
    End If
Next i

For i = 1 To k
    ket_qua(i, 4) = "Export: " & ket_qua(i, 6) & "/Import: " & ket_qua(i, 7) & " /Re-Export: " & ket_qua(i, 8) & "/Re-Import: " & ket_qua(i, 9)
    ket_qua(i, 5) = "Export: " & ket_qua(i, 10) & "/Import: " & ket_qua(i, 11) & " /Re-Export: " & ket_qua(i, 12) & "/Re-Import: " & ket_qua(i, 13)
Next
Sheet1.Range("C2").Resize(k, 5).Value = ket_qua
End Sub
Cảm ơn anh nhiều ạ !
 
Upvote 0
Vậy bài này để tường mình phải xơi 2 cái đít xần rồi nối lại với nhau sư phụ nhỉ?
Đít sần có thể coi như là từ điển.
Bạn có một quyển từ điển Pháp Việt, và một quyển từ điển Hán Việt. Bạn muốn đóng chúng lại thành 1 quyển?
Đương nhiên là vẫn làm được nhưng nó sẽ khó xài như thế nào.

Trên nhyên tắc, cứ tra điều khác nhau chả lý do gì để không lập một cái đít sần khác.
 
Lần chỉnh sửa cuối:
Upvote 0
Đít sần có thể coi như là từ điển.
Bạn có 2 quyển từ điển Pháp Việt, và một quyển từ điển Hán Việt. Bạn muốn đóng chúng lại thành 1 quyển?
Đương nhiên là vẫn làm được nhưng nó sẽ khó xài như thế nào.

Trên nhyên tắc, cứ tra điều khác nhau chả lý do gì để không lập một cái đít sần khác.
Cần tra từ điển Pháp Việt và vài từ Hán Việt biết trước, sắm 2 cuốn từ điển riêng biệt quá lãng phí, tốn thêm ít nhất 2 trang bìa, chỉ cần viết tay thêm vài từ Hán Việt vào trang đầu là vừa đủ xài, người khác cầm nhầm từ điển lật trang đầu là biết ngay của người nào :)
 
Upvote 0
Web KT
Back
Top Bottom