Các câu hỏi về Form trong Excel VBA

Liên hệ QC

Tường_Vi

Thành viên tiêu biểu
Tham gia
19/4/10
Bài viết
482
Được thích
121
Nghề nghiệp
Luôn tìm kiếm một vị trí tốt hơn
Private Sub UserForm_Initialize()
.......................
.......................
.......................
End Sub


Em xin hỏi, sự kiện khí nào mình dùng sự kiện này Initialize

Cám ơn
 
Control em xin chịu ... có viết mấy đâu
Thế bạn lập trình API như thế nào? Các hàm API chỉ dùng Pixel thôi. Vd. GetWindowRect trả về trong cấu trúc RECT left, top, right, Bottom tính bằng Pixel. Hàm ClientToScreen dùng khi vd. ta muốn biết điểm nằm trên một cửa sổ (vd. góc trái bên trên của Button) ở tọa độ (x; y) trong client-area thì nằm ở tọa độ nào trên screen. Giá trị truyền vào và kết quả của hàm ClientToScreen được tính bằng Pixel. Hoặc hàm GDI CreateCompatibleBitmap ...

Không phải vô cớ mà trong bài #395 tôi có
list.Parent.ScaleMode = vbPixels
Nhưng bạn biến dòng đó thành REM. Rồi thêm dòng
Mã:
list.Parent.Point = vbPixels.
Chứng tỏ bạn không hiểu, và không thắc mắc để tìm hiểu, tại sao tôi lại sửa ScaleMode thành vbPixels. Dòng thêm của bạn cũng chứng tỏ bạn không hiểu Point nó là gì, dùng thế nào.
 
Upvote 0
Thế bạn lập trình API như thế nào? Các hàm API chỉ dùng Pixel thôi. Vd. GetWindowRect trả về trong cấu trúc RECT left, top, right, Bottom tính bằng Pixel. Hàm ClientToScreen dùng khi vd. ta muốn biết điểm nằm trên một cửa sổ (vd. góc trái bên trên của Button) ở tọa độ (x; y) trong client-area thì nằm ở tọa độ nào trên screen. Giá trị truyền vào và kết quả của hàm ClientToScreen được tính bằng Pixel. Hoặc hàm GDI CreateCompatibleBitmap ...

Không phải vô cớ mà trong bài #395 tôi có

Nhưng bạn biến dòng đó thành REM. Rồi thêm dòng
Mã:
list.Parent.Point = vbPixels.
Chứng tỏ bạn không hiểu, và không thắc mắc để tìm hiểu, tại sao tôi lại sửa ScaleMode thành vbPixels. Dòng thêm của bạn cũng chứng tỏ bạn không hiểu Point nó là gì, dùng thế nào.
thì trên GPE này từ lâu rất lâu rồi em có nói mọi cái liên quan tới API của MS là em = 0 to đùng rồi mà
Thử hỏi trên GPE này kiến thức API như anh đếm được 2 hay 3 người ???!!!
chủ yếu em copy API của ai đó xài chứ để hiểu nó là Không ... muốn tìm hiểu lắm nhưng mấy khi xài liên quan tới nó mà tìm
 
Upvote 0
Xin chào các bạn,
OT đang muốn nhập liệu thời gian thông qua một UserForm, do kiến thức cơ bản về form còn rất kém cỏi nên chưa biết cách xử lý cho vấn đề này .
Do dó OT gửi lên nhờ các bạn xử lý giúp để OT dựa vào đó tham khảo thêm ạ.
 

File đính kèm

  • UfTime.xlsx
    15.6 KB · Đọc: 16
Upvote 0
Xin chào các bạn,
OT đang muốn nhập liệu thời gian thông qua một UserForm, do kiến thức cơ bản về form còn rất kém cỏi nên chưa biết cách xử lý cho vấn đề này .
Do dó OT gửi lên nhờ các bạn xử lý giúp để OT dựa vào đó tham khảo thêm ạ.
Vẫn chưa hiểu trên là 23 giờ mà dưới lại ca 2? Số phút hiện lên từ 0 đến 59 hay 99? Giải thích rõ hơn được không? Mục đích để làm gì?
 
Lần chỉnh sửa cuối:
Upvote 0
Vẫn chưa hiểu trên là 23 giờ mà dưới lại ca 2? Số phút hiện lên từ 0 đến 59 hay 99? Giải thích rõ hơn được không? Mục đích để làm gì?
Làm gì có 23 giờ nào? Tôi mở lên thấy 19:49.

"Ở đấy" là NOW, tức nếu muốn Ca 2 thì không được mở Form lúc 23 giờ mà phải đợi đến lúc thích hợp, nhìn đồng hồ nếu vd. 16:02 thì mới mở Form. Lúc đó trên 16:02 và dưới Ca 2 sẽ khớp nhau. :D

