Import module mới thay cho module cũ với vbaproject có pass (1 người xem)

Liên hệ QC

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

phuoclocvl

Thành viên thường trực
Tham gia
28/3/12
Bài viết
220
Được thích
32
Chào các Anh Chị,
Xin giúp em vấn đề này, mình có code nào import một module mới trùng tên với module cũ và thay thế module cũ (replace) nhưng Vba project có cài password.
Xin cảm ơn ạ,
 
Không thể trừ khi bạn mở khoá và xoá Module cũ trước
 
Upvote 0
bạn thử thì biết được hay không mình chỉ nêu nguyên lí làm việc là như vậy !
 
Upvote 0
Xin giúp em vấn đề này, mình có code nào import một module mới trùng tên với module cũ và thay thế module cũ (replace) nhưng Vba project có cài password.

Đọc yêu cầu có vẻ giống như bạn đang muốn cập nhật ứng dụng Excel mà bạn đã phân phối phải không? Cài password giao file cho người dùng cuối.
 
Upvote 0
Đổi tên module cũ trước khi import module mới.
 
Upvote 0
Dạ, gần như vâỵ ạ. Xin chỉ giáo. Cảm ơn anh,

:) Thực ra là tôi chưa trải nghiệm cái vụ phân phối ứng dụng bằng Excel và tung ra các bản nâng cấp của nó sau đó.
Vì ứng dụng Excel không có tách được dữ liệu ra riêng và ứng dụng giao diện người dùng riêng nên việc tung các bản cập nhật sẽ gặp khó khăn trong việc chuyển dữ liệu đang sử dụng sang file mới.
Theo tôi nếu bạn thiết kế CSDL kỹ lưỡng, chuẩn hoá, dữ liệu lưu trong các sheet riêng thì có thể dùng cách copy (viết code để đồng bộ) các dữ liệu gốc này sang file mới và chạy thôi. Một chú ý quan trọng là bản nâng cấp không đụng gì tới việc thay đổi cấu trúc, thiết kế bảng dữ liệu (không thêm cột, thay đổi thứ tự cột v.v..).
Một số ý kiến cá nhân là vậy, để các bạn chuyên về ứng dụng trên nền Excel góp ý thêm nhé.
 
Upvote 0
:) Thực ra là tôi chưa trải nghiệm cái vụ phân phối ứng dụng bằng Excel và tung ra các bản nâng cấp của nó sau đó.
Vì ứng dụng Excel không có tách được dữ liệu ra riêng và ứng dụng giao diện người dùng riêng nên việc tung các bản cập nhật sẽ gặp khó khăn trong việc chuyển dữ liệu đang sử dụng sang file mới.
Theo tôi nếu bạn thiết kế CSDL kỹ lưỡng, chuẩn hoá, dữ liệu lưu trong các sheet riêng thì có thể dùng cách copy (viết code để đồng bộ) các dữ liệu gốc này sang file mới và chạy thôi. Một chú ý quan trọng là bản nâng cấp không đụng gì tới việc thay đổi cấu trúc, thiết kế bảng dữ liệu (không thêm cột, thay đổi thứ tự cột v.v..).
Một số ý kiến cá nhân là vậy, để các bạn chuyên về ứng dụng trên nền Excel góp ý thêm nhé.
Mình cũng có thiết kế 1 file tự cập nhật khi có phiên bản mới
Do sử dụng bảo mật trên cty nên có lẽ bạn phải chỉnh sửa một chút. ah thôi nói nôm na cho bạn như vậy
Cách mình làm là: Tạo ra 3 file như sau ( File macro1(ng ta sẽ sử dụng), file macro2 (là file gốc của bạn), file Data)
Liên kết file macro của bạn với file data.
Chương trình sẽ chạy như sau:
Khi mởi file macro1 sẽ mở thêm file data.
sau đó kiểm tra phiên bản. nếu ok thì tắt file data và mở file macro1. ngược lại thì thiện thông báo yêu cầu update.
khi nhấn update thì file macro1 sẽ mở file macro2 và lấy toàn bộ dữ liệu từ macro1 chuyển qua macro2.
cuối cùng là save as macro2 với tên của macro1 + thêm số phiên bản tiếp theo là đóng và xóa macro1.
xong!!!
 
