Sau 1 tháng Mã Lại reset về 1 trở lên (1 người xem)

Liên hệ QC

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

Tôi tuân thủ nội quy khi đăng bài
Em có code tạo mã theo ngày chạy được,các bác ghé qua giúp em như tiêu đề nhé!
Tôi không biết dùng Range.Find nên dùng cách duyệt mảng.

JavaScript:
Function TaomaCT(maCT As String) As String
    Dim lrow As Long, arrData(), i As Long
    Dim nam As Long, thang As Long, stt As Long, sttMax As Long, maCT_tk As String, maCTMoi As String

    lrow = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row
    arrData = Sheets("Sheet1").Range("A2:A" & lrow).Value
    curyear = Year(Date): curmonth = Month(Date)
    'curyear = Sheet1.Range("E2"): curmonth = Sheet1.Range("D2") '<-- testing
    sttMax = 1
    For i = 1 To UBound(arrData)
        nam = CLng("20" & Left(arrData(i, 1), 2)): thang = CLng(Mid(arrData(i, 1), 3, 2)): stt = CLng(Right(arrData(i, 1), 3))
        maCT_tk = Mid(arrData(i, 1), 8, 1)
        If nam = curyear And thang = curmonth And maCT_tk = UCase(maCT) Then
            If stt > sttMax Then sttMax = stt
        End If
    Next
    TaomaCT = Format(Date, "yymmdd-") & UCase(maCT) & Right("000" & sttMax + 1, 3)
    'TaomaCT = Format(DateSerial(curyear, curmonth, Day(Date)), "yymmdd-") & UCase(maCT) & Right("000" & sttMax + 1, 3) '<-- testing
End Function
 
Lần chỉnh sửa cuối:
Tôi không biết dùng Range.Find nên dùng cách duyệt mảng.

JavaScript:
Function TaomaCT(maCT As String) As String
    Dim lrow As Long, arrData(), i As Long
    Dim nam As Long, thang As Long, stt As Long, sttMax As Long, maCT_tk As String, maCTMoi As String

    lrow = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row
    arrData = Sheets("Sheet1").Range("A2:A" & lrow).Value
    curyear = Year(Date): curmonth = Month(Date)
    'curyear = Sheet1.Range("E2"): curmonth = Sheet1.Range("D2") '<-- testing
    sttMax = 1
    For i = 1 To UBound(arrData)
        nam = CLng("20" & Left(arrData(i, 1), 2)): thang = CLng(Mid(arrData(i, 1), 3, 2)): stt = CLng(Right(arrData(i, 1), 3))
        maCT_tk = Mid(arrData(i, 1), 8, 1)
        If nam = curyear And thang = curmonth And maCT_tk = UCase(maCT) Then
            If stt > sttMax Then sttMax = stt
        End If
    Next
    TaomaCT = Format(Date, "yymmdd-") & UCase(maCT) & Right("000" & sttMax + 1, 3)
    'TaomaCT = Format(DateSerial(curyear, curmonth, Day(Date)), "yymmdd-") & UCase(maCT) & Right("000" & sttMax + 1, 3) '<-- testing
End Function
Xin cảm ơn anh đã giúp nhé! em mới học nên còn mù mờ lắm, anh gửi cả file cho em tham khảo được không?
 
Mình đi nhờ Copilot đây:

Viết giúp mình macro sự kiện để khi nhập N hay X ở cột 'Loại'thì cột mã phiếu sẽ được macro điền tiếp mã phiếu theo qui tắc được ghi ở cột cuối

1755183398897.png


Tuyệt vời! Mình sẽ giúp bạn viết một macro sự kiện Worksheet_Change để tự động điền mã phiếu khi bạn nhập N hoặc X vào cột Loại. Macro này sẽ dựa trên:

Quy tắc tạo mã phiếu​

  • Ký tự đầu: E nếu năm là 2025, F nếu là 2026...
  • Ký tự thứ hai: mã tháng (ví dụ: 8 cho tháng 8, 9 cho tháng 9)
  • Ký tự thứ ba: N hoặc X theo loại
  • Số thứ tự: tăng dần theo từng loại trong cùng tháng

