Chuyên mục xử lý, gỡ rối code VBA

Liên hệ QC
Status
Không mở trả lời sau này.

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,924
Tôi là thành viên mới thấy mục này quá hay, bản thân cũng đang tập tành học code, nhưng có 1 số code trong file tôi chưa biết viết thế nào, mong các Bác giúp dùm, cụ thể như sau:
Tôi đang làm 1 file excel để theo dõi đơn nhưng đang vướng chưa biết chuyển hàm thành code cụ thể thế nào, mong các Bác giúp đỡ thêm để tôi hoàn thiện.. Cụ thể theo file gửi kèm tôi chưa biết dùng code thế nào như sau:
- Với Sheet XLD:
+ Nếu các ô tại cột I và cột F của dòng đang nhập liệu khác rỗng và nếu ô tại cột F,H,I khi nhập có dữ liệu trùng với dữ liệu tại cột F,H,I ở dòng trên thì đánh dấu X vào cột Q của dòng đang nhập liệu (khi sửa nội dung dòng bất kỳ mà không trùng nữa thì bỏ dấu X).
+ Và tại cột S đánh dấu X nếu như tại dòng đó mà các cột A,B,C,D,E,F,G,H có dữ liệu và các cột I,J,K,L,M,N,O rỗng.
- Với sheet TD TQUYEN:
+ Nếu cột G khác rỗng và nếu các ô thuộc cột E,G của sheet TD TQUYEN bằng với các ô thuôc cột F,I của sheet XLD thì đếm số ô trùng nhau của cột I thuộc sheet XLD và đưa kết quả vào cột AA của sheet TD TQUYEN tại dòng trùng nhau.

Do dữ liệu tôi nhập rất lớn mà dùng hàm thì file quá nặng mà đang chưa biết viết code như thế nào, mong các Bác giúp đỡ, tôi cảm ơn rất nhiều. (Không biết đăng bài nhờ giúp ở đâu nên đăng ở đây có gì không đúng mong các Bác bỏ qua cho).
 

File đính kèm

  • nhapdon.xlsm
    1.6 MB · Đọc: 10
Upvote 0
Gửi các anh, chị em
Tôi có lắp ghép được 1 đoạn code vào trong file như file đính kèm với mục đích khi mở file code sẽ rà các ô chỉ định có ngày chênh lệch với ngày hiện tại quá 30 nó sẽ gửi email qua Outlook
Khi code chạy, dù rất nhiều ô thỏa mãn việc phải gửi email, nhưng thực tế chỉ có khoảng 15 ô (15 email) được gửi.
Tôi không biết code thiếu hoặc nhầm cái gì mà không phải tất cả các ô thỏa mãn điều kiện thì được nhắc nhở bằng email
Mong các anh chị em kiểm tra giúp.
Xin cảm ơn
 

File đính kèm

  • gpe_email.xlsb
    160.3 KB · Đọc: 9
Upvote 0
Chào Anh/Chị trong GPE!

Em có xem trên mạng video về lập trình nhập liệu VBA hay nên đã ứng dụng vào công việc của mình. Do chưa biết gì về VBA nên chỉ làm theo hướng dẫn của video, Khi làm thì có một số lỗi nên đã giải quyết thủ công nên code không được tối ưu,
Nên em Up lên này nhờ Anh/Chị Code lại cho tối ưu giúp em với nhé.
Cảm ơn nhiều!
 

File đính kèm

  • nhaplieu1.xlsm
    270.3 KB · Đọc: 8
Upvote 0
Em chào mọi người, em có 1 file excel được export từ phần mềm ra, trước khi đến khâu tính toán thì phải xử lý dữ liệu thô. Mà dữ liệu thì lặp đi lặp lại, em ngồi copy cả ngày mới xong. Em nghe nói excel có macro chuyên xử lý những thao tác lặp đi lặp lại, tuy nhiên em không rõ về nó.
B1. Ở sheet "Before" Em copy toàn bộ cell màu đỏ ở cột G vào cột B tương ứng với thông tin của nhân viên ( cái này lâu nhất ).
B2. Xóa các cột và hàng màu em bôi màu vàng đi cho đỡ rối mắt
B3. Text to colums những mã mà em vừa copy xuống.
Như vậy em có file ở bên Sheet " After ".
Mọi người giúp em với. Em cám ơn.
 

File đính kèm

  • 1111111111111.xlsx
    18.1 KB · Đọc: 8