Upvote 0
Cách mình làm là: Tạo ra 3 file như sau ( File macro1(ng ta sẽ sử dụng), file macro2 (là file gốc của bạn), file Data)
Liên kết file macro của bạn với file data.
Chương trình sẽ chạy như sau:
Khi mởi file macro1 sẽ mở thêm file data.
sau đó kiểm tra phiên bản. nếu ok thì tắt file data và mở file macro1. ngược lại thì thiện thông báo yêu cầu update.
khi nhấn update thì file macro1 sẽ mở file macro2 và lấy toàn bộ dữ liệu từ macro1 chuyển qua macro2.
cuối cùng là save as macro2 với tên của macro1 + thêm số phiên bản tiếp theo là đóng và xóa macro1.
xong!!!

Vậy file Data như là file thông báo có phiên bản mới cần cập nhật và file Data này bạn lưu trên hệ thống (Shared Folder ) để file Macro 1 khởi động là truy cập vô Data để kiểm tra thông tin? Việc lưu hay copy 2 file: Data và macro2 như thế nào tôi chưa hiểu lắm, đại khái là cái qui trình nâng cấp đó?
 
Upvote 0
Mình cũng có thiết kế 1 file tự cập nhật khi có phiên bản mới
Do sử dụng bảo mật trên cty nên có lẽ bạn phải chỉnh sửa một chút. ah thôi nói nôm na cho bạn như vậy
Cách mình làm là: Tạo ra 3 file như sau ( File macro1(ng ta sẽ sử dụng), file macro2 (là file gốc của bạn), file Data)
Liên kết file macro của bạn với file data.
Chương trình sẽ chạy như sau:
Khi mởi file macro1 sẽ mở thêm file data.
sau đó kiểm tra phiên bản. nếu ok thì tắt file data và mở file macro1. ngược lại thì thiện thông báo yêu cầu update.
khi nhấn update thì file macro1 sẽ mở file macro2 và lấy toàn bộ dữ liệu từ macro1 chuyển qua macro2.
cuối cùng là save as macro2 với tên của macro1 + thêm số phiên bản tiếp theo là đóng và xóa macro1.
xong!!!
Thật ra giờ mình cũng không hình dung ra cách làm như thế nào nữa
 
Upvote 0
Tôi cũng từng viết code để cập nhật Add-Ins. Cách là thế này, 1 File Add-Ins có tên A (File này là các tiện ích để sử dụng), file thứ 2 là B. Từ file A cho chạy đoạn code lấy dữ liệu từ Web về (Thật ra chỉ là file txt được lưu trên Google Driver, đọc nó để biết có phiên bản mới hay chưa) để kiểm tra phiên bản. Nếu đã có phiên bản mới thì lúc đó sẽ gọi file B, khi file B được mở nó sẽ chạy đoạn code gỡ bỏ Add-Ins A (Mục đích là tắt file A đê cập nhật không bị lỗi), tải File A mới (File này cũng lưu trên Google Driver) về và lưu vào thư mục tạm của máy tính. nếu tải về thành công xóa File A cũ đi và Copy file A mới từ thư mục tạm vào vị trí của file A cũ, đăng ký lại Add-Ins A với Excel thông báo thành công và sau đó đóng file B. Nếu tải về không thành công thì đăng ký Add-Ins A lại (Đây là file A cũ) như ban đâu, thông báo cập nhật thất bại và đóng file B lại.
Cách này tôi đã làm thành công, nhưng khi áp dụng vào thực tế thì bị lỗi thế này vẫn chưa khắc phục được. nếu File Add-Ins A nằm ở thư mục nào đó không phải ổ đĩa hệ thống thì chạy ngon lành, nhưng cái Add-Ins của tôi cài vào C:\Program Files\... thì lúc đó nó không cho phép copy file A từ thư mục tạm vào đường dẫn này. Nói túm lại hiện tại vẫn chưa biết cách khắc phục, sẳn tiện thành viên nào có cách hay chỉ giáo với.
 
Upvote 0
@giaiphap Em đoán là thư mục tại C\Program FIles\ là thư mục đòi hỏi Permission trước khi truy cập vào folder trong đó.
 