Cấu trúc bảng (giả định)​

CộtTên cộtVị trí
ASTT1
BNgày2
CLoại3
DMã Phiếu4
EGhi chú5

Mã VBA: Gắn vào Sheet chứa dữ liệu​

Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim r As Long
    Dim loai As String, ngay As Date
    Dim namMa As String, thangMa As String, loaiMa As String
    Dim soThuTu As Long, maPhieu As String
    Dim ws As Worksheet
    Set ws = Me

    ' Kiểm tra nếu thay đổi ở cột Loại (C)
    If Not Intersect(Target, ws.Range("C2:C1000")) Is Nothing Then
        Application.EnableEvents = False
     
        For Each cell In Intersect(Target, ws.Range("C2:C1000"))
            r = cell.Row
            loai = UCase(cell.Value)
         
            ' Chỉ xử lý nếu là N hoặc X
            If loai = "N" Or loai = "X" Then
                If IsDate(ws.Cells(r, 2).Value) Then
                    ngay = ws.Cells(r, 2).Value
                 
                    ' Tạo mã năm: E = 2025, F = 2026, G = 2027...
                    namMa = Chr(Asc("E") + Year(ngay) - 2025)
                 
                    ' Mã tháng: số nguyên
                    thangMa = Month(ngay)
                 
                    ' Loại mã: N hoặc X
                    loaiMa = loai
                 
                    ' Đếm số phiếu cùng tháng và loại trước đó
                    soThuTu = 0
                    For i = 2 To r - 1
                        If IsDate(ws.Cells(i, 2).Value) Then
                            If Month(ws.Cells(i, 2).Value) = Month(ngay) And _
                               Year(ws.Cells(i, 2).Value) = Year(ngay) And _
                               UCase(ws.Cells(i, 3).Value) = loai Then
                                soThuTu = soThuTu + 1
                            End If
                        End If
                    Next i
                 
                    ' Tăng số thứ tự lên 1
                    soThuTu = soThuTu + 1
                 
                    ' Ghép mã phiếu
                    maPhieu = namMa & thangMa & loaiMa & Format(soThuTu, "000")
                 
                    ' Ghi vào cột Mã Phiếu (D)
                    ws.Cells(r, 4).Value = maPhieu
                End If
            End If
        Next cell
     
        Application.EnableEvents = True
    End If
End Sub

✅ Cách sử dụng​

  1. Mở Excel → nhấn Alt + F11 để vào VBA Editor
  2. Chọn sheet chứa bảng dữ liệu → dán đoạn code vào khung Worksheet Code
  3. Quay lại Excel → nhập N hoặc X vào cột Loại → cột Mã Phiếu sẽ tự động điền theo quy tắc

Bạn muốn mở rộng thêm để tự động ghi chú, kiểm tra trùng lặp, hay lọc theo ngày không? Mình có thể “chế” tiếp theo ý bạn
 
Bác nào ghé giúp sửa code của em với! Code của bác

ongke0711 em chưa học tới
 

File đính kèm

  • DdownGianr.png
    DdownGianr.png
    9.2 KB · Đọc: 4
Lần chỉnh sửa cuối:
Mình đi nhờ Copilot đây:

Viết giúp mình macro sự kiện để khi nhập N hay X ở cột 'Loại'thì cột mã phiếu sẽ được macro điền tiếp mã phiếu theo qui tắc được ghi ở cột cuối

View attachment 309292


Tuyệt vời! Mình sẽ giúp bạn viết một macro sự kiện Worksheet_Change để tự động điền mã phiếu khi bạn nhập N hoặc X vào cột Loại. Macro này sẽ dựa trên:

Quy tắc tạo mã phiếu​

  • Ký tự đầu: E nếu năm là 2025, F nếu là 2026...
  • Ký tự thứ hai: mã tháng (ví dụ: 8 cho tháng 8, 9 cho tháng 9)
  • Ký tự thứ ba: N hoặc X theo loại
  • Số thứ tự: tăng dần theo từng loại trong cùng tháng

