[Cần giúp đỡ] Code update data vào file excel hàng ngày

Liên hệ QC

Datcdt2k9

Thành viên hoạt động
Tham gia
27/12/19
Bài viết
109
Được thích
11
Chào mọi người
Em đang gặp vấn đề nếu làm thủ công sẽ mất nhiều thời gian
Vì vậy em đăng lên diễn đàn nhờ mọi người giúp đỡ
Khi Paste data vào cột C (bảng trên )=> chạy code => Data sẽ ra như bảng dưới và khi update data mới dữ liệu sẽ update vào dòng kế tiếp( trong ví dụ data cũ update tới hàng 23, nếu update data mới khi run code update vào dòng 24 trở đi)
Các trường hợp có thể phát sinh em đã tổng hợp trong file
Mong các anh chị giúp đỡ. Em xin cảm ơn
1607769830534.png
 

File đính kèm

  • TEST FILL DOWN_V01.xlsm
    23.4 KB · Đọc: 9
Lần chỉnh sửa cuối:
Chào mọi người
Em đang gặp vấn đề nếu làm thủ công sẽ mất nhiều thời gian
Vì vậy em đăng lên diễn đàn nhờ mọi người giúp đỡ
Khi Paste data vào cột C => chạy code => Data sẽ ra như bảng dưới
Các trường hợp có thể phát sinh em đã tổng hợp trong file
Mong các anh chị giúp đỡ. Em xin cảm ơn
View attachment 251108
Bạn xem thử thế nào:
Mã:
Option Explicit
Function Rex(Chuoi As String, Ptn As String) As String
    Dim Re As Object, KQ
    Set Re = CreateObject("vbscript.regexp")
    With Re
        .Global = True
        .MultiLine = True
        .IgnoreCase = True
        .Pattern = Ptn
    End With
    If Re.Test(Chuoi) Then
        Set KQ = Re.Execute(Chuoi)
        Rex = KQ(0)
    Else
        Rex = "#N/A"
    End If
End Function

Sub NTKTNN()
Dim sArr(), dArr(), I&, J&, K&, R&, R1&, SL()
Dim Model$, PGM$, Dai$, CTD$, sType$, Side$, sChuoi$
sArr = Application.InputBox("Chon vùng du lieu nhu ben duoi:", "Select Data Range", "C2:C7", Type:=64)
R = UBound(sArr, 1)
ReDim SL(1 To R)
For I = 1 To R
    sChuoi = sArr(I, 1)
    SL(I) = 1 - Evaluate(Rex(sChuoi, "\d{3}-\d{3}"))
    R1 = R1 + SL(I)
Next
ReDim dArr(1 To R1, 1 To 7)
For I = 1 To R
    sChuoi = sArr(I, 1)
    Side = Left(sChuoi, 1)
    sType = Rex(sChuoi, "\w{2}(?=\.ZIP)")
    If InStr(1, sType, "X", 1) = 0 Then sType = ""
    Dai = Rex(sChuoi, "[A-Z0-9|-]{10,}")
    For J = 1 To SL(I)
        K = K + 1
        CTD = Rex(sChuoi, "[A-Z0-9]{10,}")
        CTD = Left(CTD, Len(CTD) - 3) & Format(Right(CTD, 3) + J - 1, "000")
        Model = Mid(sChuoi, 2, 3) & CTD & sType
        PGM = Mid(sChuoi, 2, Len(sChuoi) - 5)
        dArr(K, 1) = K
        dArr(K, 2) = Model
        dArr(K, 3) = PGM
        dArr(K, 4) = Dai
        dArr(K, 5) = CTD
        dArr(K, 6) = sType
        dArr(K, 7) = Side
    Next
Next
Range("A12").Resize(10000, 7).ClearContents
Range("A12").Resize(K, 7) = dArr
End Sub
 

File đính kèm

  • TEST FILL DOWN.xlsm
    22.6 KB · Đọc: 10
Upvote 0
Vâng em kiểm tra ạ
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn xem thử thế nào:
Mã:
Option Explicit
Function Rex(Chuoi As String, Ptn As String) As String
    Dim Re As Object, KQ
    Set Re = CreateObject("vbscript.regexp")
    With Re
        .Global = True
        .MultiLine = True
        .IgnoreCase = True
        .Pattern = Ptn
    End With
    If Re.Test(Chuoi) Then
        Set KQ = Re.Execute(Chuoi)
        Rex = KQ(0)
    Else
        Rex = "#N/A"
    End If
