Thực tập tạo Form từ A->Z

  • Thread starter Thread starter ThuNghi
  • Ngày gửi Ngày gửi
Liên hệ QC

ThuNghi

Hãy cho rồi sẽ nhận!
Thành viên đã mất
Tham gia
16/8/06
Bài viết
3,808
Được thích
4,449
Qua tham khảo formNgay của Mr OkeBab, MaxSoCT của MVSON, tôi xin phép lập thêm đề tài này nhằm tham khảo cách tạo form, nhờ các bạn hướng dẫn.
Tôi có form theo file gồm có TBNgayHT, TBNgayCT, TBLoaiCT, TBSoCT, tôi muốn làm thế nào khi nhập xong các chỉ tiêu TBNgayHT, TBNgayCT, TBLoaiCT, theo form thì TBSoCT sẽ tự động update theo tiêu thức LoaiCT/Nam-ThangHT/Số tt tăng theo tháng.
Mong các bạn hỗ trợ.
Xin cám ơn.
Làm sao lấy MaxSoCT không phải dùng ct {max(if...))}
Đây là file học tập, mong các bạn nhiệt tình.
 

File đính kèm

Lần chỉnh sửa cuối:
ThuNghi đã viết:
Tôi có form theo file gồm có TBNgayHT, TBNgayCT, TBLoaiCT, TBSoCT, tôi muốn làm thế nào khi nhập xong các chỉ tiêu TBNgayHT, TBNgayCT, TBLoaiCT, theo form thì TBSoCT sẽ tự động update theo tiêu thức LoaiCT/Nam-ThangHT/Số tt tăng theo tháng.

Có phải yêu cầu của Bác như thế này không ạ ?

1. Trong một ngày phát sinh 2 loại chứng từ là:

+ Phiếu thu (PT) -> Thứ tự tăng theo ngày
+ Phiếu chi (PC) -> Thứ tự tăng theo ngày

2. Hết 1 tháng thì số thứ tự của chứng từ trong ngày lại lặp lại và tăng từ 001 cho các loại phiếu thu(PT) và phiếu chi (PC)
 
Upvote 0
Cám ơn Dat2007 quan tâm.
Đúng rồi, hiện tại là làm từng bước, nếu thêm nhập mới lọai CT nữa thì rất hay.
 
Upvote 0
ThuNghi đã viết:
Cám ơn Dat2007 quan tâm.
Đúng rồi, hiện tại là làm từng bước, nếu thêm nhập mới lọai CT nữa thì rất hay.

Vấn đề đánh số TT thì đã có 2 Sub của bác nvson giải quyết xong, từng bước của bác ThuNghi sẽ phải cụ thể như thế này
  1. init form thì phải di chuyển đến cuối của Data (65536, xlup...)
  2. nhập và kiểm tra cho từng ô, nhập xong hết thì
  3. gán giá trị lần lượt cho các field
  4. call sub đánh số Thứ tự của bác nvson cho Row hiện tại
  5. di chuyển xuống dòng kế tiếp
  6. Xoá dữ liệu hiện tại tại các textbox (hay để luôn cho việc nhập chỉ là chỉnh sửa cho nhanh

Vậy thì bác muốn làm luôn, hay là hướng dẫn từng bước ạ?
Em thì hiểu ý bác là muốn hướng dẫn từng bước trên 4R để mọi người cùng xem phải không ạ?
 
Upvote 0
ThuNghi đã viết:
Qua tham khảo formNgay của Mr OkeBab, MaxSoCT của MVSON, tôi xin phép lập thêm đề tài này nhằm tham khảo cách tạo form, nhờ các bạn hướng dẫn.
Tôi có form theo file gồm có TBNgayHT, TBNgayCT, TBLoaiCT, TBSoCT, tôi muốn làm thế nào khi nhập xong các chỉ tiêu TBNgayHT, TBNgayCT, TBLoaiCT, theo form thì TBSoCT sẽ tự động update theo tiêu thức LoaiCT/Nam-ThangHT/Số tt tăng theo tháng.
Mong các bạn hỗ trợ.
Xin cám ơn.
Làm sao lấy MaxSoCT không phải dùng ct {max(if...))}
Đây là file học tập, mong các bạn nhiệt tình.

