Trải nghiệm cùng thiết kế Form bằng sheets trong Excel

Liên hệ QC

ketoan100

Thành viên bị đình chỉ hoạt động
Thành viên bị đình chỉ hoạt động
Tham gia
13/10/07
Bài viết
90
Được thích
13
Mình muốn có một phần mềm được tích hợp sẵn trên Excel mà không phải quá rờm rà khi sử dụng nhiều User Form
nên mình cố gắng tìm kiếm code để làm ra sản phẩm này. Mọi người hãy cùng trải nghiệm và góp ý thêm cho mình nhe.
Để mình được hoàn thành thêm nhiều tiện ích khác.
Xin chân thành cảm ơn mọi người.
 

File đính kèm

  • form trai nghiem.xlsm
    767.4 KB · Đọc: 64
Quả là 1 công trình đồ sộ & kỳ công lắm!
Vậy nên thấy cái gì gốp thử cái í nha, thông cảm:

Đoạn mã dưới đây trích ở module3 ở macro có tên là Them:
PHP:
With Sheets("BANGKE")
    Sheets("BANGKE").Select
3    lr = .Cells(.Rows.count, "F").End(xlUp).Row
    x = WorksheetFunction.CountIf(.Range("D9:D" & lr), sophieuchi)
    If x <> 0 Then MsgBox ("Da co so phieu " & sophieuchi & "!!!"): Exit Sub
    Sheets("BANGKE").Select
7    Range("D" & lr + 1).Value = sophieuchi
    Range("F" & lr + 1).Value = ngaychi
    Range("G" & lr + 1).Value = lydochi
    Range("H" & lr + 1).Value = sotienchi
    Range("I" & lr + 1).Value = tienthuechi
    Range("J" & lr + 1).Value = tongcongchi
    Range("K" & lr + 1).Value = taikhoannochi
    Range("L" & lr + 1).Value = taikhoancochi
    Range("M" & lr + 1).Value = sochungtugocchi
    Range("N" & lr + 1).Value = ngaychungtugocchi
    Range("O" & lr + 1).Value = mausochungtugoc
    Range("P" & lr + 1).Value = kyhieuchungtugoc
    Range("Q" & lr + 1).Value = mancc
    Range("R" & lr + 1).Value = tenncc
    Range("S" & lr + 1).Value = nguoinhantien
    Range("T" & lr + 1).Value = diachincc
    Range("U" & lr + 1).Value = thuesuatchi
    Range("V" & lr + 1).Value = quychi
    Range("W" & lr + 1).Value = ghichuchi           '25  '
' . . . . . .    '
Bạn xem có thể cộng đơn vị vô dòng lệnh mang số 3; Để 25 dòng lệnh từ dòng lệnh 7 đỡ hao điện do cứ phải cộng đơn vị không?

Thứ 2: Gôm các dòng lệnh ngắn lại, như:
Mã:
    With Sheet3
        Sheet3.Select
        .Range("E3").Value = "":        .Range("E5").Value = ""
        .Range("E9").Value = "":        .Range("E19").Value = ""
        .Range("E7").Value = "":        .Range("K5").Value = ""
        .Range("H3").Value = "":        .Range("H5").Value = ""
        .Range("H11").Value = "":        .Range("H17").Value = ""
        .Range("E21").Value = ""
    End With

Lợi ích của việc này ta dễ bao quát hết các dòng lệnh trong 1 macro trên 1 trang màn hình chăng?!

Thứ 3: Nếu là mình thì mình viết vầy:
PHP:
Sub Lam_Moi()
With Sheets("Formchi")
    Cells(3, 5).Value = Cells(3, 12).Value
    Range("E5").Value = Format(Now, "dd/mm/yyyy") 'Cells(5, 5).Value = Format(Now, "dd/mm/yyyy")    '
'    Sheet3.Range("E7") = "":    Sheet3.Range("E9") = ""    '
'    Sheet3.Range("E19") = "":    Sheet3.Range("E21") = ""  '
    Sheet3.Union([E7], [E9], [E19], [E21]).Value = Space(0)
    Sheet3.Union([h3], [h5], [h7], [h9], [H11], [H17]).Value = ""
'    Sheet3.Range("H3") = "":                Sheet3.Range("H5") = ""    '
'    Sheet3.Range("H7") = "":                Sheet3.Range("H9") = ""    '
'    Sheet3.Range("H11") = "":               Sheet3.Range("H17") = ""   '
    Sheet3.Union([k3], [k5], [k7]).Value = Space(0)