End Function

Sub NTKTNN()
Dim sArr(), dArr(), I&, J&, K&, R&, R1&, SL()
Dim Model$, PGM$, Dai$, CTD$, sType$, Side$, sChuoi$
sArr = Application.InputBox("Chon vùng du lieu nhu ben duoi:", "Select Data Range", "C2:C7", Type:=64)
R = UBound(sArr, 1)
ReDim SL(1 To R)
For I = 1 To R
    sChuoi = sArr(I, 1)
    SL(I) = 1 - Evaluate(Rex(sChuoi, "\d{3}-\d{3}"))
    R1 = R1 + SL(I)
Next
ReDim dArr(1 To R1, 1 To 7)
For I = 1 To R
    sChuoi = sArr(I, 1)
    Side = Left(sChuoi, 1)
    sType = Rex(sChuoi, "\w{2}(?=\.ZIP)")
    If InStr(1, sType, "X", 1) = 0 Then sType = ""
    Dai = Rex(sChuoi, "[A-Z0-9|-]{10,}")
    For J = 1 To SL(I)
        K = K + 1
        CTD = Rex(sChuoi, "[A-Z0-9]{10,}")
        CTD = Left(CTD, Len(CTD) - 3) & Format(Right(CTD, 3) + J - 1, "000")
        Model = Mid(sChuoi, 2, 3) & CTD & sType
        PGM = Mid(sChuoi, 2, Len(sChuoi) - 5)
        dArr(K, 1) = K
        dArr(K, 2) = Model
        dArr(K, 3) = PGM
        dArr(K, 4) = Dai
        dArr(K, 5) = CTD
        dArr(K, 6) = sType
        dArr(K, 7) = Side
    Next
Next
Range("A12").Resize(10000, 7).ClearContents
Range("A12").Resize(K, 7) = dArr
End Sub

Cột F (Side) khi run code thì chỉ trả về "B" nên em xin update lại file. Cột C phần kết quả em cần giữ nguyên đuôi zip. Mỗi lần update data mới và run code => Kết quả tự động update vào dòng kế tiếp ( trong ví dụ đang ở dòng 23 khi update data mới => update vào dòng 24 trở đi) và cột STT cũng tự động nhảy tăng dần
Chỉ khi Cột A (STT) có dữ liệu => run code => data update, không có run code =>không update dữ liệu

1607769732124.png
 

File đính kèm

  • TEST FILL DOWN_V01.xlsm
    23.4 KB · Đọc: 7
  • 1607769612538.png
    1607769612538.png
    332.6 KB · Đọc: 7
Lần chỉnh sửa cuối:
Upvote 0
Khai báo là static để mỗi vòng lặp không phải dựng lại regex object.
Em đã nghĩ tới sau khi gửi code đi, mà gửi rồi nên lười sửa. Vì regex chủ đề nào đó gần đây em cũng có hỏi bác liên quan đến cái này, không nhớ rõ lắm, hình như là "dựng lại regex tốn bộ nhớ hay làm giảm tốc độ" gì đó thì phải
 
Upvote 0
Em đã nghĩ tới sau khi gửi code đi, mà gửi rồi nên lười sửa. Vì regex chủ đề nào đó gần đây em cũng có hỏi bác liên quan đến cái này, không nhớ rõ lắm, hình như là "dựng lại regex tốn bộ nhớ hay làm giảm tốc độ" gì đó thì phải
Mọi người giúp em với ạ, với lại em muốn sheet 1 chỉ là sheet nhập dữ liệu mới hàng ngày=> khi run code => phần kết quả như trong bảng tự động update vào sheet2 hoặc sheet3...do mình chọn được không ạ
 