Em chưa xem hết File, nhưng xin trao đổi với bác thế này :

Dù không dùng {max(if...))} thì ta vẫn phải dùng một hàm nào đó (có thể là UF) để cho ra số này, tuy nhiên nó vẫn phải dùng vòng lặp (thì mới duyệt được tất cả các record trong bảng). Ta dùng các công thức của excel thì ta mới có thể lợi dụng được cái nhanh của mã máy. Vì vậy có lẽ vẫn nên dùng công thức của excel, nếu công thức dễ thì làm luôn trong VBA, còn khó thì làm trên sheet, sau đó bốc lên Form. Như thế chẳng tiện hơn sao. Đâu có mất nhiều thời gian và chỉ mất 1 cell thôi mà.

Vì ta có rất nhiều TH xảy ra : Thêm CT bình thường, sửa chứng từ, hủy CT . . . .

Vì vậy hàm {max(if...))} cũng rất hay đấy chứ.
Thân!
 
Upvote 0
Vậy thì bác muốn làm luôn, hay là hướng dẫn từng bước ạ?
Bạn giúp hộ, thêm vào 1 textbox nhập số của bạn.
Theo tôi, GP này về CT max có được không.
- Tìm từ dưới lên trên nếu thỏa dk là cùng tháng và loại CT = TBloaiCT thì lấy +1. Số CT luôn tăng dần.
- Dùng Max(if) mà không cần cells trung gian, chỉ gán cho 1 biến và gán vào TBSoCT.
Bổ sung thêm hộ, nếu TBNgayHT > TBNgayCT thì msg "sai"
Về khỏan form này trình độ tôi khiêm tốn lắm.
Cám ơn nhiều.
 
Upvote 0
ThuNghi đã viết:
Bạn giúp hộ, thêm vào 1 textbox nhập số của bạn.
Theo tôi, GP này về CT max có được không.
- Tìm từ dưới lên trên nếu thỏa dk là cùng tháng và loại CT = TBloaiCT thì lấy +1. Số CT luôn tăng dần.
- Dùng Max(if) mà không cần cells trung gian, chỉ gán cho 1 biến và gán vào TBSoCT.
Bổ sung thêm hộ, nếu TBNgayHT > TBNgayCT thì msg "sai"
Về khỏan form này trình độ tôi khiêm tốn lắm.
Cám ơn nhiều.
Em tặng bác cái UF này, nó có thể đánh số tự động đấy.
Option Explicit

PHP:
Public Function CTMax(KT As String, SoKT As Byte) As String
    On Error Resume Next
    Dim HC As Long
    Dim Cot As Long
    Dim Hang As Long
    Dim i As Long
    Dim CT As Range
    Cot = ActiveCell.Column
    Hang = ActiveCell.Row
    HC = Hang - 1
    For Each CT In Range(Cells(2, Cot), Cells(HC, Cot))
        If Left$(CT.Value, Len(KT)) = KT Then
        If IsNumeric(Val(Right$(CT.Value, SoKT))) = True Then
            If Val(Right$(CT.Value, SoKT)) > i Then i = Val(Right$(CT.Value, SoKT))
        End If: End If
    Next
    CTMax = KT & Format(i + 1, "000")
    Set CT = Nothing
End Function
Cú pháp : CTMax(KT;SoKT): PT/07/10/xxx

KT : Ký tự đầu của loại phiếu đó : PT/07/10/
SôKT :
Số KT sau cùng để xác định STT tăng dần, như VD trên là 3 ký tự (xxx)

Nó sẽ tính từ hàng thứ 2 đến ô trên nó 1 hàng

VD : Bác muốn tính CTMax của Phiếu PT/07/10/xxx (3 số xxx)

Vậy thì bác nhập = CTMax("PT/07/10/";3)

Nó sẽ tính ra phiếu max cho bác

Bác xem File VD.

Thân!
 

File đính kèm