'    Sheet3.Range("K3") = "":                 Sheet3.Range("K5") = ""   '
'    Sheet3.Range("K7") = ""        '
End With
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
3 macro ở module2 nên thử viết thành 4 macro, như vầy
Mã:
Sub Home()
 GPE Sheet2, 1
End Sub
Mã:
Sub BANGKE()
 GPE Sheet6, 3
End Sub
Mã:
Sub SOQUY()
GPE Sheet7, 5
End Sub
PHP:
Sub GPE(Sh As Worksheet, Num As Integer)
Application.ScreenUpdating = False
ActiveWindow.Zoom = 80
Sh.Select
Select Case Num
Case 1
    ActiveSheet.Shapes.Range(Array("Rectangle 1")).Visible = msoFalse
Case 3
    ActiveSheet.Shapes.Range(Array("Rectangle 3")).Visible = msoFalse
Case 5
    ActiveSheet.Shapes.Range(Array("Rectangle 5")).Visible = msoFalse
End Select
Application.ScreenUpdating = True
End Sub
 
Upvote 0
Cảm ơn sự góp ý của chuyên gia !!!:yeah:
 
Upvote 0
Code có quá nhiều chi tiết. Nếu chỉ đơn giản thu gọn thì chỉ là một sự trao đổi giữa số dòng code và tính chất dễ hiểu, dễ chỉnh sửa.
Điển hình chùm code ở bài #2 có thể gộp lại thành mảng:
a1 = Array(Range("D1"), Range("F1"), ...)
a2 = .... ' với sophieuchi là a2(0), ngaychi là a2(2)...
for i = 0 to UBound(a1)
a1(i).Offset(lr,0) = a2(i)
Next c
Nhưng đọc code sẽ rất khó hiểu. Rất khó nối (map) các phần tử với nhau khi cần debug và chỉnh sửa.

Nếu muốn thu gọn code thì cách duy nhất là thiết kế lại ngay từ đầu. Thu gọn từng đoạn chỉ là một sự vá víu.

Code ở bài #3 hơi chủ quan. Với một project lớn thì khi tách mỗi sub/function cần phải chú thích nó làm gì, và tham số nó cần gì.
Nếu khong, cỡ 3 tháng sau, đọc lại code sẽ chả hiểu gì hết.
 
Upvote 0
Cảm ơn sự góp ý và chia sẻ của bạn, mình sẽ tìm cách chỉnh sửa lại cho gọn và dễ hiểu hơn. Thanks!!
Bài đã được tự động gộp:

Sub Lam_Moi()
With Sheets("Formchi")
Cells(3, 5).Value = Cells(3, 12).Value
Range("E5").Value = Format(Now, "dd/mm/yyyy") 'Cells(5, 5).Value = Format(Now, "dd/mm/yyyy") '
' Sheet3.Range("E7") = "": Sheet3.Range("E9") = "" '
' Sheet3.Range("E19") = "": Sheet3.Range("E21") = "" '
Sheet3.Union([E7], [E9], [E19], [E21]).Value = Space(0)
Sheet3.Union([h3], [h5], [h7], [h9], [H11], [H17]).Value = ""
...........
Nó báo lỗi, nó không hiểu Union là cái gì Bác ơi !
 
Lần chỉnh sửa cuối:
Upvote 0
Sheet3.Union([E7], [E9], [E19], [E21]).Value = Space(0)
Sheet3.Union([h3], [h5], [h7], [h9], [H11], [H17]).Value = ""
...........
Nó báo lỗi, nó không hiểu Union là cái gì Bác ơi !
Union là hàm của Application, không phải của sheet/worksheet.
Rõ ràng trước mắt. Rút gọn code kiểu này thì phải trả giá bằng sự khó hiểu của code.
(có những trường hợp rút gọn khiến cho code dễ hiểu, dễ chiunhr sửa hơn; nhưng nó không phải là trường hợp của bạn. Như tôi đã nói ở trên, trường hợp của bạn muốn rút gọn phải thiết kế lại từ đầu)
 