Cấu trúc bảng (giả định)​

CộtTên cộtVị trí
ASTT1
BNgày2
CLoại3
DMã Phiếu4
EGhi chú5

Mã VBA: Gắn vào Sheet chứa dữ liệu​

Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim r As Long
    Dim loai As String, ngay As Date
    Dim namMa As String, thangMa As String, loaiMa As String
    Dim soThuTu As Long, maPhieu As String
    Dim ws As Worksheet
    Set ws = Me

    ' Kiểm tra nếu thay đổi ở cột Loại (C)
    If Not Intersect(Target, ws.Range("C2:C1000")) Is Nothing Then
        Application.EnableEvents = False
    
        For Each cell In Intersect(Target, ws.Range("C2:C1000"))
            r = cell.Row
            loai = UCase(cell.Value)
        
            ' Chỉ xử lý nếu là N hoặc X
            If loai = "N" Or loai = "X" Then
                If IsDate(ws.Cells(r, 2).Value) Then
                    ngay = ws.Cells(r, 2).Value
                
                    ' Tạo mã năm: E = 2025, F = 2026, G = 2027...
                    namMa = Chr(Asc("E") + Year(ngay) - 2025)
                
                    ' Mã tháng: số nguyên
                    thangMa = Month(ngay)
                
                    ' Loại mã: N hoặc X
                    loaiMa = loai
                
                    ' Đếm số phiếu cùng tháng và loại trước đó
                    soThuTu = 0
                    For i = 2 To r - 1
                        If IsDate(ws.Cells(i, 2).Value) Then
                            If Month(ws.Cells(i, 2).Value) = Month(ngay) And _
                               Year(ws.Cells(i, 2).Value) = Year(ngay) And _
                               UCase(ws.Cells(i, 3).Value) = loai Then
                                soThuTu = soThuTu + 1
                            End If
                        End If
                    Next i
                
                    ' Tăng số thứ tự lên 1
                    soThuTu = soThuTu + 1
                
                    ' Ghép mã phiếu
                    maPhieu = namMa & thangMa & loaiMa & Format(soThuTu, "000")
                
                    ' Ghi vào cột Mã Phiếu (D)
                    ws.Cells(r, 4).Value = maPhieu
                End If
            End If
        Next cell
    
        Application.EnableEvents = True
    End If
End Sub

✅ Cách sử dụng​

  1. Mở Excel → nhấn Alt + F11 để vào VBA Editor
  2. Chọn sheet chứa bảng dữ liệu → dán đoạn code vào khung Worksheet Code
  3. Quay lại Excel → nhập N hoặc X vào cột Loại → cột Mã Phiếu sẽ tự động điền theo quy tắc

Bạn muốn mở rộng thêm để tự động ghi chú, kiểm tra trùng lặp, hay lọc theo ngày không? Mình có thể “chế” tiếp theo ý bạn
file của em chỉ có cột ngày thôi anh!
 
Xin cảm ơn anh đã giúp nhé! em mới học nên còn mù mờ lắm, anh gửi cả file cho em tham khảo được không?

Bạn xem file đính kèm.
File này của bạn chỉ test chơi thôi chứ thực tế không thiết kế kiểu vậy được.
Bạn phải vẽ ra được cái qui trình nhập liệu thực tế, các tham số nào cần đưa vào (như loại CT, ngày CT...) sau đó dựa 2 tham số đó mà tạo phiếu. Như kiểu bác SA đã gợi ý đó.
 

File đính kèm

file của em chỉ có cột ngày thôi anh!
Nhưng trong mả hóa đơn lại phải chứa tác vụ nhập hay xuất riêng biệt mà, phải không!
Làm sao chương trình nó biết rằng bạn đang 'N' hay 'X'!
Ngoài lề 1 chút để rõ ý của mình:
Trong mã ta chỉ cần mã hóa năm & tháng; Vì 1 điều hiễn nhiên là sau mỗi tháng bạn lại bắt đầu lại số thứ tự nhập hay xuất mà!
[1 điều có thể quan tấm là hóa đơn đầu tháng mười (Tháng 11 :=B & tháng 12 :=C) có thể là EAN000 hay EAX000 (xuất)
chứ không nhất thiết phải là 001]
 