Upvote 0
Nếu bác muốn nó tính toán trong một vùng chỉ định thì dùng UF này :
PHP:
Public Function CTMax2(Vung As Range, KT As String, SoKT As Byte) As String
    On Error Resume Next
    Dim i As Long
    Dim CT As Range
    For Each CT In Vung
        If Left$(CT.Value, Len(KT)) = KT Then
        If IsNumeric(Val(Right$(CT.Value, SoKT))) = True Then
            If Val(Right$(CT.Value, SoKT)) > i Then i = Val(Right$(CT.Value, SoKT))
        End If: End If
    Next
    CTMax2 = KT & Format(i + 1, "000")
    Set CT = Nothing
    Set Vung = Nothing
End Function
Thân!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Cám ơn Hiếu nhiều lắm, hôm GPE thế nào, rớt liên tục nên chưa xem kịp. Sẽ hồi báo.
 
Upvote 0
To Mr OkeBab
Cám ơn nhiều.
Hàm CTMax() rất tuyệt, sao bác không làm tham chiếu theo cột Loại CT luôn mà phải =CTMax("PT07/11/",3) cái "PT07/11/" có nhập rồi mà. Với lại nếu thuật tóan chuyển tìm từ dưới lên có nhanh hơn không. Giống như hàm Match tìm từ dưới (NVSON), nếu ngày = ngày HT thì lấy max. Nghĩ vậy mà chưa làm ra.
To SoiBien
Cám ơn nhiều. Chưa đúng ý đồ lắm nếu trong form chỉ kiểm tra ngày HT và Ngày CT hợp lệ và sau khi chọn loại CT thì SoCT tự udate, chưa tính chuyện gán vào cell.
 
Upvote 0
ThuNghi đã viết:
To SoiBien
Cám ơn nhiều. Chưa đúng ý đồ lắm nếu trong form chỉ kiểm tra ngày HT và Ngày CT hợp lệ và sau khi chọn loại CT thì SoCT tự udate, chưa tính chuyện gán vào cell.

hì hì, vì cái hàm của bác nvson nó thế, vậy bác gán cái của bác Bap vào là được mà.
 
Upvote 0
ThuNghi đã viết:
To Mr OkeBab
Cám ơn nhiều.
Hàm CTMax() rất tuyệt, sao bác không làm tham chiếu theo cột Loại CT luôn mà phải =CTMax("PT07/11/",3) cái "PT07/11/" có nhập rồi mà. Với lại nếu thuật tóan chuyển tìm từ dưới lên có nhanh hơn không. Giống như hàm Match tìm từ dưới (NVSON), nếu ngày = ngày HT thì lấy max. Nghĩ vậy mà chưa làm ra.

Cái thứ nhất :

cái "PT07/11/" em chỉ dùng VD thôi, em muốn dùng cho mọi TH là yyyyyyyyxxxxx

Ở đó dãy Y là chuỗi ký tự (không phân biệt là cái gì, để dùng cho cái gì cũng được), X là dãy số thứ tự để đánh số

VD :
  • PT07/11/002 ---> CTMax("PT07/11/";3)
  • PNK/2007/11/0004 ---> CTMax("PNK2007/11/";4)
  • PXK07/7/000001---> CTMax("PXK07/7/";6)
Đến đây bác đã hiểu ý đồ của em rồi : Nó không dùng cho một TH cụ thể, ta chỉ cần khai báo 2 tham số đó (lấy ra từ texbox) là OK rồi, không phụ thuộc và độ dài của mã chứng từ.

Vì lúc đầu em nghĩ đơn giản là nó tính toán trong cột hiện hành, nhưng sau nghĩ lại là nó có thể tính trong vùng khác. Vì vậy em mới có hàm thứ 2. Bác xem lại nhé.


Còn cái thứ 2 : Nếu dò ngược từ dưới lên cũng được, tuy nhiên chỉ có tác dụng nhanh hơn khi dữ liệu đã được Sort theo thứ tự phiếu. Còn nếu lộn xộn (sort theo 1 chỉ tiêu khác chẳng hạn) thì cũng chẳng hơn gì cả.

Bác OK chứ ??

Thân!
 