Tôi lại có câu hỏi khác. Ngày giờ hiện hành để làm gì? Nếu chỉ để làm cảnh thì loại bỏ. Còn nếu dùng ngày hiện giờ hiên hành thì bỏ ComboBox Ca. Lúc đó Ca sẽ được xác định dựa vào ngày giờ hiện hành chứ không phải chọn từ combobox. Thêm ComboBox Ca để chọn thì người ta sẽ không hiểu tại sao "trên là 23 giờ mà dưới lại ca 2". :D

Hoặc giải thích kỹ, cái ngày giờ kia (NOW) nó dùng để làm gì.
-------------
Thôi không quan trọng việc textbox hiện tại làm cảnh hay không. Ở dưới là code. Tên các textbox hiện tại, combobox ca, combobox giờ, combobox phút, nút Xác định lần lượt phải là: tb_hientai, cb_Ca, cb_Gio, cb_Phut, cmdXacNhan.
Mã:
Option Explicit

Private Sub cb_Ca_Change()
Dim k As Long, batdau As Long, gio(0 To 8)
    cb_Gio.Clear    ' xoa danh sach cu trong combobox cb_Gio
    batdau = 6 + (Right(cb_Ca.Value, 1) - 1) * 8    ' voi Ca1, Ca2, C3 thi batdau = 6, 14, 22
    For k = 0 To 8
        gio(k) = (batdau + k - 1) Mod 24 + 1
    Next k
    cb_Gio.List = gio   ' nap danh sach gio vao combobox cb_Gio
End Sub

Private Sub cmdXacNhan_Click()
    If cb_Gio.ListIndex = -1 Or cb_Phut.ListIndex = -1 Then Exit Sub
    With ThisWorkbook.Worksheets("Sheet1")
        .Range("H17").Value = cb_Ca.Value
        .Range("K17").Value = Format(cb_Gio.Value / 24 + cb_Phut.Value / 1440, "h:mm")
    End With
End Sub

Private Sub UserForm_Initialize()
Dim k As Long, phut(0 To 59) As Long
    tb_hientai.Value = Format(Date, "Short Date") & Format(Now(), " hh:mm:ss")  ' ngay gio hien tai
    cb_Ca.List = Array("Ca1", "Ca2", "Ca3") ' nap danh sach 3 ca vao combobox cb_Ca
    For k = 0 To 59
        phut(k) = k
    Next k
    cb_Phut.List = phut ' nap danh sach phut vao combobox cb_Phut
    cb_Gio.ListRows = 9 ' hien thi 9 dog
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Ngày giờ hiện hành để làm gì? Nếu chỉ để làm cảnh thì loại bỏ.

Con chào Bác Siwtom,
Con cảm ơn Bác nhiều ạ, xem code con đã hiểu thêm được nhiều vấn đề rồi Bác.
Dạ vâng ngày giờ hiện hành chỉ mang tính làm 'cảnh' cho người nhập nhìn thấy ạ, con muônd làm cái đồng hồ ở đây nhưng con nghĩ trong quá trình chạy nó nặng cho code nên thôi Bác ạ.
Con chúc Bác nhiều sức khỏe ạ.
 
Upvote 0
Con chào Bác Siwtom,
Con cảm ơn Bác nhiều ạ, xem code con đã hiểu thêm được nhiều vấn đề rồi Bác.
Dạ vâng ngày giờ hiện hành chỉ mang tính làm 'cảnh' cho người nhập nhìn thấy ạ, con muônd làm cái đồng hồ ở đây nhưng con nghĩ trong quá trình chạy nó nặng cho code nên thôi Bác ạ.
Con chúc Bác nhiều sức khỏe ạ.
Bây giờ không chỉ ăn no mặc ấm mà còn ăn ngon mặc đẹp, không thể xem nhẹ "làm cảnh"
 
Upvote 0
Bây giờ không chỉ ăn no mặc ấm mà còn ăn ngon mặc đẹp, không thể xem nhẹ "làm cảnh"

Con chào Bác Hiếu
Bác ơi con tính làm cái đồng hồ ở đó để tiện theo dõi.
Nhưng đúng là nó chưa quá cần thiết Bác ạ.
Con cảm ơn Bác đã góp ý ạ.
 
Upvote 0
Làm gì có 23 giờ nào? Tôi mở lên thấy 19:49.

"Ở đấy" là NOW, tức nếu muốn Ca 2 thì không được mở Form lúc 23 giờ mà phải đợi đến lúc thích hợp, nhìn đồng hồ nếu vd. 16:02 thì mới mở Form. Lúc đó trên 16:02 và dưới Ca 2 sẽ khớp nhau. :D