Upvote 0
Em nghĩ tuần sau đọc lại là chóng mặt rồi ấy.
Chịu khó ghi chú mới ổn, cái đơn giản cũng ghi chú thì càng tốt.
Khách quan:
Nếu không có ghi chú thì một thời gian sau người ta sẽ quên mất thiết kế mô hình của project. Thời gian để quên này (1 tuần, 1 tháng hay 1 năm) tuỳ thuộc vào độ phức tạp và độ lớn của project.
Chính vì vậy mà các phần mềm lớn đều có hệ thống quản trị code riêng của nó. (*)

Chủ quan:
Một người bình thường (tức là không phải người siêu giỏi) có một cái sì tin code mà chỉ tiến hoá hoặc thoái hoá theo thời gian.
Thời gian vài tháng tới 1-2 năm là thời gian trung bình để tiến/thoái hoá.
Chính sự tiến/thoái hoá này khiến người ta nhìn lại "ủa code này là tôi viết đây sao?"

(*) Điển hình: Hình như bạn đang làm Python. Python có luật chú kiểu Java cho các hàm, các script của nó.
Với kiểu chú này, các phần mềm IDE có thể lấy chú thích làm help và gợi ý (intellisense) khi bạn gõ tên hàm.
 
Upvote 0
Mình muốn có một phần mềm được tích hợp sẵn trên Excel mà không phải quá rờm rà khi sử dụng nhiều User Form

:) Cũng góp ý chút trong vụ Form nhập liệu này.
Bạn thiết kế Form nhập liệu thẳng trên Sheet Excel thì cũng là 1 Form và nó không khác gì 1 UserForm nên nói UserForm rườm rà là không hợp lý.
Theo tôi bạn nên thiết kế Form theo 2 cách sau:
1. Là bạn kéo trực tiếp các control của form (textbox, checkbox...) bố cục lên thẳng Sheet.
2. Làm trong UserForm.
Tôi thấy bạn code trong VBA cũng nhiều thì việc dùng UserForm không phải là vấn đề khó đối với bạn.

Tại sao tôi khuyên bạn nên làm theo cách trên vì có nhưng điểm không thuận tiện khi thiết kế Form nhập liệu bằng chính từng Cell của Excel:
- Ô nhập liệu bằng Cell sẽ bị phụ thuộc độ rộng của Cell (cùng cột). Các ô nhập bên dưới phụ thuộc thiết kế của hàng đầu tiên.
- Không có nhiều công cụ hỗ trợ cho nhập liệu nhanh ví dụ như: Checkbox, Option button...
- Nói về code: dùng UserForm code sẽ ngắn hơn trong việc Thêm, Lưu, Xoá
Ví dụ:
Code cho nút Lưu hiện tại trong Form của bạn:
Mã:
Sub them()
    Dim sophieuchi As String
    Dim ngaychi As String
    ...
    With Sheets("Formchi")
        Sheets("Formchi").Select
        sophieuchi = Range("E3").Value
        ngaychi = Range("E5").Value
        ...
    End With
    ...
    Sheets("BANGKE").Select
        Range("D" & lr + 1).Value = sophieuchi
        Range("F" & lr + 1).Value = ngaychi
        ...

==> Code này bạn phải khai báo biến để nhận giá trị từ Cell (sopheuchi,...) rồi sau đó mới gán trị đó cho các Cell trong bảng dữ liệu.

Nếu dùng UserForm bạn chỉ cần gán trực tiếp từ textbox trên Form.

Mã:
Sheets("BANGKE").Select
        Range("D" & lr + 1).Value = txtSoPhieuChi
        Range("F" & lr + 1).Value = txtNgayChi
        ...


Code cho nút [làm mới] cũng có thể viết gọn hơn. Ví dụ:
Mã:
Private cmdLamMoi_Click

  Dim c As Control
  For Each c In Me.Controls
      If c.Name Like "txt*" Then c = vbNullString
  next c

End Sub

Đôi điều góp ý cùng bạn.
 
Lần chỉnh sửa cuối:
Upvote 0
Biết ít hoặc vừa (vì đây là môi trường Excel) thì sheet_form có thể hiệu quả
Biết đủ hoặc hơn chút thì dùng Form là chuẩn tắc mọi phần mềm ứng dụng.
Tuy thế với sheet_form thì có vẻ lợi dụng được lưới của sheets, nhưng bất tiện với các yếu tố riêng lẻ.
nên cuối cùng là phụ thuộc vào chữ "tùy"
 
Upvote 0
Web KT
Back
Top Bottom