Upvote 0
Em chào mọi người, em có 1 file excel được export từ phần mềm ra, trước khi đến khâu tính toán thì phải xử lý dữ liệu thô. Mà dữ liệu thì lặp đi lặp lại, em ngồi copy cả ngày mới xong. Em nghe nói excel có macro chuyên xử lý những thao tác lặp đi lặp lại, tuy nhiên em không rõ về nó.
B1. Ở sheet "Before" Em copy toàn bộ cell màu đỏ ở cột G vào cột B tương ứng với thông tin của nhân viên ( cái này lâu nhất ).
B2. Xóa các cột và hàng màu em bôi màu vàng đi cho đỡ rối mắt
B3. Text to colums những mã mà em vừa copy xuống.
Như vậy em có file ở bên Sheet " After ".
Mọi người giúp em với. Em cám ơn.
Xem file
 

File đính kèm

  • Copys.xlsm
    26.1 KB · Đọc: 9
Upvote 0
Tôi là thành viên mới thấy mục này quá hay, bản thân cũng đang tập tành học code, nhưng có 1 số code trong file tôi chưa biết viết thế nào, mong các Bác giúp dùm, cụ thể như sau:
Tôi đang làm 1 file excel để theo dõi đơn nhưng đang vướng chưa biết chuyển hàm thành code cụ thể thế nào, mong các Bác giúp đỡ thêm để tôi hoàn thiện.. Cụ thể theo file gửi kèm tôi chưa biết dùng code thế nào như sau:
- Với Sheet XLD:
+ Nếu các ô tại cột I và cột F của dòng đang nhập liệu khác rỗng và nếu ô tại cột F,H,I khi nhập có dữ liệu trùng với dữ liệu tại cột F,H,I ở dòng trên thì đánh dấu X vào cột Q của dòng đang nhập liệu (khi sửa nội dung dòng bất kỳ mà không trùng nữa thì bỏ dấu X).
+ Và tại cột S đánh dấu X nếu như tại dòng đó mà các cột A,B,C,D,E,F,G,H có dữ liệu và các cột I,J,K,L,M,N,O rỗng.
- Với sheet TD TQUYEN:
+ Nếu cột G khác rỗng và nếu các ô thuộc cột E,G của sheet TD TQUYEN bằng với các ô thuôc cột F,I của sheet XLD thì đếm số ô trùng nhau của cột I thuộc sheet XLD và đưa kết quả vào cột AA của sheet TD TQUYEN tại dòng trùng nhau.

Do dữ liệu tôi nhập rất lớn mà dùng hàm thì file quá nặng mà đang chưa biết viết code như thế nào, mong các Bác giúp đỡ, tôi cảm ơn rất nhiều. (Không biết đăng bài nhờ giúp ở đâu nên đăng ở đây có gì không đúng mong các Bác bỏ qua cho).
Nội dung theo dõi về tố cáo, khiếu nại trước đây (khoảng 7 năm) tôi viết hẳn 1 File theo dõi cho cơ quan, nhưng rất tiếc cơ quan không dùng (lý do đã có phần mềm theo dõi), để tôi tìm lại và sửa cho phù hợp cái bạn cần. Vậy, bạn hãy chờ tôi tìm (giờ không nhớ để nó ở cái xó nào).
 
Upvote 0
Nội dung theo dõi về tố cáo, khiếu nại trước đây (khoảng 7 năm) tôi viết hẳn 1 File theo dõi cho cơ quan, nhưng rất tiếc cơ quan không dùng (lý do đã có phần mềm theo dõi), để tôi tìm lại và sửa cho phù hợp cái bạn cần. Vậy, bạn hãy chờ tôi tìm (giờ không nhớ để nó ở cái xó nào).
Em cám ơn anh, em chưa thấy ở đâu mọi người nhiệt tình như ở GPE :D

Em cám ơn anh. Nhưng mỗi lần em xuất file từ phần mềm ra excel tên sheet sẽ không là "Before" và "After" ( em đặt vậy để trình bày cho mọi người dễ hiểu ). Có cách nào mà mình chạy thì nó cho sang sheet mới không anh ? Cột mã số em làm text to colums theo cột cũng nhanh thôi.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Em cám ơn anh. Nhưng mỗi lần em xuất file từ phần mềm ra excel tên sheet sẽ không là "Before" và "After" ( em đặt vậy để trình bày cho mọi người dễ hiểu ). Có cách nào mà mình chạy thì nó cho sang sheet mới không anh ? Cột mã số em làm text to colums theo cột cũng nhanh thôi.
Tên sheet xuất từ phần mềm cố định hay thay đổi? tên sheet tạo mới đặt tên như thế nào?
 