Upvote 0
Mọi người giúp em với ạ, với lại em muốn sheet 1 chỉ là sheet nhập dữ liệu mới hàng ngày=> khi run code => phần kết quả như trong bảng tự động update vào sheet2 hoặc sheet3...do mình chọn được không ạ
Tôi đã sửa lại code, bạn xem lại nhé (File lúc đầu bạn gửi hình như kết quả không giống bây giờ)
Mã:
Option Explicit
Function Rex(Chuoi As String, Ptn As String) As String
    Static Re As Object
    Dim KQ
    If Re Is Nothing Then Set Re = CreateObject("vbscript.regexp")
    With Re
        .Global = True
        .MultiLine = True
        .IgnoreCase = True
        .Pattern = Ptn
    End With
    If Re.Test(Chuoi) Then
        Set KQ = Re.Execute(Chuoi)
        Rex = KQ(0)
    End If
End Function

Sub NTKTNN()
Dim sArr(), dArr(), I&, J&, K&, R&, R1&, SL()
Dim Model$, PGM$, Dai$, CTD$, sType$, Side$, sChuoi$, ExtractToSheet$
sArr = Application.InputBox("Chon vùng du lieu nhu ben duoi:", "Select Data Range", "C2:C7", Type:=64)
R = UBound(sArr, 1)
ReDim SL(1 To R)
For I = 1 To R
    sChuoi = sArr(I, 1)
    SL(I) = 1 - Evaluate(Rex(sChuoi, "\d{3}-\d{3}"))
    R1 = R1 + SL(I)
Next
ReDim dArr(1 To R1, 1 To 7)
For I = 1 To R
    sChuoi = sArr(I, 1)
    On Error Resume Next
    Side = Right(Rex(sChuoi, "_[A-Z]{2}(?=_)"), 1)
    On Error GoTo 0
    sType = Rex(sChuoi, "\w{2}(?=\.ZIP)")
    If InStr(1, sType, "X", 1) = 0 Then sType = ""
    Dai = Rex(sChuoi, "[A-Z0-9|-]{10,}")
    For J = 1 To SL(I)
        K = K + 1
        CTD = Rex(sChuoi, "[A-Z0-9]{10,}")
        CTD = Left(CTD, Len(CTD) - 3) & Format(Right(CTD, 3) + J - 1, "000")
        PGM = Mid(sChuoi, 2, Len(sChuoi))
        Model = Left(PGM, 7) & CTD & sType & Side
        dArr(K, 1) = K
        dArr(K, 2) = Model
        dArr(K, 3) = PGM
        dArr(K, 4) = Dai
        dArr(K, 5) = CTD
        dArr(K, 6) = sType
        dArr(K, 7) = Side
    Next
Next
ExtractToSheet = Application.InputBox("Ðiê`n tên sheet", "Xuât Kêt Qua", "Fill auto", Type:=2)
With Sheets(ExtractToSheet)
.Range("A10000").End(xlUp).Offset(2).Resize(10000, 7).ClearContents
.Range("A10000").End(xlUp).Offset(2).Resize(K, 7) = dArr
End With
End Sub
 

File đính kèm

  • TEST FILL DOWN_V01.xlsm
    23.8 KB · Đọc: 11
Upvote 0
Tôi đã sửa lại code, bạn xem lại nhé (File lúc đầu bạn gửi hình như kết quả không giống bây giờ)
Mã:
Option Explicit
Function Rex(Chuoi As String, Ptn As String) As String
    Static Re As Object
    Dim KQ
    If Re Is Nothing Then Set Re = CreateObject("vbscript.regexp")
    With Re
        .Global = True
        .MultiLine = True
        .IgnoreCase = True
        .Pattern = Ptn
    End With
    If Re.Test(Chuoi) Then
        Set KQ = Re.Execute(Chuoi)
        Rex = KQ(0)
    End If
End Function

Sub NTKTNN()
Dim sArr(), dArr(), I&, J&, K&, R&, R1&, SL()
Dim Model$, PGM$, Dai$, CTD$, sType$, Side$, sChuoi$, ExtractToSheet$
sArr = Application.InputBox("Chon vùng du lieu nhu ben duoi:", "Select Data Range", "C2:C7", Type:=64)
R = UBound(sArr, 1)
ReDim SL(1 To R)
For I = 1 To R
    sChuoi = sArr(I, 1)
    SL(I) = 1 - Evaluate(Rex(sChuoi, "\d{3}-\d{3}"))
    R1 = R1 + SL(I)
