[Xin giúp đỡ] Check user và pass, sau đó tìm ra level dùng VBA

Liên hệ QC
Chào bác, cái lv_cbb của em khi không điều chỉnh gì thì nó hiện dải ô rất rộng trong khi mình có mỗi số 1-2-3-4 rất ngắn, em muốn thu nó lại thì điều chỉnh ở ListWith. Nhưng khi điều chỉnh (chỉnh ListWith thành 20pt) thì bị lỗi lv_cbb thằng này, nó cứ hiện lên cái như trong đóng khung rất khó chịu, có các nào để bỏ đi không ạ.
Em cảm ơn!

Chỉnh Column Width nhé.Nếu combobox của bạn hiển thị 3 cột thì thiết lập độ rộng từng cột cách nhau dấu ";". ListWidth là tổng độ rộng của tất cả các cột hiển thị.
Ví dụ:
Column Width: 20pt;30pt;10pt
ListWidth: 60 pt
 
Chỉnh Column Width nhé.Nếu combobox của bạn hiển thị 3 cột thì thiết lập độ rộng từng cột cách nhau dấu ";". ListWidth là tổng độ rộng của tất cả các cột hiển thị.
Ví dụ:
Column Width: 20pt;30pt;10pt
ListWidth: 60 pt
OK bác chuẩn luôn ạ, chỉnh thêm cái Column Width = 20pt nữa là đẹp long lanh rồi ạ
 
Chỉnh Column Width nhé.Nếu combobox của bạn hiển thị 3 cột thì thiết lập độ rộng từng cột cách nhau dấu ";". ListWidth là tổng độ rộng của tất cả các cột hiển thị.
Ví dụ:
Column Width: 20pt;30pt;10pt
ListWidth: 60 pt
Chào bác, hnay em lại có lỗi phát sinh nữa ạ.
Khi vào user form "login" click "Admin", sau đó đăng nhập user và pass nào đó hợp lệ.
Khi vào được ấn Cancel để quay về lại user form "login" sau đó lại click "Admin" thì báo lỗi VBA: error 400 form already displayed can't show modally
Em buộc phải thêm 1 dòng code vào file "login" nhưng nói thật nó bị load 2 lần và không đẹp.
Trong khi các dòng code khác em đều để lệnh Unload admin_login thay cho Hide rồi, mong bác tư vấn hộ em với
 

File đính kèm

  • 4.jpg
    4.jpg
    370 KB · Đọc: 13
Chào bác, hnay em lại có lỗi phát sinh nữa ạ.
Khi vào user form "login" click "Admin", sau đó đăng nhập user và pass nào đó hợp lệ.
Khi vào được ấn Cancel để quay về lại user form "login" sau đó lại click "Admin" thì báo lỗi VBA: error 400 form already displayed can't show modally
Em buộc phải thêm 1 dòng code vào file "login" nhưng nói thật nó bị load 2 lần và không đẹp.
Trong khi các dòng code khác em đều để lệnh Unload admin_login thay cho Hide rồi, mong bác tư vấn hộ em với

Tôi thấy file cũ bạn chạy bình thường, không lỗi.
Mà ý đồ bạn muốn thiết kế như thế nào mà lại có thêm nút Admin trên form Login? Hiếm thấy... :)

Mã:
'Code cho nút Admin tren form Login'
Private Sub admin_cmb_Click()
    Me.Hide
    admin_login.Show
End Sub

'------------------------------------
'Code cho nút Cancel trên form admiin_login'
Private Sub CommandButton2_Click()
Me.Hide
Login.Show
End Sub
 
Tôi thấy file cũ bạn chạy bình thường, không lỗi.
Mà ý đồ bạn muốn thiết kế như thế nào mà lại có thêm nút Admin trên form Login? Hiếm thấy... :)

Mã:
'Code cho nút Admin tren form Login'
Private Sub admin_cmb_Click()
    Me.Hide
    admin_login.Show
End Sub

'------------------------------------
'Code cho nút Cancel trên form admiin_login'
Private Sub CommandButton2_Click()
Me.Hide
Login.Show
End Sub
Chào bác ạ, em muốn lấy cái list vào combo box từ cột M, từ M5 đến M*, M* là vì khi thêm mới dữ liệu ở cột M thì số dòng có dữ liệu sẽ thay đổi.
Em muốn khi có dữ liệu mới nó sẽ load vào combo box dựa vào tìm dòng cuối.
Nhưng khi viết đoạn load từ cột M vào combo box thì bị lỗi.
Bác xem code sai ở đâu hộ e với ạ + viết sao cho đúng ạ.
Mã:
Private sub userform_initialize()
Dim dong_cuoi as long
dong_cuoi = sheet2.cells(rows.count, “m”).end(xlup).row+1
dvql_cbb.list = sheet2.range(“m5:m&dong_cuoi”).value
End sub
Bác thông cảm, nhà em mất mạng, up ảnh chụp bằng điện thoại thì báo lỗi dung lượng lớn.
Của em là có 1 combo box tên là : dvql_cbb
Em muốn lấy dữ liệu trên sheet2 cột M bắt đầu từ M5 đến M dòng cuối cùng có dữ liệu.
Em cảm ơn!
 
