Xin code lấy ngày tháng năm trong chuỗi.

Liên hệ QC

HUONGHCKT

Zalo 0986997214
Tham gia
30/8/12
Bài viết
1,571
Được thích
2,779
Donate (Paypal)
Donate
Donate (Momo)
Donate
Giới tính
Nam
Xin chào tất cả các anh chị em. Tôi có viết đoạn code để tách lấy ngày tháng năm trong một chuỗi nhưng kết quả trả về không được như ý.
Nhưng nếu các ngày là nhỏ hơn hoặc bằng 12 thì nó lại ra là 10/.../2021 còn nếu ngày lớn hơn 12 thì kết quả trả về là ...../10/2021....
Ví dụ : tôi có chuỗi : Thứ hai, ngày 14 tháng 10 năm 2021 Tôi muốn thu được kết quả là: 14/10/2021 .
Nhưng nếu là Thứ hai, ngày 04 tháng 10 năm 2021 thì kết quả trả về lại là 03/01/1900/10/2021, trong khi tôi muốn thu được là 04/10/2021.
Kính mong anh chị em nào biết xin được bày vẽ cho tôi: đoạn code trên sai ở chỗ nào? phải sửa lại thế nào cho đúng (nếu có thể giải thuật code thì càng tốt)
Trân trọng!
Mã:
Option Explicit

Sub TachLayNgay()
Dim i&, j&, k&
Dim S, Temp
With Sheets("Sheet1")
    .Range("H5:H100").ClearContents
For j = 5 To 13
Temp = .Cells(j, 1)
S = Split(Temp, " ")
For i = 0 To UBound(S)
    If IsNumeric(S(i)) Then
        If .Cells(j, 8) = Empty Then
            .Cells(j, 8).Value = S(i)
        Else
            .Cells(j, 8).Value = .Cells(j, 8).Value & "/" & S(i)
        End If
    End If
Next i
Erase S
Next j
End With
End Sub
 

File đính kèm

  • tach ngay thang trong chuôi.xlsm
    19.8 KB · Đọc: 29
cấu trúc dữ liệu của anh lúc nào cũng như thế kia ạ. có trường hợp nào khác lạ không. ý tưởng là sẽ xét từng ô. tìm kiếm số sau chữ ngày, Tháng , năm để lấy ra các con số
 
Xin chào tất cả các anh chị em. Tôi có viết đoạn code để tách lấy ngày tháng năm trong một chuỗi nhưng kết quả trả về không được như ý.
Nhưng nếu các ngày là nhỏ hơn hoặc bằng 12 thì nó lại ra là 10/.../2021 còn nếu ngày lớn hơn 12 thì kết quả trả về là ...../10/2021....
Ví dụ : tôi có chuỗi : Thứ hai, ngày 14 tháng 10 năm 2021 Tôi muốn thu được kết quả là: 14/10/2021 .
Nhưng nếu là Thứ hai, ngày 04 tháng 10 năm 2021 thì kết quả trả về lại là 03/01/1900/10/2021, trong khi tôi muốn thu được là 04/10/2021.
Kính mong anh chị em nào biết xin được bày vẽ cho tôi: đoạn code trên sai ở chỗ nào? phải sửa lại thế nào cho đúng (nếu có thể giải thuật code thì càng tốt)
Trân trọng!
Mã:
Option Explicit

Sub TachLayNgay()
Dim i&, j&, k&
Dim S, Temp
With Sheets("Sheet1")
    .Range("H5:H100").ClearContents
For j = 5 To 13
Temp = .Cells(j, 1)
S = Split(Temp, " ")
For i = 0 To UBound(S)
    If IsNumeric(S(i)) Then
        If .Cells(j, 8) = Empty Then
            .Cells(j, 8).Value = S(i)
        Else
            .Cells(j, 8).Value = .Cells(j, 8).Value & "/" & S(i)
        End If
    End If
Next i
Erase S
Next j
End With
End Sub
sao bạn không dùng công thức, nếu dữ liệu nhập đồng nhất như này
 
Xin chào tất cả các anh chị em. Tôi có viết đoạn code để tách lấy ngày tháng năm trong một chuỗi nhưng kết quả trả về không được như ý.
Nhưng nếu các ngày là nhỏ hơn hoặc bằng 12 thì nó lại ra là 10/.../2021 còn nếu ngày lớn hơn 12 thì kết quả trả về là ...../10/2021....
Ví dụ : tôi có chuỗi : Thứ hai, ngày 14 tháng 10 năm 2021 Tôi muốn thu được kết quả là: 14/10/2021 .
Nhưng nếu là Thứ hai, ngày 04 tháng 10 năm 2021 thì kết quả trả về lại là 03/01/1900/10/2021, trong khi tôi muốn thu được là 04/10/2021.
Kính mong anh chị em nào biết xin được bày vẽ cho tôi: đoạn code trên sai ở chỗ nào? phải sửa lại thế nào cho đúng (nếu có thể giải thuật code thì càng tốt)
Trân trọng!
Mã:
Option Explicit

Sub TachLayNgay()
Dim i&, j&, k&
Dim S, Temp
With Sheets("Sheet1")
    .Range("H5:H100").ClearContents
For j = 5 To 13
Temp = .Cells(j, 1)
S = Split(Temp, " ")
For i = 0 To UBound(S)
    If IsNumeric(S(i)) Then
        If .Cells(j, 8) = Empty Then
            .Cells(j, 8).Value = S(i)
        Else
            .Cells(j, 8).Value = .Cells(j, 8).Value & "/" & S(i)
        End If
    End If
Next i
Erase S
Next j
End With
End Sub
Gán kết qủa nhiều lần vào 1 ô excel tốc độ sẽ chậm và excel có thể tự động chuyển dạng dữ liệu làm sai kết quả, nên tạo biến kết quả và gán vào sheet 1 lần
Xử lý ngày tháng từ dạng chuỗi thường dùng hàm datevalue
 
' dùng hàm DateSerial để tránh VBA mặc định vị trí ngày tháng năm trong chuỗi "xx/yy/zzzz"