Upvote 0
Em cám ơn anh. Nhưng mỗi lần em xuất file từ phần mềm ra excel tên sheet sẽ không là "Before" và "After" ( em đặt vậy để trình bày cho mọi người dễ hiểu ). Có cách nào mà mình chạy thì nó cho sang sheet mới không anh ? Cột mã số em làm text to colums theo cột cũng nhanh thôi.
Vậy thì bạn nên đưa vài cái File xuất từ phần mềm ra excel lên đây thử xem, biết quy luật thì mới tính tiếp được.

Lưu ý: Mỗi sheet chứa khoảng 20 dòng dữ liệu là được (còn tên sheet là gì không quan trọng).
 
Upvote 0
Vậy thì bạn nên đưa vài cái File xuất từ phần mềm ra excel lên đây thử xem, biết quy luật thì mới tính tiếp được.

Lưu ý: Mỗi sheet chứa khoảng 20 dòng dữ liệu là được (còn tên sheet là gì không quan trọng).
Tên sheet thì sẽ là tên file mình đặt, mình đặt gì cũng đc. Chỉ có 1 sheet duy nhất giống như sheet “before” đó ạ. Tuy nhiên nếu hiện tại ( dùng code của anh HieuCD ) khi em export file mới, em sẽ phải xoá các cột đi để lấy đc hàng tiêu đề mẫu và copy sang sheet mới và đặt tên là after. Em cám ơn
 
Lần chỉnh sửa cuối:
Upvote 0
Chạy code mới
Mã:
Sub CopyData()
  Dim Rng As Range
  Dim Id As Long, i As Long, lRow As Long
  Const Str = "Personnel Number:"
  Application.ScreenUpdating = False
  Sheets("Before").Copy After:=Sheets(Sheets.Count)
  ActiveSheet.Name = "After" & Sheets.Count - 1 'Chinh lai tên Sheet
 
  lRow = Range("C" & Rows.Count).End(xlUp).Row
  Set Rng = Cells(1, 1)
  For i = 2 To lRow
    If Cells(i, 2) = Str Then Id = Cells(i, 7)
    If IsNumeric(Mid(Cells(i, 3), 1, 2)) Then
      Cells(i, 2) = Id
    Else
      If i <> 11 Then Set Rng = Union(Rng, Cells(i, 1))
    End If
  Next i
  Rng.EntireRow.Delete
  Range("A:A,E:E,I:I,N:N,P:P,R:X,Z:Z,AB:AB,AD:AF,AO:AQ,BA:BA").EntireColumn.Delete
  Set Rng = Nothing
  Application.ScreenUpdating = True
End Sub
 

File đính kèm

  • Copys.xlsm
    25 KB · Đọc: 8
Upvote 0
Xin chào các bạn

Tôi có một đoạn code như sau:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row >= 9 And Target.Row <= 16 And Target.Column = 6 Then
With Target.Offset(, -2)
.FormulaR1C1 = "=RC[2]"
.Value = .Value
End With
End If
If Target.Row >= 9 And Target.Row <= 16 And Target.Column = 4 Then
With Target.Offset(, 2)
.FormulaR1C1 = "=RC[-2]"
.Value = .Value
End With
End If
End Sub

Nếu tôi xóa 1 trong 2 cái If thì code chạy không vấn đề gì, nhưng khi tôi để cả 2 cái if cùng chạy thì code bị lỗi.

Nhờ các bạn xử lý giúp ạ.
 

File đính kèm

  • Book1.xls
    34.5 KB · Đọc: 4
Upvote 0
Xin chào các bạn

Tôi có một đoạn code như sau:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row >= 9 And Target.Row <= 16 And Target.Column = 6 Then
With Target.Offset(, -2)
.FormulaR1C1 = "=RC[2]"
.Value = .Value
End With
End If
If Target.Row >= 9 And Target.Row <= 16 And Target.Column = 4 Then
With Target.Offset(, 2)
.FormulaR1C1 = "=RC[-2]"
.Value = .Value
End With
End If
End Sub

Nếu tôi xóa 1 trong 2 cái If thì code chạy không vấn đề gì, nhưng khi tôi để cả 2 cái if cùng chạy thì code bị lỗi.