Chào bác ạ, em muốn lấy cái list vào combo box từ cột M, từ M5 đến M*, M* là vì khi thêm mới dữ liệu ở cột M thì số dòng có dữ liệu sẽ thay đổi.
Em muốn khi có dữ liệu mới nó sẽ load vào combo box dựa vào tìm dòng cuối.
Nhưng khi viết đoạn load từ cột M vào combo box thì bị lỗi.
Bác xem code sai ở đâu hộ e với ạ + viết sao cho đúng ạ.
Mã:
Private sub userform_initialize()
Dim dong_cuoi as long
dong_cuoi = sheet2.cells(rows.count, “m”).end(xlup).row+1
dvql_cbb.list = sheet2.range(“m5:m&dong_cuoi”).value
End sub
Bác thông cảm, nhà em mất mạng, up ảnh chụp bằng điện thoại thì báo lỗi dung lượng lớn.
Của em là có 1 combo box tên là : dvql_cbb
Em muốn lấy dữ liệu trên sheet2 cột M bắt đầu từ M5 đến M dòng cuối cùng có dữ liệu.
Em cảm ơn!

Tôi cũng mới làm quen với VBA Excel thôi bạn à nên còn nhiều cái chưa nắm rõ nhé bạn, cũng thuộc dạng nhập môn thôi :) , chưa sạch nước cản đó.
Về cái Range động để gán cho source của Combobox như bạn đề cập, tôi nghĩ nên đổi thành Table sẽ hiệu quả hơn. Tài liệu của MS cũng khuyến cáo vậy.
Để khai báo Range động thì có thể dùng hàm OFFSET hoặc như kiểu bạn đang làm:
= OFFSET(Sheet2!$M$5,0,0,COUNTA(Sheet2!$M:$M),1)
= "Info!$M$5:M" & Sheet2.Range("M" & Rows.Count).End(xlUp).Row

Trong cách khai báo Range ở trên có lồng các hàm CountA, Count nó sẽ thực hiện việc điếm nhiều dòng trong range do đó sẽ ảnh hưởng đến tốc độ thực thi khi cái range có số lượng dòng lớn. Dùng Range có cái lợi là có thể viết cho phiên bản Excel 2003. Dùng Table thì phải Excel 2007 trở lên mới hỗ trợ.
Form của bạn sửa lại:
- Tạo Table cho cái range có cột M, đặt tên ví dụ như: "UserLevelRange"
- Sự kiện UserForm_Initialize():
Me.dvql_cbb.RowSource = "UserLevelRange"
 
Tôi cũng mới làm quen với VBA Excel thôi bạn à nên còn nhiều cái chưa nắm rõ nhé bạn, cũng thuộc dạng nhập môn thôi :) , chưa sạch nước cản đó.
Về cái Range động để gán cho source của Combobox như bạn đề cập, tôi nghĩ nên đổi thành Table sẽ hiệu quả hơn. Tài liệu của MS cũng khuyến cáo vậy.
Để khai báo Range động thì có thể dùng hàm OFFSET hoặc như kiểu bạn đang làm:
= OFFSET(Sheet2!$M$5,0,0,COUNTA(Sheet2!$M:$M),1)
= "Info!$M$5:M" & Sheet2.Range("M" & Rows.Count).End(xlUp).Row

Trong cách khai báo Range ở trên có lồng các hàm CountA, Count nó sẽ thực hiện việc điếm nhiều dòng trong range do đó sẽ ảnh hưởng đến tốc độ thực thi khi cái range có số lượng dòng lớn. Dùng Range có cái lợi là có thể viết cho phiên bản Excel 2003. Dùng Table thì phải Excel 2007 trở lên mới hỗ trợ.
Form của bạn sửa lại:
- Tạo Table cho cái range có cột M, đặt tên ví dụ như: "UserLevelRange"
- Sự kiện UserForm_Initialize():
Me.dvql_cbb.RowSource = "UserLevelRange"
Em vẫn chưa hiểu lắm ạ.
Em chỉ cần lấy cái giá trị của List = số phần tử hiện tại trên cột M có giá trị. Vi khi thêm dữ liệu vào cột M thì list của cột M sẽ thay đổi ạ.
Ví dụ dữ liệu đang có từ M5:M10, nhưng khi thêm dữ liệu vào thì list sẽ thành là M5:M12 ạ.
Em làm như của bác hướng dẫn nhưng ko được. Bác cho em hỏi cái "UserLevelRange" là sao bác?
Bài đã được tự động gộp:

Tôi cũng mới làm quen với VBA Excel thôi bạn à nên còn nhiều cái chưa nắm rõ nhé bạn, cũng thuộc dạng nhập môn thôi :) , chưa sạch nước cản đó.
Về cái Range động để gán cho source của Combobox như bạn đề cập, tôi nghĩ nên đổi thành Table sẽ hiệu quả hơn. Tài liệu của MS cũng khuyến cáo vậy.
Để khai báo Range động thì có thể dùng hàm OFFSET hoặc như kiểu bạn đang làm:
= OFFSET(Sheet2!$M$5,0,0,COUNTA(Sheet2!$M:$M),1)
= "Info!$M$5:M" & Sheet2.Range("M" & Rows.Count).End(xlUp).Row

Trong cách khai báo Range ở trên có lồng các hàm CountA, Count nó sẽ thực hiện việc điếm nhiều dòng trong range do đó sẽ ảnh hưởng đến tốc độ thực thi khi cái range có số lượng dòng lớn. Dùng Range có cái lợi là có thể viết cho phiên bản Excel 2003. Dùng Table thì phải Excel 2007 trở lên mới hỗ trợ.
Form của bạn sửa lại:
- Tạo Table cho cái range có cột M, đặt tên ví dụ như: "UserLevelRange"
- Sự kiện UserForm_Initialize():
Me.dvql_cbb.RowSource = "UserLevelRange"
Chào bác, em vừa tìm được trên mạng đoạn code đơn giản như này, em vừa check thấy ok bác ạ
Mã:
Private Sub userform_initialize()
With Sheet2
    Me.dvql_cbb.List = .Range("m5", .Range("M" & .Rows.Count).End(xlUp)).Value
End With
End Sub
 
Lần chỉnh sửa cuối:
Em làm như của bác hướng dẫn nhưng ko được. Bác cho em hỏi cái "UserLevelRange" là sao bác?
Bài đã được tự động gộp:


Chào bác, em vừa tìm được trên mạng đoạn code đơn giản như này, em vừa check thấy ok bác ạ
Mã:
Private Sub userform_initialize()
With Sheet2
    Me.dvql_cbb.List = .Range("m5", .Range("M" & .Rows.Count).End(xlUp)).Value
End With
End Sub

Bạn nên ngâm cứu về Table và Name Range trong Excel đi nhé, sử dụng nó tiện lắm đó. Cái "UserLevelRange" là cái tên tự đặt cho cái Table chứa cột dữ liệu từ M5 đến dòng cuối có dữ liệu đó. Muốn đặt tên gì dễ nhớ, dễ hiểu để dễ gọi trong code.
Thay vì bạn dùng:
Me.dvql_cbb.List = .Range("m5", .Range("M" & .Rows.Count).End(xlUp)).Value

Thì tôi dùng: gọn hơn và kết quả như nhau nhưng về mặt tốc độ thì chắc chắn nhanh hơn.
Me.dvql_cbb.RowSource = "UserLevelRange"
Cách dùng này dễ bảo trì, sửa code hơn. Ví dụ: sau này bạn thay đổi địa chỉ ô M5 sang vị trí khác thì phải vô sửa code. Còn dùng Tên Table như cách của tôi thì khi bạn thay đổi địa chỉ khai báo cho cái table đó thì không cần đổi code miễn là cái tên Table ("UserLevelRange")không đổi là vẫn chạy được.
 
Bạn nên ngâm cứu về Table và Name Range trong Excel đi nhé, sử dụng nó tiện lắm đó. Cái "UserLevelRange" là cái tên tự đặt cho cái Table chứa cột dữ liệu từ M5 đến dòng cuối có dữ liệu đó. Muốn đặt tên gì dễ nhớ, dễ hiểu để dễ gọi trong code.
Thay vì bạn dùng:
Me.dvql_cbb.List = .Range("m5", .Range("M" & .Rows.Count).End(xlUp)).Value

Thì tôi dùng: gọn hơn và kết quả như nhau nhưng về mặt tốc độ thì chắc chắn nhanh hơn.
Me.dvql_cbb.RowSource = "UserLevelRange"
Cách dùng này dễ bảo trì, sửa code hơn. Ví dụ: sau này bạn thay đổi địa chỉ ô M5 sang vị trí khác thì phải vô sửa code. Còn dùng Tên Table như cách của tôi thì khi bạn thay đổi địa chỉ khai báo cho cái table đó thì không cần đổi code miễn là cái tên Table ("UserLevelRange")không đổi là vẫn chạy được.
Bác qua đây tư vấn giúp e về code load Chart với ạ.
 
Web KT

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

Back
Top Bottom