Upvote 0
Vậy file Data như là file thông báo có phiên bản mới cần cập nhật và file Data này bạn lưu trên hệ thống (Shared Folder ) để file Macro 1 khởi động là truy cập vô Data để kiểm tra thông tin? Việc lưu hay copy 2 file: Data và macro2 như thế nào tôi chưa hiểu lắm, đại khái là cái qui trình nâng cấp đó?
Trong hệ thống này mình đã cắt khá nhiều code. không phải bảo mật nên chia sẻ về cách update của mình nhé.
Yêu cầu sử dụng office 2010 trở lên.
Đầu tiên các bạn tải thư mục này "Data Update Revision" về sau đó giải nén ra.
có 3 file như mình nói:
1. "File ng khac su dung" File này là file bạn sẽ nhân ra cho ng ta sử dụng (đang ở phiên bản 2.0.17) file này các bạn có thể đổi tên.
2. "Member_Data" File này chứa giá trị 2.0.18 => là file quản lý phiên bản, data người dùng. không được đổi tên
3. "TH-BOM-MAU" Là file gốc bạn sẽ nâng cấp. không được đổi tên

giải nén xong bạn mở file "File ng khac su dung" lên là code sẽ chạy. mình mở khóa sẵn rồi nha.
còn đối với file "Member_Data" thì không có code đâu nên các bạn không cần xem gì đâu.
thắc mắc gì cứ hú mình nhé. nếu có time mình sẽ phản hồi.

Ah thêm nữa trong hệ thống này cũng cố một số code mình chưa xóa. các bạn có thể lấy tham khỏa nha. khá nhiều code hay đấy. :)
 

File đính kèm

Upvote 0
nếu File Add-Ins A nằm ở thư mục nào đó không phải ổ đĩa hệ thống thì chạy ngon lành, nhưng cái Add-Ins của tôi cài vào C:\Program Files\... thì lúc đó nó không cho phép copy file A từ thư mục tạm vào đường dẫn này. Nói túm lại hiện tại vẫn chưa biết cách khắc phục, sẳn tiện thành viên nào có cách hay chỉ giáo với.

Có cách này: bạn hiện thông báo "nếu muốn cập nhật thành công vui lòng bật UAC về mức MIN rồi bấm cập nhật". :)
Hoặc chạy bằng CMD với quyền Administrator: ShellExecute
 
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
làm vậy cho nó đơn giản nè thử trong ổ C ý chỗ nào mà nó cho tạo File mà ko có thông báo Continue ý thì cho nó vào đó mà lách cái UAC đi cho gọn ... xong copy Files vào đó xong Add nó vào là xong
hay lách trên Ổ C tạo 1 Folder xong copy files vào đó xong muốn làm chi tiếp thì làm
 
Upvote 0
giải nén xong bạn mở file "File ng khac su dung" lên là code sẽ chạy. mình mở khóa sẵn rồi nha.
còn đối với file "Member_Data" thì không có code đâu nên các bạn không cần xem gì đâu.
thắc mắc gì cứ hú mình nhé. nếu có time mình sẽ phản hồi.

Ah thêm nữa trong hệ thống này cũng cố một số code mình chưa xóa. các bạn có thể lấy tham khỏa nha. khá nhiều code hay đấy. :)

Mở 2 file: nguoi khac su dung và BOM mau không được bạn à. Nó pop up màn hình Toshiba khi chọn Close là thoát luôn.

Screen Shot 2020-08-06 at 2.20.59 PM.png
 
Upvote 0
Dạ, em upload file lên các anh em hỗ trợ giúp.
Trong file có những module. em muốn gửi file này cho mọi người dùng và sẽ đặt password cho VBAproject, khi nào có thay đổi thì em sẽ cho update 1 trong những module này. có cách nào update new module thay thế module cũ mà với project đã cài password không.
mục đích là vậy.
xin cảm ơn ạ.
 

File đính kèm

Upvote 0

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Dạ, em upload file lên các anh em hỗ trợ giúp.
Trong file có những module. em muốn gửi file này cho mọi người dùng và sẽ đặt password cho VBAproject, khi nào có thay đổi thì em sẽ cho update 1 trong những module này. có cách nào update new module thay thế module cũ mà với project đã cài password không.
mục đích là vậy.
xin cảm ơn ạ.
Tôi không tải file bạn, nhưng bạn xem file tôi viết có thể áp dụng cho file của mình được hay không? Trong file có tham khảo code ở link sau:
 