Nhờ các bạn xử lý giúp ạ.
Code vậy không được vì sẽ bị tham chiếu vòng. Cứ gán giá trị trực tiếp luôn thay vì gán công thức
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Application.EnableEvents = False
  If Target.Row >= 9 And Target.Row <= 16 Then
    If Target.Column = 6 Then Target.Offset(, -2).Value = Target.Value
    If Target.Column = 4 Then Target.Offset(, 2).Value = Target.Value
  End If
  Application.EnableEvents = True
End Sub
 
Upvote 0
Code vậy không được vì sẽ bị tham chiếu vòng. Cứ gán giá trị trực tiếp luôn thay vì gán công thức
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Application.EnableEvents = False
  If Target.Row >= 9 And Target.Row <= 16 Then
    If Target.Column = 6 Then Target.Offset(, -2).Value = Target.Value
    If Target.Column = 4 Then Target.Offset(, 2).Value = Target.Value
  End If
  Application.EnableEvents = True
End Sub

Cảm ơn ndu96081631 đã giúp đỡ.
Nhờ bạn xử lý giúp tôi cho trường hợp này ạ.
 

File đính kèm

  • Book1.xls
    35 KB · Đọc: 7
Upvote 0
Cảm ơn ndu96081631 đã giúp đỡ.
Nhờ bạn xử lý giúp tôi cho trường hợp này ạ.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Target.Row >= 9 And Target.Row <= 16 Then
    If Target.Column = 6 Then
        With Target.Offset(, -2)
            .FormulaR1C1 = "=INDEX(R9C10:R16C10,MATCH(RC[2],R9C11:R16C11,0))"
            .Value = .Value
        End With
    End If
    If Target.Column = 4 Then
        With Target.Offset(, 2)
            .FormulaR1C1 = "=INDEX(R9C11:R16C11,MATCH(RC[-2],R9C10:R16C10,0))"
            .Value = .Value
        End With
    End If
End If
Application.EnableEvents = True
End Sub
 
Upvote 0
Nội dung theo dõi về tố cáo, khiếu nại trước đây (khoảng 7 năm) tôi viết hẳn 1 File theo dõi cho cơ quan, nhưng rất tiếc cơ quan không dùng (lý do đã có phần mềm theo dõi), để tôi tìm lại và sửa cho phù hợp cái bạn cần. Vậy, bạn hãy chờ tôi tìm (giờ không nhớ để nó ở cái xó nào).
Cảm ơn bạn.
 
Upvote 0
Cảm ơn ndu96081631 đã giúp đỡ.
Nhờ bạn xử lý giúp tôi cho trường hợp này ạ.
Vẫn quan điểm ở trên: Tuyệt đối không nên gán công thức vào Target khi thực hiện sự kiện Change (dễ bị lỗi) mà nên tính toán trực tiếp trong code
Ví dụ:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim rngFind As Range, cel As Range
  Dim lOffset1 As Long, lOffset2 As Long, lOffset3 As Long
  Application.EnableEvents = False
  On Error Resume Next
  If Target.Row >= 9 And Target.Row <= 16 Then
    If Target.Column = 4 Then lOffset1 = 1
    If Target.Column = 6 Then lOffset1 = -1
    If lOffset1 Then
      lOffset2 = (1 - lOffset1) / 2
      lOffset3 = lOffset1 * 2
      For Each cel In Target
        If cel.Column = 4 Or cel.Column = 6 Then
          Set rngFind = Range("DANHSACH").Resize(, 1).Offset(, lOffset2).Find(cel.Value, , xlValues, xlWhole)
          If Not rngFind Is Nothing Then
            cel.Offset(, lOffset3).Value = rngFind.Offset(, lOffset1).Value
          Else
            cel.Offset(, lOffset3).ClearContents
          End If
        End If
      Next
    End If
  End If
  If Err.Number Then MsgBox Err.Description
  Application.EnableEvents = True
End Sub
Trong đó:
- DANHSACH chính là Define name của vùng J9:K16 (bạn tự đặt)
- lOffset1, lOffset2 và lOffset3 là các con số dùng để dịch chuyển cột sang trái hoặc phải (tự tính cho phù hợp)
----------------------------------
Ngoài ra có 1 lưu ý quan trọng: Khi sự kiện Change thực hiện sự thay đổi ngay trên Target thì bắt buộc phải có cặp lệnh: Application.EnableEvents = False ở đầu code và Application.EnableEvents = True ở cuối code, nếu không sẽ có lúc rơi vào "vòng lập vô tân". Có nghĩa là:
- Khi ta thay đổi trên sheet thì code sự kiện sẽ chạy
- Code chạy làm thay đổi giá trị trên sheet
- Sự thay đổi giá trị trên sheet mà giá trị này nằm ngay vùng Target sẽ làm code chạy tiếp