Tôi lại có câu hỏi khác. Ngày giờ hiện hành để làm gì? Nếu chỉ để làm cảnh thì loại bỏ. Còn nếu dùng ngày hiện giờ hiên hành thì bỏ ComboBox Ca. Lúc đó Ca sẽ được xác định dựa vào ngày giờ hiện hành chứ không phải chọn từ combobox. Thêm ComboBox Ca để chọn thì người ta sẽ không hiểu tại sao "trên là 23 giờ mà dưới lại ca 2". :D

Hoặc giải thích kỹ, cái ngày giờ kia (NOW) nó dùng để làm gì.
-------------
Thôi không quan trọng việc textbox hiện tại làm cảnh hay không. Ở dưới là code. Tên các textbox hiện tại, combobox ca, combobox giờ, combobox phút, nút Xác định lần lượt phải là: tb_hientai, cb_Ca, cb_Gio, cb_Phut, cmdXacNhan.
Mã:
Option Explicit

Private Sub cb_Ca_Change()
Dim k As Long, batdau As Long, gio(0 To 8)
    cb_Gio.Clear    ' xoa danh sach cu trong combobox cb_Gio
    batdau = 6 + (Right(cb_Ca.Value, 1) - 1) * 8    ' voi Ca1, Ca2, C3 thi batdau = 6, 14, 22
    For k = 0 To 8
        gio(k) = (batdau + k - 1) Mod 24 + 1
    Next k
    cb_Gio.List = gio   ' nap danh sach gio vao combobox cb_Gio
End Sub

Private Sub cmdXacNhan_Click()
    If cb_Gio.ListIndex = -1 Or cb_Phut.ListIndex = -1 Then Exit Sub
    With ThisWorkbook.Worksheets("Sheet1")
        .Range("H17").Value = cb_Ca.Value
        .Range("K17").Value = Format(cb_Gio.Value / 24 + cb_Phut.Value / 1440, "h:mm")
    End With
End Sub

Private Sub UserForm_Initialize()
Dim k As Long, phut(0 To 59) As Long
    tb_hientai.Value = Format(Date, "Short Date") & Format(Now(), " hh:mm:ss")  ' ngay gio hien tai
    cb_Ca.List = Array("Ca1", "Ca2", "Ca3") ' nap danh sach 3 ca vao combobox cb_Ca
    For k = 0 To 59
        phut(k) = k
    Next k
    cb_Phut.List = phut ' nap danh sach phut vao combobox cb_Phut
    cb_Gio.ListRows = 9 ' hien thi 9 dog
End Sub

Con chào Bác Siwtom,
Bác ơi code đúng ý con rồi Bác,Bác thêm giúp con một số câu lệnh xử lý lỗi với ạ:
Nếu 'cb_ca' là rỗng (chưa nhập) thì các 'cb_Gio' và 'cb_Phut' và 'cmdXacNhan' bị ẩn đi không cho thao tác ạ.
Sau khi chọn 'cb_ca' xong thì sẽ hiện lên 'cb_Gio' và sau khi 'cb_Gio' nhập liệu thì hiện 'cb_Phut' và sau khi có đầy đủ dữ liệu ở các combobox thì sẽ hiện 'cmdXacNhan.
Con cảm ơn Bác Siwtom nhiều ạ.
 
Upvote 0
Con chào Bác Siwtom,
Bác ơi code đúng ý con rồi Bác,Bác thêm giúp con một số câu lệnh xử lý lỗi với ạ:
Nếu 'cb_ca' là rỗng (chưa nhập) thì các 'cb_Gio' và 'cb_Phut' và 'cmdXacNhan' bị ẩn đi không cho thao tác ạ.
Sau khi chọn 'cb_ca' xong thì sẽ hiện lên 'cb_Gio' và sau khi 'cb_Gio' nhập liệu thì hiện 'cb_Phut' và sau khi có đầy đủ dữ liệu ở các combobox thì sẽ hiện 'cmdXacNhan.
Con cảm ơn Bác Siwtom nhiều ạ.
Tôi nghĩ là không nên làm thế. Nếu muốn ẩn hiện 2 combobox và 1 commandbutton thì phải có code ẩn hiện, và code phản ứng với các thay đổi trong các combobox. Vd. tôi chọn trong cb_Ca thì code phải nắm được sự kiện đó để hiện cb_Gio. Nhưng nếu sau đó tôi xóa trong cb_Ca thì code cũng phải nắm được sự kiện đó để ẩn cb_Gio. Tương tự khi chọn hoặc xóa trong cb_Gio thì phải nắm được sự kiện đó để hiện hoặc ẩn cb_Phut. Đồng thời phải ẩn hiện cmdXacNhan. Thay đổi liên tục như thế không phải là cách hay.