File đính kèm

Upvote 0
Có cách này: bạn hiện thông báo "nếu muốn cập nhật thành công vui lòng bật UAC về mức MIN rồi bấm cập nhật". :)
Hoặc chạy bằng CMD với quyền Administrator: ShellExecute
Làm vậy cũng được, nhưng phần lớn người dùng sẽ không biết đưa UAC về mức thấp nhất (Có thể viết hướng dẫn nhưng cách này sẽ không được chuyên nghiệp lắm). Vì vậy viết được code làm luôn điều này nửa mới ngon, tức là trước khi Update mình đưa nó về mức thất nhất, sau đó Update, khi update xong trả nó về hiện trạng ban đầu (dùng luôn code VBA) nhưng hiện tại mình tịch cái vụ này. Nên cách giải quyết hiện tại là cho phép người dùng chọn đường dẫn lưu file setup về máy, sau đó cài lại file setup, thấy hơi phiền.
 
Upvote 0
Chương trình sẽ chạy như sau:
Khi mởi file macro1 sẽ mở thêm file data.
sau đó kiểm tra phiên bản. nếu ok thì tắt file data và mở file macro1. ngược lại thì thiện thông báo yêu cầu update.
khi nhấn update thì file macro1 sẽ mở file macro2 và lấy toàn bộ dữ liệu từ macro1 chuyển qua macro2.
cuối cùng là save as macro2 với tên của macro1 + thêm số phiên bản tiếp theo là đóng và xóa macro1.
xong!!!

Tôi xem file của bạn rồi. Code hoành tránh nhỉ.
Tôi hỏi thêm chút cho rõ về qui trình cập nhật nhé.
- File macro1 là file người ta đang sử dụng trên máy người ta. Có thể nhiều người dùng ở nhiều máy khác nhau.
- Khi muốn cập nhật thì bạn phải qua một bước là chủ động yêu cầu người dùng tải 2 file: Member_data.xlsm và TH-BOM-Mau.xlsm về lưu vào cùng đường dẫn file macro1 mà họ đang sử dụng thì mới Update được đúng không? Vì tôi thấy sự kiện On Open bạn dùng ThisWorkbook.Path + ...
Cảm ơn bạn đã chia sẻ một cách cập nhật ứng dụng Excel hay.
 
Upvote 0
Tôi xem file của bạn rồi. Code hoành tránh nhỉ.
Tôi hỏi thêm chút cho rõ về qui trình cập nhật nhé.
- File macro1 là file người ta đang sử dụng trên máy người ta. Có thể nhiều người dùng ở nhiều máy khác nhau.
- Khi muốn cập nhật thì bạn phải qua một bước là chủ động yêu cầu người dùng tải 2 file: Member_data.xlsm và TH-BOM-Mau.xlsm về lưu vào cùng đường dẫn file macro1 mà họ đang sử dụng thì mới Update được đúng không? Vì tôi thấy sự kiện On Open bạn dùng ThisWorkbook.Path + ...
Cảm ơn bạn đã chia sẻ một cách cập nhật ứng dụng Excel hay.
Không bạn ơi.
File mình đưa lên là chỉnh sửa lại đường dẫn rồi. vì không chỉnh sửa thì các bạn không chạy chương trình được.
2 file ( Data với File gốc) bạn sẽ để 1 nơi thôi nhưng phải cố định. Còn file người dùng thì bạn có thể đưa đi đâu cũng được. chương trình không quan tâm.
Nó chỉ quan tâm file gốc có tồn tại ở thư mục chỉ định hay không và file data cũng vậy.
Vì chỉ muốn các bạn hiểu code update chạy thế nào nên mới xóa đi khá khá. chứ thực chất các điều kiện của file gốc nó còn phức tạp hơn nữa.
Bạn muốn chi tiết thì zalo vào số này nhé. có time mình sẽ giúp bạn. 0354 366 282
 
Upvote 0
Xin lỗi nha!.
Quên xóa điều kiện check member.
Gửi lại bạn nhé.
Hay quá
Bài đã được tự động gộp:

Tôi không tải file bạn, nhưng bạn xem file tôi viết có thể áp dụng cho file của mình được hay không? Trong file có tham khảo code ở link sau:
Hay lắm, nhưng có cách nào nó tự click ok luôn hong hén.
 
Upvote 0
:) Thực ra là tôi chưa trải nghiệm cái vụ phân phối ứng dụng bằng Excel và tung ra các bản nâng cấp của nó sau đó.
Vì ứng dụng Excel không có tách được dữ liệu ra riêng và ứng dụng giao diện người dùng riêng nên việc tung các bản cập nhật sẽ gặp khó khăn trong việc chuyển dữ liệu đang sử dụng sang file mới.
Theo tôi nếu bạn thiết kế CSDL kỹ lưỡng, chuẩn hoá, dữ liệu lưu trong các sheet riêng thì có thể dùng cách copy (viết code để đồng bộ) các dữ liệu gốc này sang file mới và chạy thôi. Một chú ý quan trọng là bản nâng cấp không đụng gì tới việc thay đổi cấu trúc, thiết kế bảng dữ liệu (không thêm cột, thay đổi thứ tự cột v.v..).
Một số ý kiến cá nhân là vậy, để các bạn chuyên về ứng dụng trên nền Excel góp ý thêm nhé.
Cách này ổn. Tôi đã dùng kiểu này. Khi thay đổi code, tôi chỉ cần gửi cho người dùng 1 file trống. Người dùng chạy sub chuyển hết dữ liệu từ file cũ sang. Các name (nếu có), format đều code để mang sang hết.
 
Upvote 0
Hay quá
Bài đã được tự động gộp:


Hay lắm, nhưng có cách nào nó tự click ok luôn hong hén.
Mình tạo ra 3 file để điều khiển bởi vì mình phải quản lý thêm nember và phân quyền cho từng người.
Trên thực tế các bạn chỉ cần sử dụng 2 file là có thể auto update.
1 file ng dùng sử dụng như bình thường (coppy ra bao nhiêu file không ảnh hưởng)
1 file gốc bạn để ở ổ Public.

Bản chất 2 file này cũng chỉ là 1 file coppy ra và điểm khác biệt là (khác tên file) và (khác phiên bản code) thôi.
Nếu bạn nghĩ: "Làm sao để update modul nhỉ" thì tại sao mình không nghĩ đơn giản hơn là: "Làm cách nào để update dữ liệu cũ sang file mới"
Cách nào dễ hơn nhỉ :)
 
Upvote 0
Upvote 0
Anh ơi,
nó update nhiều module 1 lần không được hả? nó lại xuất hiện hộp nhập pass phải nhấn ok khi import trên 1 file
Nếu bạn muốn thay nhiều Module thì bạn phải cho nó vào vòng lặp chứ. Ví dụ
Mã:
        For i = 1 To UBound(Arr)
            Set Md = .VBProject.VBComponents.Import(Arr(i))
            Md.Name = Arr_New(i)
        Next i
Trong đó Arr là danh sách đường dẫn các Module, còn Arr_New là danh sách các module.
À quên bạn phải sửa code của vòng lặp phía trên và sửa luôn điều kiện để remove Module nửa, và khi thỏa mãn điều kiện thì không được Exit For mà phải duyệt tiếp tục đến hết vòng lặp.
Mã:
               If UCase(mdlName) = Module_Name Then
                    .VBProject.VBComponents.Remove .VBProject.VBComponents(mdlName)
                    Exit For
                End If
 
Upvote 0
Nếu bạn muốn thay nhiều Module thì bạn phải cho nó vào vòng lặp chứ. Ví dụ
Mã:
        For i = 1 To UBound(Arr)
            Set Md = .VBProject.VBComponents.Import(Arr(i))
            Md.Name = Arr_New(i)
        Next i
Trong đó Arr là danh sách đường dẫn các Module, còn Arr_New là danh sách các module.
À quên bạn phải sửa code của vòng lặp phía trên và sửa luôn điều kiện để remove Module nửa, và khi thỏa mãn điều kiện thì không được Exit For mà phải duyệt tiếp tục đến hết vòng lặp.
Mã:
               If UCase(mdlName) = Module_Name Then
                    .VBProject.VBComponents.Remove .VBProject.VBComponents(mdlName)
                    Exit For
                End If
 