Next
ReDim dArr(1 To R1, 1 To 7)
For I = 1 To R
    sChuoi = sArr(I, 1)
    On Error Resume Next
    Side = Right(Rex(sChuoi, "_[A-Z]{2}(?=_)"), 1)
    On Error GoTo 0
    sType = Rex(sChuoi, "\w{2}(?=\.ZIP)")
    If InStr(1, sType, "X", 1) = 0 Then sType = ""
    Dai = Rex(sChuoi, "[A-Z0-9|-]{10,}")
    For J = 1 To SL(I)
        K = K + 1
        CTD = Rex(sChuoi, "[A-Z0-9]{10,}")
        CTD = Left(CTD, Len(CTD) - 3) & Format(Right(CTD, 3) + J - 1, "000")
        PGM = Mid(sChuoi, 2, Len(sChuoi))
        Model = Left(PGM, 7) & CTD & sType & Side
        dArr(K, 1) = K
        dArr(K, 2) = Model
        dArr(K, 3) = PGM
        dArr(K, 4) = Dai
        dArr(K, 5) = CTD
        dArr(K, 6) = sType
        dArr(K, 7) = Side
    Next
Next
ExtractToSheet = Application.InputBox("Ðiê`n tên sheet", "Xuât Kêt Qua", "Fill auto", Type:=2)
With Sheets(ExtractToSheet)
.Range("A10000").End(xlUp).Offset(2).Resize(10000, 7).ClearContents
.Range("A10000").End(xlUp).Offset(2).Resize(K, 7) = dArr
End With
End Sub
Uk bạn,
+ sheet nhập liệu khi chạy code , bạn sửa giúp mình khi có data cột c là run data cột đó=> mình không cần phải chọn vùng=> run xong mk sẽ xóa đi và lần sau lại update data mới vào cột c( coi như sheet này chỉ để nhập liệu hàng ngày)
+ sheet kết quả thì khi run sẽ điền vào dòng tiếp theo
 
Lần chỉnh sửa cuối:
Upvote 0
Uk bạn,
+ sheet nhập liệu khi chạy code , bạn sửa giúp mình khi có data cột c là run data cột đó=> mình không cần phải chọn vùng=> run xong mk sẽ xóa đi và lần sau lại update data mới vào cột c( coi như sheet này chỉ để nhập liệu hàng ngày)
+ sheet kết quả thì khi run sẽ điền vào dòng tiếp theo
Tôi không thích thêm bớt ý tưởng kiểu như này, rõ ràng một lần luôn để chỉnh
Bạn tạo lại file gồm sheet data (để nhập liệu), sheet KQ (để ghi kết quả)
Muốn kết quả ghi vào sheet KQ từ dòng nào ghi chú rõ ra (và có cần phải chọn sheet để ghi kết quả hay không, hay chỉ cần ghi vào sheet KQ là được?)
 
Upvote 0
..., hình như là "dựng lại regex tốn bộ nhớ hay làm giảm tốc độ" gì đó thì phải
1. tốn bộ nhớ: tuỳ theo hàm được gọi bằng cách nào.
- nếu dùng bộ nhớ chung (heap - biến toàn cục hoặc biến static) thì nó luôn nằm đó. Và sẽ tốn bộ nhớ cho nó hơn là gọi hàm xong thì giải phóng đi.
- nếu dùng bộ nhớ ngăn xếp (stack - biến nội bộ) thì nó sẽ được giải phóng sau khi hàm chạy xong. Tuy nhiên, nếu hàm chưa chạy xong (gọi hàm khác, đệ quy) thì nó còn nằm đó, đệ quy vài vòng sẽ hết bộ nhớ ngăn xếp.
2. giảm tốc độ: nếu bộ nhớ lớn thì tuy chương trình "giải phóng bộ nhớ" nhưng nó vẫn còn nằm đó. Lúc cần nhập trở lại thì nhập cũng khá nhanh - Hệ thống (Windows) chỉ cần nối lại các địa chỉ hàm, tham số,... . Các phương tiện của VBScript hầu hết là COM, Windows biết cách tối ưu cách trữ trong bộ nhớ. Cái khác nhau là:
(a) nếu máy xịn, Windows sẽ có khuynh hướng đưa các COM vào phần cache (phần truy vấn trực tiếp nhanh của Processor) và sẽ chạy nhanh hơn.
(b) với các hệ thống hiệu quả, chính cái cỗ máy Regex sẽ "nhớ" các chi tiết trước đó và làm việc hiệu quả hơn. Trong trường hợp này thì giữ nó lại, không giải phóng thì nó sẽ làm việc hiệu quả hơn.