File của bạn này phụ thuộc vào 1 ô ngày,tháng năm để tạo mã,là tạo mã theo ngày,hết tháng là chốt. Đúng không bạn?
Đúng rồi anh,file của em cần thêm sub nhỏ là tạo được các mã theo yêu cầu.
Bài đã được tự động gộp:

Nhưng trong mả hóa đơn lại phải chứa tác vụ nhập hay xuất riêng biệt mà, phải không!
Làm sao chương trình nó biết rằng bạn đang 'N' hay 'X'!
Ngoài lề 1 chút để rõ ý của mình:
Trong mã ta chỉ cần mã hóa năm & tháng; Vì 1 điều hiễn nhiên là sau mỗi tháng bạn lại bắt đầu lại số thứ tự nhập hay xuất mà!
[1 điều có thể quan tấm là hóa đơn đầu tháng mười (Tháng 11 :=B & tháng 12 :=C) có thể là EAN000 hay EAX000 (xuất)
chứ không nhất thiết phải là 001]
Mã của em phụ thuộc vào 1 ô ngày,tháng,năm.Còn mã nhập xuất là thêm vào theo sub nhỏ.Em đang tìm hiểu code hết ngày,hết tuần,hết tháng và hết năm thì reset lại từ đầu.Anh biết chỉ em với!
 
Lần chỉnh sửa cuối:
Bạn xem file đính kèm.
File này của bạn chỉ test chơi thôi chứ thực tế không thiết kế kiểu vậy được.
Bạn phải vẽ ra được cái qui trình nhập liệu thực tế, các tham số nào cần đưa vào (như loại CT, ngày CT...) sau đó dựa 2 tham số đó mà tạo phiếu. Như kiểu bác SA đã gợi ý đó.
Cám ơn anh đã giúp! em test file sang tháng 9 thì mã tạo là 002 trở lên (đúng là 001) và xoá hết cột A thì code báo lỗi
 

File đính kèm

  • ChuwaDdungs.png
    ChuwaDdungs.png
    11.8 KB · Đọc: 4
Em có code tạo mã theo ngày chạy được,các bác ghé qua giúp em như tiêu đề nhé!
Số phiếu có số thứ tự liên tục, tháng sau sẽ đánh từ 001
Mã:
Sub NewPhieuNX(MaPhieu)
  Dim arr(), t$, eR&, i&, sp$, myDate As Date
 
  myDate = Date
  t = Format(myDate, "yymm??-") & MaPhieu
  eR = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
  arr = Sheet1.Range("A1:B" & eR).Value
  For i = UBound(arr) To 1 Step -1
    If Mid(arr(i, 1), 1, 8) Like t Then
      sp = Format(myDate, "yymmdd-") & MaPhieu & Format(Right(arr(i, 1), 3) + 1, "000")
      Exit For
    End If
  Next i
  If i = 0 Then sp = Format(myDate, "yymmdd-") & MaPhieu & "001"
  Sheet1.Range("A" & eR + 1).Value = sp
End Sub
 
Số phiếu có số thứ tự liên tục, tháng sau sẽ đánh từ 001
Mã:
Sub NewPhieuNX(MaPhieu)
  Dim arr(), t$, eR&, i&, sp$, myDate As Date
 
  myDate = Date
  t = Format(myDate, "yymm??-") & MaPhieu
  eR = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
  arr = Sheet1.Range("A1:B" & eR).Value
  For i = UBound(arr) To 1 Step -1
    If Mid(arr(i, 1), 1, 8) Like t Then
      sp = Format(myDate, "yymmdd-") & MaPhieu & Format(Right(arr(i, 1), 3) + 1, "000")
      Exit For
    End If
  Next i
  If i = 0 Then sp = Format(myDate, "yymmdd-") & MaPhieu & "001"
  Sheet1.Range("A" & eR + 1).Value = sp