Nếu bạn vẫn muốn ẩn hiện thì đợi người khác.

Chả lý gì cấm người ta vd. chọn Phút sau đó mới chọn Ca rồi sau cùng chọn Giờ. Giả sử cần chọn Ca2, giờ 16, phút 25 thì hoàn toàn có thể chọn Phút 25 -> chọn Ca2 -> chọn Giờ 16. Tại sao lại cấm người ta?

Nếu cần phục vụ trường hợp nhấn Xác Nhận khi chưa chọn đủ thì
Mã:
Private Sub cb_Ca_Change()
Dim k As Long, batdau As Long, gio(0 To 8)
    cb_Gio.Clear    ' xoa danh sach cu trong combobox cb_Gio
    If cb_Ca.ListIndex = -1 Then Exit Sub
    batdau = 6 + (Right(cb_Ca.Value, 1) - 1) * 8    ' voi Ca1, Ca2, C3 thi batdau = 6, 14, 22
    For k = 0 To 8
        gio(k) = (batdau + k - 1) Mod 24 + 1
    Next k
    cb_Gio.List = gio   ' nap danh sach gio vao combobox cb_Gio
End Sub

Private Sub cmdXacNhan_Click()
    If cb_Gio.ListIndex = -1 Or cb_Phut.ListIndex = -1 Then
        If cb_Ca.ListIndex = -1 Then
            cb_Ca.SetFocus
        ElseIf cb_Gio.ListIndex = -1 Then
            cb_Gio.SetFocus
        Else
            cb_Phut.SetFocus
        End If
        Exit Sub
    End If
    With ThisWorkbook.Worksheets("Sheet1")
        .Range("H17").Value = cb_Ca.Value
        .Range("K17").Value = Format(cb_Gio.Value / 24 + cb_Phut.Value / 1440, "h:mm")
    End With
End Sub
------- Sửa thêm 1 chữ c (ptm0412)
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Tôi nghĩ là không nên làm thế. Nếu muốn ẩn hiện 2 combobox và 1 commandbutton thì phải có code ẩn hiện, và code phản ứng với các thay đổi trong các combobox. Vd. tôi chọn trong cb_Ca thì code phải nắm được sự kiện đó để hiện cb_Gio. Nhưng nếu sau đó tôi xóa trong cb_Ca thì code cũng phải nắm được sự kiện đó để ẩn cb_Gio. Tương tự khi chọn hoặc xóa trong cb_Gio thì phải nắm được sự kiện đó để hiện hoặc ẩn cb_Phut. Đồng thời phải ẩn hiện cmdXacNhan. Thay đổi liên tục như thế không phải là cách hay.

Nếu bạn vẫn muốn ẩn hiện thì đợi người khác.

Chả lý gì cấm người ta vd. chọn Phút sau đó mới chọn Ca rồi sau cùng chọn Giờ. Giả sử cần chọn Ca2, giờ 16, phút 25 thì hoàn toàn có thể chọn Phút 25 -> chọn Ca2 -> chọn Giờ 16. Tại sao lại cấm người ta?

Nếu cần phục vụ trường hợp nhấn Xác Nhận khi chưa chọn đủ thì
[ode]
Private Sub cb_Ca_Change()
Dim k As Long, batdau As Long, gio(0 To 8)
cb_Gio.Clear ' xoa danh sach cu trong combobox cb_Gio
If cb_Ca.ListIndex = -1 Then Exit Sub
batdau = 6 + (Right(cb_Ca.Value, 1) - 1) * 8 ' voi Ca1, Ca2, C3 thi batdau = 6, 14, 22
For k = 0 To 8
gio(k) = (batdau + k - 1) Mod 24 + 1
Next k
cb_Gio.List = gio ' nap danh sach gio vao combobox cb_Gio
End Sub

Private Sub cmdXacNhan_Click()
If cb_Gio.ListIndex = -1 Or cb_Phut.ListIndex = -1 Then
If cb_Ca.ListIndex = -1 Then
cb_Ca.SetFocus
ElseIf cb_Gio.ListIndex = -1 Then
cb_Gio.SetFocus
Else
cb_Phut.SetFocus
End If
Exit Sub
End If
With ThisWorkbook.Worksheets("Sheet1")
.Range("H17").Value = cb_Ca.Value
.Range("K17").Value = Format(cb_Gio.Value / 24 + cb_Phut.Value / 1440, "h:mm")
End With
End Sub
[/code]
Con chào Bác Siwtom,
Đúng là cách này của Bác hơn cách mà con đang nghĩ ạ.
Ô nào thiếu thì sẽ di chuyển đến ô đó ạ.
Con cảm ơn Bác nhiều ạ.
 
Upvote 0
Web KT
Back
Top Bottom