Tuy nhiên, những điều trên chỉ là lý thuyết lập trình. Nếu một dối tượng (COM object) được sử dụng cả trăm cả ngàn lần thì giữ nó đừng giải phóng là chuyện tập thói quen tốt thôi.
 
Upvote 0
1. tốn bộ nhớ: tuỳ theo hàm được gọi bằng cách nào.
- nếu dùng bộ nhớ chung (heap - biến toàn cục hoặc biến static) thì nó luôn nằm đó. Và sẽ tốn bộ nhớ cho nó hơn là gọi hàm xong thì giải phóng đi.
- nếu dùng bộ nhớ ngăn xếp (stack - biến nội bộ) thì nó sẽ được giải phóng sau khi hàm chạy xong. Tuy nhiên, nếu hàm chưa chạy xong (gọi hàm khác, đệ quy) thì nó còn nằm đó, đệ quy vài vòng sẽ hết bộ nhớ ngăn xếp.
2. giảm tốc độ: nếu bộ nhớ lớn thì tuy chương trình "giải phóng bộ nhớ" nhưng nó vẫn còn nằm đó. Lúc cần nhập trở lại thì nhập cũng khá nhanh - Hệ thống (Windows) chỉ cần nối lại các địa chỉ hàm, tham số,... . Các phương tiện của VBScript hầu hết là COM, Windows biết cách tối ưu cách trữ trong bộ nhớ. Cái khác nhau là:
(a) nếu máy xịn, Windows sẽ có khuynh hướng đưa các COM vào phần cache (phần truy vấn trực tiếp nhanh của Processor) và sẽ chạy nhanh hơn.
(b) với các hệ thống hiệu quả, chính cái cỗ máy Regex sẽ "nhớ" các chi tiết trước đó và làm việc hiệu quả hơn. Trong trường hợp này thì giữ nó lại, không giải phóng thì nó sẽ làm việc hiệu quả hơn.

Tuy nhiên, những điều trên chỉ là lý thuyết lập trình. Nếu một dối tượng (COM object) được sử dụng cả trăm cả ngàn lần thì giữ nó đừng giải phóng là chuyện tập thói quen tốt thôi.
Cảm ơn bác đã chia sẻ
 
Upvote 0
Tôi không thích thêm bớt ý tưởng kiểu như này, rõ ràng một lần luôn để chỉnh
Bạn tạo lại file gồm sheet data (để nhập liệu), sheet KQ (để ghi kết quả)
Muốn kết quả ghi vào sheet KQ từ dòng nào ghi chú rõ ra (và có cần phải chọn sheet để ghi kết quả hay không, hay chỉ cần ghi vào sheet KQ là được?)
ok bạn ,mình gửi lại file bạn giúp mình hoàn thành nốt nhé
Sheet nhập liệu (data mình sẽ paste vào cột C, số lượng dòng tùy ý, không phải chọn vùng dữ liệu như code cũ) => Run code sẽ tự nhận data có trong các dòng ở cột c và tách ra Sheet KQ=> run code xong thì sẽ nhảy sang sheet KQ để mình có thể xem KQ bên sheet KQ.=> Sheet kết quả mỗi lần nhấn chạy code thì dữ liệu sẽ nằm dòng kế tiếp của lần run trước đó(ví dụ lần 1 run tới dòng 12, lần 2 run data vào dòng 13 trở đi, cứ thế lần lượt)
Mình cảm ơn nhé!!!
 

File đính kèm

  • TEST FILL DOWN_V03.xlsm
    25.4 KB · Đọc: 2
Upvote 0
ok bạn ,mình gửi lại file bạn giúp mình hoàn thành nốt nhé
Sheet nhập liệu (data mình sẽ paste vào cột C, số lượng dòng tùy ý, không phải chọn vùng dữ liệu như code cũ) => Run code sẽ tự nhận data có trong các dòng ở cột c và tách ra Sheet KQ=> run code xong thì sẽ nhảy sang sheet KQ để mình có thể xem KQ bên sheet KQ.=> Sheet kết quả mỗi lần nhấn chạy code thì dữ liệu sẽ nằm dòng kế tiếp của lần run trước đó(ví dụ lần 1 run tới dòng 12, lần 2 run data vào dòng 13 trở đi, cứ thế lần lượt)
Mình cảm ơn nhé!!!
Chú ý, do yêu cầu của bạn là ghi dữ liệu kế tiếp, do đó với cùng 1 dữ liệu ở sheet NhapLieu, nếu bấm Run Code button 2 lần thì sẽ cho ra 2 lần kết quả bên sheet KQ
 