.... cứ thế mãi không ngừng đến lúc treo máy mới thôi
----------------------------------
Code ở trên dài thế vì:
- Nó còn làm được việc cho phép copy paste nhiều cell cùng lúc
- Khi xóa cột này thì cột kia sẽ bị xóa theo
- vân vân...
 

File đính kèm

  • Tracuucheo.xls
    38.5 KB · Đọc: 11
Upvote 0
Vẫn quan điểm ở trên: Tuyệt đối không nên gán công thức vào Target khi thực hiện sự kiện Change (dễ bị lỗi) mà nên tính toán trực tiếp trong code
Ví dụ:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim rngFind As Range, cel As Range
  Dim lOffset1 As Long, lOffset2 As Long, lOffset3 As Long
  Application.EnableEvents = False
  On Error Resume Next
  If Target.Row >= 9 And Target.Row <= 16 Then
    If Target.Column = 4 Then lOffset1 = 1
    If Target.Column = 6 Then lOffset1 = -1
    If lOffset1 Then
      lOffset2 = (1 - lOffset1) / 2
      lOffset3 = lOffset1 * 2
      For Each cel In Target
        If cel.Column = 4 Or cel.Column = 6 Then
          Set rngFind = Range("DANHSACH").Resize(, 1).Offset(, lOffset2).Find(cel.Value, , xlValues, xlWhole)
          If Not rngFind Is Nothing Then
            cel.Offset(, lOffset3).Value = rngFind.Offset(, lOffset1).Value
          Else
            cel.Offset(, lOffset3).ClearContents
          End If
        End If
      Next
    End If
  End If
  If Err.Number Then MsgBox Err.Description
  Application.EnableEvents = True
End Sub
Trong đó:
- DANHSACH chính là Define name của vùng J9:K16 (bạn tự đặt)
- lOffset1, lOffset2 và lOffset3 là các con số dùng để dịch chuyển cột sang trái hoặc phải (tự tính cho phù hợp)
----------------------------------
Ngoài ra có 1 lưu ý quan trọng: Khi sự kiện Change thực hiện sự thay đổi ngay trên Target thì bắt buộc phải có cặp lệnh: Application.EnableEvents = False ở đầu code và Application.EnableEvents = True ở cuối code, nếu không sẽ có lúc rơi vào "vòng lập vô tân". Có nghĩa là:
- Khi ta thay đổi trên sheet thì code sự kiện sẽ chạy
- Code chạy làm thay đổi giá trị trên sheet
- Sự thay đổi giá trị trên sheet mà giá trị này nằm ngay vùng Target sẽ làm code chạy tiếp

.... cứ thế mãi không ngừng đến lúc treo máy mới thôi
----------------------------------
Code ở trên dài thế vì:
- Nó còn làm được việc cho phép copy paste nhiều cell cùng lúc
- Khi xóa cột này thì cột kia sẽ bị xóa theo
- vân vân...

Cảm ndu96081631 nhiều nhé,
ở bài trước Oanh Thơ định thắc mắc về Application.EnableEvents = False chưa kịp hỏi thì đã được bạn giải thích rõ ràng và giúp đỡ phương pháp tối hơn.
Khi áp dụng nếu có vấn đề gì rất mong lại được hỗ trợ ạ.
 
Upvote 0
Mọi người gỡ rối giúp code này với. Mình viết code VBA chèn công thức vào vùng từ G3:G66 với dữ liệu được chọn từ F3:F66
Nhưng khi chạy code nó copy công thức cho hết nguyên cột G. Giờ muốn nó chạy tới G66 thôi thì sao vậy các bác
Mã:
    With ShTrangChu.Range("g3:g66" & [f66].End(3).Row)
        .Value = "=IF(RC[-1]=0,0,HLOOKUP(R2C2,Data!R2C3:R180C250,MATCH(RC[-1],Data!R2C2:R198C2,0),0))"
        .Value = "'" & .Value
    End With
 
Upvote 0
Status
Không mở trả lời sau này.
Web KT
Back
Top Bottom