Dim ntn(1 To 3) ' phần tử 1 là ngày, 2 là tháng, 3 là năm
viTri = 0
For Each e In Split(.Cells(j, 1))
If IsNumeric(e) Then
viTri = viTri + 1
ntn(viTri) = CLng(e)
If viTri >= 3 Then ' đủ 3 số rồi, tính ngày
.Cells(j, 8).Value = DateSerial(ntn(3), ntn(2), ntn(1))
Exit For
End If
End If
Next i

Chú thích: code Wtih Sheets(...) là loại code nguy hiểm. Thứ nhất là khó copy paste sang chỗ khác. Thư shai là gõ thiếu dấu chấm sẽ hỏng hết.
1. chỉ sử dụng nó cho 1-3 dòng thôi
2. nhiều dòng hơn thì nên dùng Set sh = ...
 
Anh thử code cùi bắp này coi thế nào. Đúng với dữ kiệu trong file của anh thôi
Mà thế nào cái cột mong muốn em thấy nó không giống là sao ta
Mã:
Sub ABC()
    Dim Arr(), Res(), i&
    With Sheet1
        Arr = .Range("A5:A12").Value
        ReDim Res(1 To UBound(Arr, 1), 1 To 1)
        For i = 1 To UBound(Arr, 1)
            Res(i, 1) = Mid(Arr(i, 1), InStr(Arr(i, 1), "ngày"), 25)
            Res(i, 1) = Replace(Res(i, 1), "ngày ", "")
            Res(i, 1) = Replace(Res(i, 1), " tháng ", "/")
            Res(i, 1) = Replace(Res(i, 1), [A1], "/")
        Next
        .Range("H5").Resize(UBound(Arr, 1)) = Res
    End With
End Sub
 

File đính kèm

  • tach ngay thang trong chuôi.xlsb
    17.7 KB · Đọc: 10
cấu trúc dữ liệu của anh lúc nào cũng như thế kia ạ. có trường hợp nào khác lạ không. ý tưởng là sẽ xét từng ô. tìm kiếm số sau chữ ngày, Tháng , năm để lấy ra các con số
cấu trúc dữ liệu thật cũng là như vậy chỉ khác vị trí ô. Nhìn chung là trước và sau đoạn ngày tháng năm có một số chuỗi nữa. Đoạn code trên được trích trong một sub dài hơn, dùng để lấy dữ liệu của rất nhiều (trên dưới 200 file có cấu trúc giống nhau)về 1 file thành trên dưới 200 cái sheet (mỗi file kia được lấy thành 1 sheet) .Tôi muốn trích ra ngày tháng năm để lấy đó đặt tên lại cho sheet vừa mới tạo thành.
Bài đã được tự động gộp:

' dùng hàm DateSerial để tránh VBA mặc định vị trí ngày tháng năm trong chuỗi "xx/yy/zzzz"

Dim ntn(1 To 3) ' phần tử 1 là ngày, 2 là tháng, 3 là năm
viTri = 0
For Each e In Split(.Cells(j, 1))
If IsNumeric(e) Then
viTri = viTri + 1
ntn(viTri) = CLng(e)
If viTri >= 3 Then ' đủ 3 số rồi, tính ngày
.Cells(j, 8).Value = DateSerial(ntn(3), ntn(2), ntn(1))
Exit For
End If
End If
Next i

Chú thích: code Wtih Sheets(...) là loại code nguy hiểm. Thứ nhất là khó copy paste sang chỗ khác. Thư shai là gõ thiếu dấu chấm sẽ hỏng hết.
1. chỉ sử dụng nó cho 1-3 dòng thôi
2. nhiều dòng hơn thì nên dùng Set sh = ...
Cảm ơn anh đã chỉ giáo, để tôi thử làm lại theo cách của anh.
 
Lần chỉnh sửa cuối:
' dùng hàm DateSerial để tránh VBA mặc định vị trí ngày tháng năm trong chuỗi "xx/yy/zzzz"

Dim ntn(1 To 3) ' phần tử 1 là ngày, 2 là tháng, 3 là năm
viTri = 0
For Each e In Split(.Cells(j, 1))
If IsNumeric(e) Then
viTri = viTri + 1
ntn(viTri) = CLng(e)
If viTri >= 3 Then ' đủ 3 số rồi, tính ngày
.Cells(j, 8).Value = DateSerial(ntn(3), ntn(2), ntn(1))
Exit For
End If
End If
Next i

Chú thích: code Wtih Sheets(...) là loại code nguy hiểm. Thứ nhất là khó copy paste sang chỗ khác. Thư shai là gõ thiếu dấu chấm sẽ hỏng hết.
1. chỉ sử dụng nó cho 1-3 dòng thôi
2. nhiều dòng hơn thì nên dùng Set sh = ...
Một lần nữa xin đượccảm ơn anh. Tôi đã làm được bằng code của anh.
Mã:
Option Explicit

Sub TachLayNgay1()

Dim j&, vitri&
Dim Temp
Dim ntn(1 To 3) ' ph?n t? 1 là ngày, 2 là tháng, 3 là năm
Dim e As Variant
Dim Sh As Worksheet
Set Sh = Sheets("Sheet1")

For j = 5 To 13
    vitri = 0
    For Each e In Split(Sh.Cells(j, 1))
        If IsNumeric(e) Then
            vitri = vitri + 1
                ntn(vitri) = CLng(e)
                    If vitri >= 3 Then ' đ? 3 s? r?i, tính ngày
                        Sh.Cells(j, 7).Value = DateSerial(ntn(3), ntn(2), ntn(1))
                            Exit For
                    End If
        End If
    Next e
Next j
End Sub
 