File đính kèm

  • TEST FILL DOWN_V03.xlsm
    24.9 KB · Đọc: 8
Upvote 0
ok bạn ,mình gửi lại file bạn giúp mình hoàn thành nốt nhé
Sheet nhập liệu (data mình sẽ paste vào cột C, số lượng dòng tùy ý, không phải chọn vùng dữ liệu như code cũ) => Run code sẽ tự nhận data có trong các dòng ở cột c và tách ra Sheet KQ=> run code xong thì sẽ nhảy sang sheet KQ để mình có thể xem KQ bên sheet KQ.=> Sheet kết quả mỗi lần nhấn chạy code thì dữ liệu sẽ nằm dòng kế tiếp của lần run trước đó(ví dụ lần 1 run tới dòng 12, lần 2 run data vào dòng 13 trở đi, cứ thế lần lượt)
Mình cảm ơn nhé!!!
Ok bạn, cái này mình kiểm soát được, miễn là kết quả cứ nối tiếp nhau và stt cũng tự động +1 sau mỗi lần run code là được bạn ạ
 
Upvote 0
Mình cảm ơn bạn nhé, mình test ok rồi
Lần sau có trích dẫn thì trích dẫn bài của tôi, lỡ hỏi giúp đỡ gì tôi còn có thông báo, biết để vào xem lại cho bạn. Cả 2 bài #15 và #16 bạn đầu trích dẫn câu của bạn rồi trả lời, tôi đâu có biết. Rút kinh nghiệm cho những bài sau này nhé
 
Upvote 0
Lần sau có trích dẫn thì trích dẫn bài của tôi, lỡ hỏi giúp đỡ gì tôi còn có thông báo, biết để vào xem lại cho bạn. Cả 2 bài #15 và #16 bạn đầu trích dẫn câu của bạn rồi trả lời, tôi đâu có biết. Rút kinh nghiệm cho những bài sau này nhé
Ok bạn, mình cảm ơn nhé, mình rút kinh nghiệm lần sau
 
Upvote 0
Chú ý, do yêu cầu của bạn là ghi dữ liệu kế tiếp, do đó với cùng 1 dữ liệu ở sheet NhapLieu, nếu bấm Run Code button 2 lần thì sẽ cho ra 2 lần kết quả bên sheet KQ
Mình nhờ bạn thêm chút nữa. Sau này mình có thể mở rộng thêm dữ liệu, code hiện tại chỉ copy từ cột A tới cột G, bạn tối ưu code giúp mình có thể copy data từ cột A tới cột K " Sheet nhap lieu" để sau này mình có thể thêm trường dữ liệu túy ý, file mình upload bên dưới nhé

1608043348455.png
1608043376820.png
 

File đính kèm

  • TEST FILL DOWN_V003.xlsm
    39.9 KB · Đọc: 4
Upvote 0
Mình nhờ bạn thêm chút nữa. Sau này mình có thể mở rộng thêm dữ liệu, code hiện tại chỉ copy từ cột A tới cột G, bạn tối ưu code giúp mình có thể copy data từ cột A tới cột K " Sheet nhap lieu" để sau này mình có thể thêm trường dữ liệu túy ý, file mình upload bên dưới nhé

View attachment 251282
View attachment 251283
Do tôi thấy bạn có thay đổi tên sheet xuất kết quả (mà bạn không biết nên sửa cả function), nên rong code tôi thêm đoạn này:
Mã:
Set Ws = Sheets("KQ")
Nếu bạn muốn thay đổi xuất kết quả sang sheet khác thì sửa tên sheet trong dấu ngoặc kép, còn lại không thay đổi gì
 

File đính kèm

  • TEST FILL DOWN_V003.xlsm
    33.3 KB · Đọc: 17
Upvote 0
Web KT

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

Back
Top Bottom