Lần chỉnh sửa cuối:
Upvote 0
Không biết làm sao luôn hic
PHP:
Private Sub InsertModule()
Dim Wb As Workbook, mdlName As String, Md As Object
Dim J As Integer, I As Integer
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    'Neu lay du lieu tu Sheet thi cho chay dong code duoi day
    Call GetData    'Dong code này se khong can chay neu khai bao hang
    Set Wb = ThisWorkbook
    Call UnlockProject(Wb.VBProject, Pass)  'Test_UnlockProject(Pass)
    With Wb
        For J = .VBProject.VBComponents.Count To 1 Step -1
            If .VBProject.VBComponents(J).Type = 1 Or .VBProject.VBComponents(J).Type = 3 Then '.Type = 0
                    mdlName = .VBProject.VBComponents(J).name '.CodeModule.name
                If UCase(mdlName) = UCase(Module_Name) Then
                    .VBProject.VBComponents.Remove .VBProject.VBComponents(mdlName)
                    Exit For
                End If
            End If
        Next J
'----------------------------------------------------------------
        Set Md = .VBProject.VBComponents.Import(Path_Module_Name)
        Md.name = Module_Name
        .Save
        '.Close True
    End With
    Set Md = Nothing
    Set Wb = Nothing
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
End Sub
Private Sub GetData()
Dim mArr, I&, J&, eR&
eR = Application.WorksheetFunction.CountA(ThisWorkbook.Sheets("Update").Range("B:B"))
    mArr = ThisWorkbook.Sheets("Update").Range("A1:E" & eR).Value
    ReDim Arr(1 To UBound(mArr, 1))
    For I = LBound(mArr, 1) To UBound(mArr, 1)
        For J = LBound(mArr, 2) To UBound(mArr, 2)
            Arr(I) = mArr(I, 1)
        Next J
    Next I
    'Path_Module_Name = ThisWorkbook.Path & "\Release\" & Module_Name(I)
   
End Sub
Up cái file bạn đang làm mà chưa được kèm theo các Module bạn cần thay thế lên đây.
 
Upvote 0
Up cái file bạn đang làm mà chưa được kèm theo các Module bạn cần thay thế lên đây.

được rồi anh. hơi lủn củn nhưng chạy đc. Anh xem có hiệu chỉnh chổ nào được không?

PHP:
Private Sub InsertModule()
Dim Wb As Workbook, mdlName As String, Md As Object
Dim sh As Worksheet, nameArr, pathArr
Dim J As Integer, i As Integer, eR As Integer, K As Integer
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    'Neu lay du lieu tu Sheet thi cho chay dong code duoi day
    'Call GetData    'Dong code này se khong can chay neu khai bao hang
    Set Wb = ThisWorkbook
    Set sh = Wb.Sheets("Update")
    Call UnlockProject(Wb.VBProject, Pass)  'Test_UnlockProject(Pass)
    eR = sh.Range("A100").End(xlUp).Row
    With Wb
        For J = .VBProject.VBComponents.Count To 1 Step -1
            If .VBProject.VBComponents(J).Type = 1 Or .VBProject.VBComponents(J).Type = 3 Then '.Type = 0
                    mdlName = .VBProject.VBComponents(J).name '.CodeModule.name
            For K = 1 To eR
                ReDim Module_Name(K)
                Module_Name(K) = sh.Range("A" & K).Value
                    If UCase(mdlName) = UCase(Module_Name(K)) Then
                        .VBProject.VBComponents.Remove .VBProject.VBComponents(mdlName)
                        'Exit For
                    End If
            Next K
            End If
        Next J
'----------------------------------------------------------------
        For i = 1 To eR
            ReDim pathArr(i)
            ReDim Module_Name(i)
            Module_Name(i) = sh.Range("A" & i).Value
            pathArr(i) = sh.Range("C" & i).Value
            Set Md = .VBProject.VBComponents.Import(pathArr(i))
            Md.name = Module_Name(i)
        Next i
        .Save
        '.Close True
    End With
    Set Md = Nothing
    Set Wb = Nothing
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0

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

Back
Top Bottom