Lần chỉnh sửa cuối:
Sinh nhật Giải pháp Excel lần thứ 15 vào Thứ sáu, ngày 02 tháng 07 năm 2021.
Cảm ơn Anh đã ghé qua và xem bài.
Tôi có khoảng gần 200 file có cấu trúc giống nhau do tải trên phần mềm về. Trong mỗi file chỉ có 1 sheet (tên Sh cũng giống nhau) và trong sheet ấy chỉ có 1 ô chứa ngày tháng năm (kiểu Hôm nay, Thứ sáu ( sáu chứ không phải 6) ngày 04 tháng 11 năm 2021.
Nhiệm vụ của code tôi viết là Tìm 200 cái file ấy (tên file có dạng: xxxx Excel5.xlsx). copy Sh duy nhất ấy (tạm gọi là Sh Nguon);==>tạo sheet mới (trong Workbook chứa code) và Paste vào Sheet mới ấy; Xử lý dữ liệu; tách lấy ngày tháng của cái sheet Nguon để đặt tên cho Sheet mới (Tên mới là: N04T11....), Tiếp theo là định dạng và in ấn. Tiếp tục vòng lặp tìm file tiếp theo....cứ thế đến hết. Nhờ có sự chỉ giúp của các anh mà tôi đã viết được code chạy cho ra được kết quả đúng yêu cầu. Tuy Code này chạy cho ra được kết quả nhưng cũng phải chờ dài dài (3-5 phút)
Mong muốn của tôi là, có anh chị em có ghé qua xem bài , xem code (đính kèm bên dưới) và cho góp ý (hoặc sửa code, hoặc ....) để tôi hoàn thiện hơn.
Trân trọng cảm ơn anh chị em.
Mã:
Option Explicit
Sub Bsung()
Dim Lr&, i&, J&, R&, t&, TongN&, Vitri&, tt&, kk&
Dim Arr(), KQ(), NCC(), ntn(1 To 3), e, N
Dim fso As Object, Dic As Object, DicT As Object
Dim NWs As Worksheet, WbMoi As Workbook, Ws As Worksheet
Dim Keys As String
Dim file As Variant

 Application.ScreenUpdating = False
 Application.DisplayAlerts = False
 
Set Dic = CreateObject("Scripting.Dictionary")
Set fso = CreateObject("Scripting.FileSystemObject")

ReDim NCC(1 To 100, 1 To 3)
Sheets("DMHH").Select
For J = 1 To Sheets("DMHH").Cells(Rows.Count, 1).End(xlUp).Row
    Keys = Sheets("DMHH").Cells(J, 1)
    If Not Dic.exists(Keys) Then
        t = t + 1: Dic.Add (Keys), t
        NCC(t, 1) = Keys
        NCC(t, 2) = Sheets("DMHH").Cells(J, 2)
        NCC(t, 3) = Sheets("DMHH").Cells(J, 3)
    End If
Next J

ReDim KQ(1 To 100, 1 To 1)
For Each file In CreateObject("Scripting.FileSystemObject").GetFolder("C:\Users\Admin\Downloads\").Files
    If file.Name Like "*Excel5.xls" Then
        Set WbMoi = Workbooks.Open(file)     '======Bi lôi dong này "không tim thây, có thê đa đôi ten, di chuyên hoac đa xoa"
        For Each Ws In WbMoi.Sheets
            If Ws.Name = "TPT" Then
Set DicT = CreateObject("Scripting.Dictionary")
 
'=======Copy sheet nguon=========='
            Ws.Select
            Ws.Range("A1:Q30").Copy
        
'=========paste xuông Sheet============'

            Windows("TONGHOP DULIEU NHAP TP (DDMN).xlsm").Activate
            Sheets.Add After:=ActiveSheet
            ActiveSheet.Paste
            Set NWs = ActiveSheet
        WbMoi.Close
    
'===========tach lay ngay tháng============'
Vitri = 0: kk = 0: tt = 0
    For Each e In Split(NWs.Cells(5, 1))
        If IsNumeric(e) Then
            Vitri = Vitri + 1
                ntn(Vitri) = CLng(e)
                    If Vitri >= 3 Then ' đ? 3 s? r?i, tính ngày
                        N = DateSerial(ntn(3), ntn(2), ntn(1))
                            Exit For
                    End If
        End If
    Next e

'============Lây dư liêu thay thê bô sung=============='
        
            Lr = NWs.Cells(Rows.Count, 1).End(xlUp).Row
            Arr = NWs.Range("A10:O" & Lr).Value
            TongN = 0
            ReDim KQ(1 To UBound(Arr) + 1, 1 To 15)
            For i = 1 To UBound(Arr)
                KQ(i, 1) = Arr(i, 1)
                KQ(i, 2) = Arr(i, 2)
                KQ(i, 3) = Arr(i, 3)
              '  KQ(i, 4) = 8 & "h" & Int(Application.WorksheetFunction.RandBetween(1, 89) / 3) _
                & "p-" & Day(N) & "/" & Month(N)
                KQ(i, 5) = Arr(i, 5)
                KQ(i, 6) = Arr(i, 6)
                KQ(i, 7) = Arr(i, 5) * Arr(i, 6) 'Arr(i, 7) * 1000
                TongN = TongN + Arr(i, 7)
                KQ(i, 8) = "Đat"
                If Dic.exists(Arr(i, 2)) Then
                    KQ(i, 10) = NCC(Dic.Item(Arr(i, 2)), 2)
                    KQ(i, 11) = NCC(Dic.Item(Arr(i, 2)), 3)
                End If
                If Not DicT.exists(KQ(i, 10)) Then
                    tt = tt + 1: DicT.Add (KQ(i, 10)), tt
                    KQ(i, 4) = 8 & "h" & Int(Application.WorksheetFunction.RandBetween(1, 89) / 3) _
                & "p-" & Day(N) & "/" & Month(N)
                Else
                    kk = DicT.Item(KQ(i, 10))
                    KQ(i, 4) = KQ(kk, 4)
                End If
                    KQ(i, 13) = KQ(i, 5)
                    KQ(i, 14) = KQ(i, 6)
                    KQ(i, 15) = KQ(i, 7)
            Next i
            Set DicT = Nothing
               NWs.Name = "N" & Day(N) & "T" & Month(N)
        End If
    
        NWs.Range("A10").Resize(i, 15) = KQ
                NWs.Range("A" & Lr + 1, "P" & Lr + 2).Select
                Selection.UnMerge
                Selection.Font.Size = 10
                Selection.Font.Bold = True
                Selection.NumberFormat = "#,##0"
                'NWs.Range("A" & Lr + 1, "P" & Lr + 2).Font.Size = 10
                NWs.Range("B" & Lr + 1) = "Công"
                NWs.Range("G" & Lr + 1) = TongN
                NWs.Range("O" & Lr + 1) = TongN
                NWs.Range("B" & Lr + 2) = "Băng chư:"
                NWs.Range("C" & Lr + 2).FormulaR1C1 = "=VND(R[-1]C[4])"
                NWs.Range("C" & Lr + 2).HorizontalAlignment = xlLeft
                NWs.Range("O10", "O" & Lr).HorizontalAlignment = xlRight
                NWs.Range("B" & Lr + 2, "C" & Lr + 2).Font.Italic = True
                NWs.Range("B" & Lr + 2, "C" & Lr + 2).Font.Bold = False
                NWs.Range("M" & Lr + 2, "Q" & Lr + 2).ClearContents
                NWs.Range("A7:P16").Font.Size = 10
                NWs.Columns("A:A").ColumnWidth = 2.89
                NWs.Columns("B:B").ColumnWidth = 9.78
                NWs.Columns("C:C").ColumnWidth = 3.22
                NWs.Columns("D:D").ColumnWidth = 8.22
                NWs.Columns("E:E").ColumnWidth = 4.5
                NWs.Columns("F:F").ColumnWidth = 4.7
                NWs.Columns("G:G").ColumnWidth = 8
                NWs.Columns("H:H").ColumnWidth = 3.67
                NWs.Columns("I:I").ColumnWidth = 3.44
                NWs.Columns("J:J").ColumnWidth = 13.2
                NWs.Columns("K:K").ColumnWidth = 13
                NWs.Columns("L:L").ColumnWidth = 10.11
                NWs.Columns("M:M").ColumnWidth = 4.5
                NWs.Columns("N:N").ColumnWidth = 4.7
                NWs.Columns("O:O").ColumnWidth = 8
                NWs.Columns("P:P").ColumnWidth = 7.11
                NWs.Range("A1").HorizontalAlignment = xlCenter
                NWs.Range("A2").HorizontalAlignment = xlCenter
                NWs.Range("A1").VerticalAlignment = xlCenter
                NWs.Range("A2").VerticalAlignment = xlCenter
                NWs.Range("B10", "B" & Lr).WrapText = True
                NWs.Range("B" & Lr + 3).WrapText = False
                NWs.Range("F" & Lr + 3).WrapText = False
                NWs.Range("B" & Lr + 8).WrapText = False
                NWs.Range("F" & Lr + 8).WrapText = False
                NWs.Range("D10", "D" & Lr).ShrinkToFit = True
                NWs.Range("J10", "L" & Lr).ShrinkToFit = True
Next Ws
End If
Next file

    Call MucLuc

    Sheets("MucLuc").range("A1").Select

Set fso = Nothing
Set Dic = Nothing

Application.ScreenUpdating = True
Application.DisplayAlerts = True

MsgBox " Đa hoàn thành lây bô sung dư liêu các phiêu N-X hàng ngày", vbInformation, "THÔNG BÁO"
End Sub
Còn bài toán của Anh @huuthang_bd nêu trên thì có lẽ phải dùng đến hàm Seach để tìm xem chuỗi "ngày" nằm ở vị trí thứ mấy (thứ n) và sau đó mới chạy vòng lặp For i = n to Ubound(S). với S =Array(Range(....)," ").Rồi sau đó mới là If Isnumeric(S(i) then....
 
Lần chỉnh sửa cuối:
Cảm ơn Anh đã ghé qua và xem bài.
Tôi có khoảng gần 200 file có cấu trúc giống nhau do tải trên phần mềm về. Trong mỗi file chỉ có 1 sheet (tên Sh cũng giống nhau) và trong sheet ấy chỉ có 1 ô chứa ngày tháng năm (kiểu Hôm nay, Thứ sáu ( sáu chứ không phải 6) ngày 04 tháng 11 năm 2021.
Nhiệm vụ của code tôi viết là Tìm 200 cái file ấy (tên file có dạng: xxxx Excel5.xlsx). copy Sh duy nhất ấy (tạm gọi là Sh Nguon);==>tạo sheet mới (trong Workbook chứa code) và Paste vào Sheet mới ấy; Xử lý dữ liệu; tách lấy ngày tháng của cái sheet Nguon để đặt tên cho Sheet mới (Tên mới là: N04T11....), Tiếp theo là định dạng và in ấn. Tiếp tục vòng lặp tìm file tiếp theo....cứ thế đến hết. Nhờ có sự chỉ giúp của các anh mà tôi đã viết được code chạy cho ra được kết quả đúng yêu cầu. Tuy Code này chạy cho ra được kết quả nhưng cũng phải chờ dài dài (3-5 phút)
Mong muốn của tôi là, có anh chị em có ghé qua xem bài , xem code (đính kèm bên dưới) và cho góp ý (hoặc sửa code, hoặc ....) để tôi hoàn thiện hơn.
Trân trọng cảm ơn anh chị em.
Mã:
Option Explicit
Sub Bsung()
Dim Lr&, i&, J&, R&, t&, TongN&, Vitri&, tt&, kk&
Dim Arr(), KQ(), NCC(), ntn(1 To 3), e, N
Dim fso As Object, Dic As Object, DicT As Object
Dim NWs As Worksheet, WbMoi As Workbook, Ws As Worksheet
Dim Keys As String
Dim file As Variant

 Application.ScreenUpdating = False
 Application.DisplayAlerts = False
 
Set Dic = CreateObject("Scripting.Dictionary")
Set fso = CreateObject("Scripting.FileSystemObject")

ReDim NCC(1 To 100, 1 To 3)
Sheets("DMHH").Select
For J = 1 To Sheets("DMHH").Cells(Rows.Count, 1).End(xlUp).Row
    Keys = Sheets("DMHH").Cells(J, 1)
    If Not Dic.exists(Keys) Then
        t = t + 1: Dic.Add (Keys), t
        NCC(t, 1) = Keys
        NCC(t, 2) = Sheets("DMHH").Cells(J, 2)
        NCC(t, 3) = Sheets("DMHH").Cells(J, 3)
    End If
Next J

ReDim KQ(1 To 100, 1 To 1)
For Each file In CreateObject("Scripting.FileSystemObject").GetFolder("C:\Users\Admin\Downloads\").Files
    If file.Name Like "*Excel5.xls" Then
        Set WbMoi = Workbooks.Open(file)     '======Bi lôi dong này "không tim thây, có thê đa đôi ten, di chuyên hoac đa xoa"
        For Each Ws In WbMoi.Sheets
            If Ws.Name = "TPT" Then
Set DicT = CreateObject("Scripting.Dictionary")
 
'=======Copy sheet nguon=========='
            Ws.Select
            Ws.Range("A1:Q30").Copy
     
'=========paste xuông Sheet============'

            Windows("TONGHOP DULIEU NHAP TP (DDMN).xlsm").Activate
            Sheets.Add After:=ActiveSheet
            ActiveSheet.Paste
            Set NWs = ActiveSheet
        WbMoi.Close
 
'===========tach lay ngay tháng============'
Vitri = 0: kk = 0: tt = 0
    For Each e In Split(NWs.Cells(5, 1))
        If IsNumeric(e) Then
            Vitri = Vitri + 1
                ntn(Vitri) = CLng(e)
                    If Vitri >= 3 Then ' đ? 3 s? r?i, tính ngày
                        N = DateSerial(ntn(3), ntn(2), ntn(1))
                            Exit For
                    End If
        End If
    Next e

'============Lây dư liêu thay thê bô sung=============='
     
            Lr = NWs.Cells(Rows.Count, 1).End(xlUp).Row
            Arr = NWs.Range("A10:O" & Lr).Value
            TongN = 0
            ReDim KQ(1 To UBound(Arr) + 1, 1 To 15)
            For i = 1 To UBound(Arr)
                KQ(i, 1) = Arr(i, 1)
                KQ(i, 2) = Arr(i, 2)
                KQ(i, 3) = Arr(i, 3)
              '  KQ(i, 4) = 8 & "h" & Int(Application.WorksheetFunction.RandBetween(1, 89) / 3) _
                & "p-" & Day(N) & "/" & Month(N)
                KQ(i, 5) = Arr(i, 5)
                KQ(i, 6) = Arr(i, 6)
                KQ(i, 7) = Arr(i, 5) * Arr(i, 6) 'Arr(i, 7) * 1000
                TongN = TongN + Arr(i, 7)
                KQ(i, 8) = "Đat"
                If Dic.exists(Arr(i, 2)) Then
                    KQ(i, 10) = NCC(Dic.Item(Arr(i, 2)), 2)
                    KQ(i, 11) = NCC(Dic.Item(Arr(i, 2)), 3)
                End If
                If Not DicT.exists(KQ(i, 10)) Then
                    tt = tt + 1: DicT.Add (KQ(i, 10)), tt
                    KQ(i, 4) = 8 & "h" & Int(Application.WorksheetFunction.RandBetween(1, 89) / 3) _
                & "p-" & Day(N) & "/" & Month(N)
                Else
                    kk = DicT.Item(KQ(i, 10))
                    KQ(i, 4) = KQ(kk, 4)
                End If
                    KQ(i, 13) = KQ(i, 5)
                    KQ(i, 14) = KQ(i, 6)
                    KQ(i, 15) = KQ(i, 7)
            Next i
            Set DicT = Nothing
               NWs.Name = "N" & Day(N) & "T" & Month(N)
        End If
 
        NWs.Range("A10").Resize(i, 15) = KQ
                NWs.Range("A" & Lr + 1, "P" & Lr + 2).Select
                Selection.UnMerge
                Selection.Font.Size = 10
                Selection.Font.Bold = True
                Selection.NumberFormat = "#,##0"
                'NWs.Range("A" & Lr + 1, "P" & Lr + 2).Font.Size = 10
                NWs.Range("B" & Lr + 1) = "Công"
                NWs.Range("G" & Lr + 1) = TongN
                NWs.Range("O" & Lr + 1) = TongN
                NWs.Range("B" & Lr + 2) = "Băng chư:"
                NWs.Range("C" & Lr + 2).FormulaR1C1 = "=VND(R[-1]C[4])"
                NWs.Range("C" & Lr + 2).HorizontalAlignment = xlLeft
                NWs.Range("O10", "O" & Lr).HorizontalAlignment = xlRight
                NWs.Range("B" & Lr + 2, "C" & Lr + 2).Font.Italic = True
                NWs.Range("B" & Lr + 2, "C" & Lr + 2).Font.Bold = False
                NWs.Range("M" & Lr + 2, "Q" & Lr + 2).ClearContents
                NWs.Range("A7:P16").Font.Size = 10
                NWs.Columns("A:A").ColumnWidth = 2.89
                NWs.Columns("B:B").ColumnWidth = 9.78
                NWs.Columns("C:C").ColumnWidth = 3.22
                NWs.Columns("D:D").ColumnWidth = 8.22
                NWs.Columns("E:E").ColumnWidth = 4.5
                NWs.Columns("F:F").ColumnWidth = 4.7
                NWs.Columns("G:G").ColumnWidth = 8
                NWs.Columns("H:H").ColumnWidth = 3.67
                NWs.Columns("I:I").ColumnWidth = 3.44
                NWs.Columns("J:J").ColumnWidth = 13.2
                NWs.Columns("K:K").ColumnWidth = 13
                NWs.Columns("L:L").ColumnWidth = 10.11
                NWs.Columns("M:M").ColumnWidth = 4.5
                NWs.Columns("N:N").ColumnWidth = 4.7
                NWs.Columns("O:O").ColumnWidth = 8
                NWs.Columns("P:P").ColumnWidth = 7.11
                NWs.Range("A1").HorizontalAlignment = xlCenter
                NWs.Range("A2").HorizontalAlignment = xlCenter
                NWs.Range("A1").VerticalAlignment = xlCenter
                NWs.Range("A2").VerticalAlignment = xlCenter
                NWs.Range("B10", "B" & Lr).WrapText = True
                NWs.Range("B" & Lr + 3).WrapText = False
                NWs.Range("F" & Lr + 3).WrapText = False
                NWs.Range("B" & Lr + 8).WrapText = False
                NWs.Range("F" & Lr + 8).WrapText = False
                NWs.Range("D10", "D" & Lr).ShrinkToFit = True
                NWs.Range("J10", "L" & Lr).ShrinkToFit = True
Next Ws
End If
Next file

    Call MucLuc

    Sheets("MucLuc").range("A1").Select

Set fso = Nothing
Set Dic = Nothing

Application.ScreenUpdating = True
Application.DisplayAlerts = True

MsgBox " Đa hoàn thành lây bô sung dư liêu các phiêu N-X hàng ngày", vbInformation, "THÔNG BÁO"
End Sub
Còn bài toán của Anh @huuthang_bd nêu trên thì có lẽ phải dùng đến hàm Seach để tìm xem chuỗi "ngày" nằm ở vị trí thứ mấy (thứ n) và sau đó mới chạy vòng lặp For i = n to Ubound(S). với S =Array(Range(....)," ").Rồi sau đó mới là If Isnumeric(S(i) then....
Tuy không có giải pháp nào tối ưu hơn, nhưng em có viết cái hàm của nợ chắc sẽ thoải mái và đa dạng các trường hợp đặc biệt hơn cho bác :)
Mã:
Function xuly(Myrange As Range)
    Set regEx = CreateObject("VBScript.RegExp")
    Dim strPattern As String
    Dim strInput As String
    Dim a1, a2, a3
            strPattern = ".*?ngày\s*(\d+)\s*tháng\s*(\d+)\s*n" & ChrW(259) & "m\s*(\d+)(.+)*"
            strInput = Myrange.Value
            With regEx
                .Global = True
                .IgnoreCase = True
                .Pattern = strPattern
            End With

            If regEx.test(strInput) Then
                a1 = regEx.Replace(strInput, "$1")
                a2 = regEx.Replace(strInput, "$2")
                a3 = regEx.Replace(strInput, "$3")
                xuly = a1 & "/" & a2 & "/" & a3
            Else
                xuly = "Khong co"
            End If
End Function
 
Lần chỉnh sửa cuối:
Tuy không có giải pháp nào tối ưu hơn, nhưng em có viết cái hàm của nợ chắc sẽ thoải mái và đa dạng các trường hợp đặc biệt hơn cho bác :)
Mã:
            strPattern = ".*?ngày\s*(\d+)\s*tháng\s*(\d+)\s*n" & ChrW(259) & "m\s*(\d+)(.+)*"
...
            If regEx.test(strInput) Then
                a1 = regEx.Replace(strInput, "$1")
                a2 = regEx.Replace(strInput, "$2")
                a3 = regEx.Replace(strInput, "$3")
                xuly = a1 & "/" & a2 & "/" & a3
            Else
                xuly = "Khong co"
            End If
End Function
1. Pattern không đúng lắm.
2. làm theo sì-tin GPE cho nên quen với hàm Replace. Và vì vậy phải gọi 3 lần.
Gọi Match thì chỉ cần 1 lần rồi lấy ra 3 phần con của nó.
 
1. Pattern không đúng lắm.
2. làm theo sì-tin GPE cho nên quen với hàm Replace. Và vì vậy phải gọi 3 lần.
Gọi Match thì chỉ cần 1 lần rồi lấy ra 3 phần con của nó.
Em cám ơn bác đã góp ý, ban đầu em cũng tính xử lý bình thường đơn giản với pattern: \d+ , nhưng nếu có thêm những trường hợp đặc biệt khác như:
"lần thứ 3, ngày 23 tháng 2 năm 2021" hoặc "thứ 7, ngày 23 tháng 2 năm 2021, lần thứ 3 " thì e chưa có pattern nào có thể loại trừ được T_T
Còn pattern "sửa lại 1 chút" phía dưới không biết hợp lí chưa ạ ^^
Mã:
Function tachGPE(text As Range)
Dim VBR As Object
Dim i, j, result
Set VBR = CreateObject("VBScript.RegExp")
With VBR
    .Global = True
    .IgnoreCase = True
    .Pattern = ".*?ngày.*?(\d+).*?tháng.*?(\d+).*?n" & ChrW(259) & "m.*?(\d+).*"
Set allMatches = .Execute(text)
For i = 0 To allMatches.Count - 1
    For j = 0 To allMatches.Item(i).submatches.Count - 1
        result = result & "/" & allMatches.Item(i).submatches.Item(j)
    Next
Next
End With
If Len(result) <> 0 Then
tachGPE = Right(result, Len(result) - 1)
Else
tachGPE = "khong co gi"
End If
End Function
 
Lần chỉnh sửa cuối:
Em cám ơn bác đã góp ý, ban đầu em cũng tính xử lý bình thường đơn giản với pattern: \d+ , nhưng nếu có thêm những trường hợp đặc biệt khác như:
"lần thứ 3, ngày 23 tháng 2 năm 2021" hoặc "thứ 7, ngày 23 tháng 2 năm 2021, lần thứ 3 " thì e chưa có pattern nào có thể loại trừ được T_T
Còn pattern "sửa lại 1 chút" phía dưới không biết hợp lí chưa ạ ^^
Mã:
Function tachGPE(text As Range)
Dim VBR As Object
Dim i, j, result
Set VBR = CreateObject("VBScript.RegExp")
With VBR
    .Global = True
    .IgnoreCase = True
    .Pattern = ".*?ngày.*?(\d+).*?tháng.*?(\d+).*?n" & ChrW(259) & "m.*?(\d+).*"
Set allMatches = .Execute(text)
For i = 0 To allMatches.Count - 1
    For j = 0 To allMatches.Item(i).submatches.Count - 1
        result = result & "/" & allMatches.Item(i).submatches.Item(j)
    Next
Next
End With
If Len(result) <> 0 Then
tachGPE = Right(result, Len(result) - 1)
Else
tachGPE = "khong co gi"
End If
End Function
Cảm ơn bạn đã xem bài và cung cấp cho tôi và những thành viên khác thêm một giải pháp hữu ích.
 
Biết thì chỉ replace 1 lần thôi.
Mã:
Function LayNgay(ByVal Chuoi As String) As Date
With CreateObject("VBScript.RegExp")
    .Pattern = ".*ng" & ChrW(224) & "y (\d{1,2}) th" & ChrW(225) & "ng (\d{1,2}) n" & ChrW(259) & "m (\d{4}).*"
    LayNgay = DateValue(.Replace(Chuoi, "$3/$2/$1"))
End With
End Function
 
Cảm ơn Anh đã ghé qua và xem bài.
Tôi có khoảng gần 200 file có cấu trúc giống nhau do tải trên phần mềm về. Trong mỗi file chỉ có 1 sheet (tên Sh cũng giống nhau) và trong sheet ấy chỉ có 1 ô chứa ngày tháng năm (kiểu Hôm nay, Thứ sáu ( sáu chứ không phải 6) ngày 04 tháng 11 năm 2021.
Nhiệm vụ của code tôi viết là Tìm 200 cái file ấy (tên file có dạng: xxxx Excel5.xlsx). copy Sh duy nhất ấy (tạm gọi là Sh Nguon);==>tạo sheet mới (trong Workbook chứa code) và Paste vào Sheet mới ấy; Xử lý dữ liệu; tách lấy ngày tháng của cái sheet Nguon để đặt tên cho Sheet mới (Tên mới là: N04T11....), Tiếp theo là định dạng và in ấn. Tiếp tục vòng lặp tìm file tiếp theo....cứ thế đến hết. Nhờ có sự chỉ giúp của các anh mà tôi đã viết được code chạy cho ra được kết quả đúng yêu cầu. Tuy Code này chạy cho ra được kết quả nhưng cũng phải chờ dài dài (3-5 phút)
Mong muốn của tôi là, có anh chị em có ghé qua xem bài , xem code (đính kèm bên dưới) và cho góp ý (hoặc sửa code, hoặc ....) để tôi hoàn thiện hơn.
Trân trọng cảm ơn anh chị em.
Mã:
Option Explicit
Sub Bsung()
Dim Lr&, i&, J&, R&, t&, TongN&, Vitri&, tt&, kk&
Dim Arr(), KQ(), NCC(), ntn(1 To 3), e, N
Dim fso As Object, Dic As Object, DicT As Object
Dim NWs As Worksheet, WbMoi As Workbook, Ws As Worksheet
Dim Keys As String
Dim file As Variant

 Application.ScreenUpdating = False
 Application.DisplayAlerts = False
 
Set Dic = CreateObject("Scripting.Dictionary")
Set fso = CreateObject("Scripting.FileSystemObject")

ReDim NCC(1 To 100, 1 To 3)
Sheets("DMHH").Select
For J = 1 To Sheets("DMHH").Cells(Rows.Count, 1).End(xlUp).Row
    Keys = Sheets("DMHH").Cells(J, 1)
    If Not Dic.exists(Keys) Then
        t = t + 1: Dic.Add (Keys), t
        NCC(t, 1) = Keys
        NCC(t, 2) = Sheets("DMHH").Cells(J, 2)
        NCC(t, 3) = Sheets("DMHH").Cells(J, 3)
    End If
Next J

ReDim KQ(1 To 100, 1 To 1)
For Each file In CreateObject("Scripting.FileSystemObject").GetFolder("C:\Users\Admin\Downloads\").Files
    If file.Name Like "*Excel5.xls" Then
        Set WbMoi = Workbooks.Open(file)     '======Bi lôi dong này "không tim thây, có thê đa đôi ten, di chuyên hoac đa xoa"
        For Each Ws In WbMoi.Sheets
            If Ws.Name = "TPT" Then
Set DicT = CreateObject("Scripting.Dictionary")
 
'=======Copy sheet nguon=========='
            Ws.Select
            Ws.Range("A1:Q30").Copy
       
'=========paste xuông Sheet============'

            Windows("TONGHOP DULIEU NHAP TP (DDMN).xlsm").Activate
            Sheets.Add After:=ActiveSheet
            ActiveSheet.Paste
            Set NWs = ActiveSheet
        WbMoi.Close
   
'===========tach lay ngay tháng============'
Vitri = 0: kk = 0: tt = 0
    For Each e In Split(NWs.Cells(5, 1))
        If IsNumeric(e) Then
            Vitri = Vitri + 1
                ntn(Vitri) = CLng(e)
                    If Vitri >= 3 Then ' đ? 3 s? r?i, tính ngày
                        N = DateSerial(ntn(3), ntn(2), ntn(1))
                            Exit For
                    End If
        End If
    Next e

'============Lây dư liêu thay thê bô sung=============='
       
            Lr = NWs.Cells(Rows.Count, 1).End(xlUp).Row
            Arr = NWs.Range("A10:O" & Lr).Value
            TongN = 0
            ReDim KQ(1 To UBound(Arr) + 1, 1 To 15)
            For i = 1 To UBound(Arr)
                KQ(i, 1) = Arr(i, 1)
                KQ(i, 2) = Arr(i, 2)
                KQ(i, 3) = Arr(i, 3)
              '  KQ(i, 4) = 8 & "h" & Int(Application.WorksheetFunction.RandBetween(1, 89) / 3) _
                & "p-" & Day(N) & "/" & Month(N)
                KQ(i, 5) = Arr(i, 5)
                KQ(i, 6) = Arr(i, 6)
                KQ(i, 7) = Arr(i, 5) * Arr(i, 6) 'Arr(i, 7) * 1000
                TongN = TongN + Arr(i, 7)
                KQ(i, 8) = "Đat"
                If Dic.exists(Arr(i, 2)) Then
                    KQ(i, 10) = NCC(Dic.Item(Arr(i, 2)), 2)
                    KQ(i, 11) = NCC(Dic.Item(Arr(i, 2)), 3)
                End If
                If Not DicT.exists(KQ(i, 10)) Then
                    tt = tt + 1: DicT.Add (KQ(i, 10)), tt
                    KQ(i, 4) = 8 & "h" & Int(Application.WorksheetFunction.RandBetween(1, 89) / 3) _
                & "p-" & Day(N) & "/" & Month(N)
                Else
                    kk = DicT.Item(KQ(i, 10))
                    KQ(i, 4) = KQ(kk, 4)
                End If
                    KQ(i, 13) = KQ(i, 5)
                    KQ(i, 14) = KQ(i, 6)
                    KQ(i, 15) = KQ(i, 7)
            Next i
            Set DicT = Nothing
               NWs.Name = "N" & Day(N) & "T" & Month(N)
        End If
   
        NWs.Range("A10").Resize(i, 15) = KQ
                NWs.Range("A" & Lr + 1, "P" & Lr + 2).Select
                Selection.UnMerge
                Selection.Font.Size = 10
                Selection.Font.Bold = True
                Selection.NumberFormat = "#,##0"
                'NWs.Range("A" & Lr + 1, "P" & Lr + 2).Font.Size = 10
                NWs.Range("B" & Lr + 1) = "Công"
                NWs.Range("G" & Lr + 1) = TongN
                NWs.Range("O" & Lr + 1) = TongN
                NWs.Range("B" & Lr + 2) = "Băng chư:"
                NWs.Range("C" & Lr + 2).FormulaR1C1 = "=VND(R[-1]C[4])"
                NWs.Range("C" & Lr + 2).HorizontalAlignment = xlLeft
                NWs.Range("O10", "O" & Lr).HorizontalAlignment = xlRight
                NWs.Range("B" & Lr + 2, "C" & Lr + 2).Font.Italic = True
                NWs.Range("B" & Lr + 2, "C" & Lr + 2).Font.Bold = False
                NWs.Range("M" & Lr + 2, "Q" & Lr + 2).ClearContents
                NWs.Range("A7:P16").Font.Size = 10
                NWs.Columns("A:A").ColumnWidth = 2.89
                NWs.Columns("B:B").ColumnWidth = 9.78
                NWs.Columns("C:C").ColumnWidth = 3.22
                NWs.Columns("D:D").ColumnWidth = 8.22
                NWs.Columns("E:E").ColumnWidth = 4.5
                NWs.Columns("F:F").ColumnWidth = 4.7
                NWs.Columns("G:G").ColumnWidth = 8
                NWs.Columns("H:H").ColumnWidth = 3.67
                NWs.Columns("I:I").ColumnWidth = 3.44
                NWs.Columns("J:J").ColumnWidth = 13.2
                NWs.Columns("K:K").ColumnWidth = 13
                NWs.Columns("L:L").ColumnWidth = 10.11
                NWs.Columns("M:M").ColumnWidth = 4.5
                NWs.Columns("N:N").ColumnWidth = 4.7
                NWs.Columns("O:O").ColumnWidth = 8
                NWs.Columns("P:P").ColumnWidth = 7.11
                NWs.Range("A1").HorizontalAlignment = xlCenter
                NWs.Range("A2").HorizontalAlignment = xlCenter
                NWs.Range("A1").VerticalAlignment = xlCenter
                NWs.Range("A2").VerticalAlignment = xlCenter
                NWs.Range("B10", "B" & Lr).WrapText = True
                NWs.Range("B" & Lr + 3).WrapText = False
                NWs.Range("F" & Lr + 3).WrapText = False
                NWs.Range("B" & Lr + 8).WrapText = False
                NWs.Range("F" & Lr + 8).WrapText = False
                NWs.Range("D10", "D" & Lr).ShrinkToFit = True
                NWs.Range("J10", "L" & Lr).ShrinkToFit = True
Next Ws
End If
Next file

    Call MucLuc

    Sheets("MucLuc").range("A1").Select

Set fso = Nothing
Set Dic = Nothing

Application.ScreenUpdating = True
Application.DisplayAlerts = True

MsgBox " Đa hoàn thành lây bô sung dư liêu các phiêu N-X hàng ngày", vbInformation, "THÔNG BÁO"
End Sub
Còn bài toán của Anh @huuthang_bd nêu trên thì có lẽ phải dùng đến hàm Seach để tìm xem chuỗi "ngày" nằm ở vị trí thứ mấy (thứ n) và sau đó mới chạy vòng lặp For i = n to Ubound(S). với S =Array(Range(....)," ").Rồi sau đó mới là If Isnumeric(S(i) then....
Bạn gửi file xuất từ phần mềm ra và file chứa code lên đi
 
Bạn gửi file xuất từ phần mềm ra và file chứa code lên đi
Code tôi viết loằng ngoằng, theo ý hiểu của bản thân (viết cho vợ làm việc nên cũng gọi là tạm ổn). Tôi gửi file nên. nếu có thể anh xem và sửa giùm nhé. Trân trọng.
 

File đính kèm

  • TONGHOP DULIEU NHAP TP (DDMN).xlsm
    53.9 KB · Đọc: 6
  • 1638064882Excel5.xls
    14 KB · Đọc: 5
  • 1638064858Excel5.xls
    14.5 KB · Đọc: 3
  • 1638064812Excel5.xls
    14 KB · Đọc: 2
  • 1638064784Excel5.xls
    15 KB · Đọc: 2
  • 1638064741Excel5.xls
    14 KB · Đọc: 3
Code tôi viết loằng ngoằng, theo ý hiểu của bản thân (viết cho vợ làm việc nên cũng gọi là tạm ổn). Tôi gửi file nên. nếu có thể anh xem và sửa giùm nhé. Trân trọng.
Bạn gửi thêm cái sheet trước khi in nó như thế nào nhé, Xem cách bạn căn chỉnh ra làm sao. Nếu khả năng giúp được mình sẽ giúp
 
Bạn gửi thêm cái sheet trước khi in nó như thế nào nhé, Xem cách bạn căn chỉnh ra làm sao. Nếu khả năng giúp được mình sẽ giúp
Cảm ơn bạn. Cái Sh TongHop ấy khi nhấn nút LẤY DỮ LIỆU PHIẾU N-X thì code chạy và ta thu được các phiếu xuất (từ các file....Excel5.xsl) là các Sh đã được đặt tên là N4T10, N5T10.... và in các Sh ấy thôi. Bạn tải về Sh TongHop và 1 vài Sh ....Excel5.xsl và thử chạy code xem. Nếu có thể sửa giùm tôi thì tuyệt vời. Trân trọng.
 
Cảm ơn bạn. Cái Sh TongHop ấy khi nhấn nút LẤY DỮ LIỆU PHIẾU N-X thì code chạy và ta thu được các phiếu xuất (từ các file....Excel5.xsl) là các Sh đã được đặt tên là N4T10, N5T10.... và in các Sh ấy thôi. Bạn tải về Sh TongHop và 1 vài Sh ....Excel5.xsl và thử chạy code xem. Nếu có thể sửa giùm tôi thì tuyệt vời. Trân trọng.
File của bạn xuất từ phần mềm có vấn đề về các dấu phân cách của số liệu (dấu phẩy và chấm). File này mình chỉ tổng hợp dữ liệu từ các file con, còn vấn đề tính toán bạn xem lại nha
 

File đính kèm

  • TONGHOP DULIEU NHAP TP (DDMN).xlsm
    70.1 KB · Đọc: 8
Web KT
Back
Top Bottom