End Sub
Cám ơn anh đã giúp! Anh thêm giúp ngày tháng phụ thuộc vào ô B5 nhé! (Khi ngày ô này sang thứ 2 thì chạy 001 trở lên đến chủ nhật là mã phiếu cuối)
 
Lần chỉnh sửa cuối:
Cám ơn anh đã giúp! em test file sang tháng 9 thì mã tạo là 002 trở lên (đúng là 001) và xoá hết cột A thì code báo lỗi
Sửa lại cái sub TaoMaCT() chút.

JavaScript:
Function TaomaCT(maCT As String) As String
    Dim lrow As Long, arrData(), i As Long
    Dim nam As Long, thang As Long, curYear As Long, curMonth As Long, stt As Long, sttMax As Long, maCT_tk As String, maCTMoi As String
   
    lrow = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row
    curYear = Year(Date): curMonth = Month(Date)
    'curYear = Sheet1.Range("E2"): curMonth = Sheet1.Range("D2") '<-- testing
    Select Case lrow
        Case 1
            sttMax = 0
        Case 2
            sttMax = 1
        Case Else
            arrData = Sheets("Sheet1").Range("A2:A" & lrow).Value
            sttMax = 0
            For i = 1 To UBound(arrData)
                nam = CLng("20" & Left(arrData(i, 1), 2)): thang = CLng(Mid(arrData(i, 1), 3, 2)): stt = CLng(Right(arrData(i, 1), 3))
                maCT_tk = Mid(arrData(i, 1), 8, 1)
                If nam = curYear And thang = curMonth And maCT_tk = UCase(maCT) Then
                    If stt > sttMax Then sttMax = stt
                End If
            Next
    End Select
    TaomaCT = Format(Date, "yymmdd-") & UCase(maCT) & Right("000" & sttMax + 1, 3)
    'TaomaCT = Format(DateSerial(curYear, curMonth, Day(Date)), "yymmdd-") & UCase(maCT) & Right("000" & sttMax + 1, 3) '<-- testing
End Function
Bài đã được tự động gộp:

Số phiếu có số thứ tự liên tục, tháng sau sẽ đánh từ 001
Mã:
Sub NewPhieuNX(MaPhieu)
  ...
  For i = UBound(arr) To 1 Step -1
  
End Sub
Dò ngược lại của bác HieuCD hay nhỉ, bớt được nhiều vòng lặp.
 
Lần chỉnh sửa cuối:
Cám ơn anh đã giúp! Anh thêm giúp ngày tháng phụ thuộc vào ô B5 nhé! (Khi ngày ô này sang thứ 2 thì chạy 001 trở lên đến chủ nhật là mã phiếu cuối)
Chỉnh tí . . . .
Mã:
Sub NewPhieuNX(MaPhieu)
  Dim arr(), t&, eR&, i&, sp$, myDate As Date, w&
 
  myDate = Sheet1.Range("B5").Value
  w = Int((myDate - 2) / 7)
  eR = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
  arr = Sheet1.Range("A1:B" & eR).Value
  For i = UBound(arr) To 2 Step -1
    If Mid(arr(i, 1), 8, 1) = MaPhieu Then
      t = DateValue(20 & Mid(arr(i, 1), 1, 2) & "/" & Mid(arr(i, 1), 3, 2) & "/" & Mid(arr(i, 1), 5, 2))
      If w = Int((t - 2) / 7) Then
        sp = Format(myDate, "yymmdd-") & MaPhieu & Format(Right(arr(i, 1), 3) + 1, "000")
        Exit For
      End If
    End If
  Next i
  If i = 1 Then sp = Format(myDate, "yymmdd-") & MaPhieu & "001"
  Sheet1.Range("A" & eR + 1).Value = sp
End Sub
 