Upvote 0
@ThuNghi & MrOkeBap

em định gắn cái hàm của bác Bap vào form cho anh ThuNghi, nhưng hình như cái hàm đó nó làm sai ý đồ rồi phải không anh ThuNghi? Số CT nó nhảy khác? Hay em gắn sai? hay bác MrOkeBap chưa đọc hết cái ý đồ của anh ThuNghi????
 
Upvote 0
SoiBien đã viết:
@ThuNghi & MrOkeBap

em định gắn cái hàm của bác Bap vào form cho anh ThuNghi, nhưng hình như cái hàm đó nó làm sai ý đồ rồi phải không anh ThuNghi? Số CT nó nhảy khác? Hay em gắn sai? hay bác MrOkeBap chưa đọc hết cái ý đồ của anh ThuNghi????
Do mình chưa hiểu hết về VBA nên mới ra cớ sự như vậy.

Đây là hàm :

PHP:
Function CTMax(Vung As Range, KT As String, SoKT As Byte) As String
    On Error Resume Next
    Dim i As Long
    Dim CT As Range
    For Each CT In Vung
        CT.Select
        If Left$(CT.Value, Len(KT)) = KT Then
        If IsNumeric(Val(Right$(CT.Value, SoKT))) = True Then
            If Val(Right$(CT.Value, SoKT)) > i Then i = Val(Right$(CT.Value, SoKT)): MsgBox i
        End If: End If
    Next
    CTMax = KT & Format(i + 1, "000")
    Set CT = Nothing
    Set Vung = Nothing
End Function
Khi nó hoạt độnh ở sheet thì làm việc rất tốt
VD : A1 = CTMax(E2:E100;"PT07/10/";3)

Tuy nhiên trong VBA thì lại không dùng được.

VD : = CTMax(Sheet1.Range("E2:E100"),"PT07/10/",3)

Thì nó báo lỗi ngay ở vòng lặp For each

Như vậy có nghĩa là mình khai báo Vung đã sai (mình khai báo là Range)
Vậy thì khai báo thế nào để dùng ở VBA bình thường nhỉ ???????
Tức là nó hiểu Sheet1.Range("E2:E100") là 1 range bình thường nhỉ ???

Mong mọi người giúp đỡ.


Thân!

P/S : Hiện tại vẫn có thể dùng hàm này, tuy nhiên phải dùng 1 cell khác để tạm thời.
 
Upvote 0
Cực chẳng đã mới dùng thế này (vì chưa giải quyết được vấn đề trên)
Các bác tham khảo

Thân!
 

File đính kèm

Upvote 0
Bác SoiBien xem lại cách xác định vị trí con trỏ trong textbox ngày nhé. Nhập tháng >9 thì sẽ bị sai đấy.

Thân!
 
Upvote 0
Bác Bap vẫn thử coi lại cái cách đánh số CT của anh ThuNghi, vì ddk đánh số còn phụ thuộc vào SoCTGoc nữa, không chỉ phụ thuộc vào LoaiCT & Year & Month !!!!
Thân.
Ặc, sorry, chắc bác ThuNghi đã đổi cách đánh số chứng từ sang cách mới, không dùng cách cũ nữa.

Còn vụ sai kia! kẹt nhỉ, hì hì, để nghiên cứu lại. Làm sao để biết mình đang đi lùi hay tới, chắc phải thêm một biến public hả ta????
 
Lần chỉnh sửa cuối:
Upvote 0
SoiBien đã viết:
Còn vụ sai kia! kẹt nhỉ, hì hì, để nghiên cứu lại. Làm sao để biết mình đang đi lùi hay tới, chắc phải thêm một biến public hả ta????

PHP:
Private Sub TBNgayCT_Change()
    Dim i1 As Byte
    Me.TBNgayCT.Value = ED(Me.TBNgayCT.Value)
    i1 = InStr(1, Me.TBNgayCT.Value, "_")
    If i1 = 0 Then i1 = 11
    Me.TBNgayCT.selstart = i1 - 1
End Sub

Cách này không được hả bác ???


Thân!
 
Upvote 0
Web KT

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

Back
Top Bottom