Anh ơi! em test code chạy sai, có phải dùng hàm int trong vba tính không đúng. Nếu được anh bỏ giúp em yy (Chỉ còn mmdd nhé!)
 

File đính kèm

  • ChuwaDdungs.png
    ChuwaDdungs.png
    5.5 KB · Đọc: 4
Sửa lại cái sub TaoMaCT() chút.

JavaScript:
Function TaomaCT(maCT As String) As String
    Dim lrow As Long, arrData(), i As Long
    Dim nam As Long, thang As Long, curYear As Long, curMonth As Long, stt As Long, sttMax As Long, maCT_tk As String, maCTMoi As String
  
    lrow = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row
    curYear = Year(Date): curMonth = Month(Date)
    'curYear = Sheet1.Range("E2"): curMonth = Sheet1.Range("D2") '<-- testing
    Select Case lrow
        Case 1
            sttMax = 0
        Case 2
            sttMax = 1
        Case Else
            arrData = Sheets("Sheet1").Range("A2:A" & lrow).Value
            sttMax = 0
            For i = 1 To UBound(arrData)
                nam = CLng("20" & Left(arrData(i, 1), 2)): thang = CLng(Mid(arrData(i, 1), 3, 2)): stt = CLng(Right(arrData(i, 1), 3))
                maCT_tk = Mid(arrData(i, 1), 8, 1)
                If nam = curYear And thang = curMonth And maCT_tk = UCase(maCT) Then
                    If stt > sttMax Then sttMax = stt
                End If
            Next
    End Select
    TaomaCT = Format(Date, "yymmdd-") & UCase(maCT) & Right("000" & sttMax + 1, 3)
    'TaomaCT = Format(DateSerial(curYear, curMonth, Day(Date)), "yymmdd-") & UCase(maCT) & Right("000" & sttMax + 1, 3) '<-- testing
End Function
Bài đã được tự động gộp:


Dò ngược lại của bác HieuCD hay nhỉ, bớt được nhiều vòng lặp.
Cám ơn anh đã giúp! Anh thêm giúp ngày tháng phụ thuộc vào ô B5 nhé! Cứ sau 1 tuần thì mã reset về 001 đém lên. Nếu được bác bỏ 2 ký tự yy (chỉ còn mmdd nhé!)
 
. . . . là code chạy đúng rồi. Anh bỏ giúp em yy (Chỉ còn mmdd nhé!) Mã bớt đi 2 ký tự ưa nhìn hơn.
:D
Nếu bạn muốn thì mình sẽ giúp chuyện mã hóa ngày tháng năm còn 3 ký tự dạng YMD;
Ví dụ E9A := ngày 10 tháng 9 năm 2025;
& FAC:= ngày 12 tháng mười năm sau
Bằng hàm VBA hay băng Name trên trang Excel đều được!?
:D
 
Dữ liệu dùng cho 1 năm hay nhiều năm?
giữ liệu dùng cho nhiều năm, Anh có cách nào bớt ký tự mã đi không vậy? Giúp em nhé!
Bài đã được tự động gộp:

:D
Nếu bạn muốn thì mình sẽ giúp chuyện mã hóa ngày tháng năm còn 3 ký tự dạng YMD;
Ví dụ E9A := ngày 10 tháng 9 năm 2025;
& FAC:= ngày 12 tháng mười năm sau
Bằng hàm VBA hay băng Name trên trang Excel đều được!?
:D
Bằng hàm VBA đi anh! Chuyển mã hoá rất hay đó anh,cảm ơn anh
 
Lần chỉnh sửa cuối:
giữ liệu dùng cho nhiều năm, Anh có cách nào bớt ký tự mã đi không vậy? Giúp em nhé!
Bài đã được tự động gộp:


Bằng hàm VBA đi anh! Chuyển mã hoá rất hay đó anh,cảm ơn anh
Bỏ "YY" mã chứng từ sẽ bị trùng qua các năm, cần xét thêm cột ngày tháng, kết hợp 2 cột làm vùng khóa chính của cơ sở dữ liệu.
 

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

Back
Top Bottom