Sự kiện trong worksheet không được tối ưu

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

Nhật Anh 9x

Thành viên chính thức
Tham gia
21/10/22
Bài viết
72
Được thích
3
Em chào tất cả anh chị

Em đang gặp phải một vấn đề rất mong được anh chị giúp đỡ ạ!

Em muốn viết sự kiện cho worksheet này là khi em thay đổi giá trị ở cột I và cột M cụ thể là các dòng màu trắng thì
số liệu ở dòng màu tím và màu vàng từ cột I đến cột N sẽ tự động tính tổng lại, cột N = cột I - cột M ; cột J = Cột G - cột I.
Code em viết có vẻ hơi loằng ngoằng và cũng chưa đúng ạ . Khi chẳng may em kích vào cột I dòng màu tím hoặc màu vàng (ví dụ I3 , I5)
thì code của em lại báo lỗi, và khi em xoá dòng trong khoảng từ dòng 4 đến dòng 26 cũng xảy ra lỗi

Em rất mong anh chị chỉ dạy giúp em, em xin cảm ơn ạ!

1692762804113.png
 

File đính kèm

  • test23.xlsm
    32 KB · Đọc: 7
Tại sao phải dùng VBA vậy bạn? Nếu muốn tự động hóa công thức thì bạn có thể dùng như sau:
Vì cấu trúc của bạn dạng nhiều cấp, Cấp 1 là dòng cuối cùng, Cấp 2 là dòng màu vàng, cấp 3 là dòng màu xanh.
Tại cấp 3, ví dụ dòng 24:
I24
Mã:
=SUBTOTAL(9,I25:I$26)*2-SUM(I25:I$26)
copy I24 sang M24
J24
Mã:
=G24-I24
N24
Mã:
=I24-M24
Copy J24:N24 lên các dòng khác đồng cấp (4,11,14,18,21)
Cấp 2, dòng 3
I3
Mã:
=SUM(I4:I26)/2
Copy sang M3
Dòng tổng cuối cùng tại I27: Sumif theo cột A với điều kiện không trống
Mã:
=SUMIF($A$3:$A$26,"<>",I3:I26)
Như vậy, bảng của bạn đã được tự động hóa.
Vì trong file , có 1 Cấp 2 và sẽ có nhiều Cấp 2 nữa trong file thực tế. Do đó, tại các dòng cấp 2, bạn cần tùy chỉnh lại phạm vi vùng cho chính xác.
 

File đính kèm

  • test23.xlsm
    16.9 KB · Đọc: 5
Upvote 0
Tại sao phải dùng VBA vậy bạn? Nếu muốn tự động hóa công thức thì bạn có thể dùng như sau:
Vì cấu trúc của bạn dạng nhiều cấp, Cấp 1 là dòng cuối cùng, Cấp 2 là dòng màu vàng, cấp 3 là dòng màu xanh.
Tại cấp 3, ví dụ dòng 24:
I24
Mã:
=SUBTOTAL(9,I25:I$26)*2-SUM(I25:I$26)
copy I24 sang M24
J24
Mã:
=G24-I24
N24
Mã:
=I24-M24
Copy J24:N24 lên các dòng khác đồng cấp (4,11,14,18,21)
Cấp 2, dòng 3
I3
Mã:
=SUM(I4:I26)/2
Copy sang M3
Dòng tổng cuối cùng tại I27: Sumif theo cột A với điều kiện không trống
Mã:
=SUMIF($A$3:$A$26,"<>",I3:I26)
Như vậy, bảng của bạn đã được tự động hóa.
Vì trong file , có 1 Cấp 2 và sẽ có nhiều Cấp 2 nữa trong file thực tế. Do đó, tại các dòng cấp 2, bạn cần tùy chỉnh lại phạm vi vùng cho chính xác.
Em cảm ơn Anh, nhưng em mong nếu được Các Anh hỗ trợ về code bài này thì tốt quá ạ. Em sẽ được học hỏi về viết sự kiện trong worksheet ạ
 
Upvote 0
Em cảm ơn Anh, nhưng em mong nếu được Các Anh hỗ trợ về code bài này thì tốt quá ạ. Em sẽ được học hỏi về viết sự kiện trong worksheet ạ
Phần nào dùng được hàm excel ngắn gọn thì không nên dùng code, để học hỏi về viết sự kiện trong worksheets thì tìm hiểu trên diễn đàn khá nhiều rồi.
 
Upvote 0
Em chào tất cả anh chị

Em đang gặp phải một vấn đề rất mong được anh chị giúp đỡ ạ!

Em muốn viết sự kiện cho worksheet này là khi em thay đổi giá trị ở cột I và cột M cụ thể là các dòng màu trắng thì
số liệu ở dòng màu tím và màu vàng từ cột I đến cột N sẽ tự động tính tổng lại, cột N = cột I - cột M ; cột J = Cột G - cột I.
Code em viết có vẻ hơi loằng ngoằng và cũng chưa đúng ạ . Khi chẳng may em kích vào cột I dòng màu tím hoặc màu vàng (ví dụ I3 , I5)
thì code của em lại báo lỗi, và khi em xoá dòng trong khoảng từ dòng 4 đến dòng 26 cũng xảy ra lỗi

Em rất mong anh chị chỉ dạy giúp em, em xin cảm ơn ạ!

View attachment 294123
@Maika8008 Anh có thể xem giúp em bài này được không ạ!
 
Upvote 0
@Maika8008 Anh có thể xem giúp em bài này được không ạ!
Bạn đang làm một việc không nên làm là viết code VBA tính lại hết bảng dữ liệu trong khi chỉ cần đặt công thức. Học sự kiện đâu phải học như vậy. Trong ví dụ mới chỉ có mục I thì sẽ có II, III tiếp theo nên giả như có ai đó viết code cho bạn thì với khả năng của bạn làm sao sửa code để dùng cho bảng dữ liệu thực của bạn được.
 
Upvote 0
Bạn đang làm một việc không nên làm là viết code VBA tính lại hết bảng dữ liệu trong khi chỉ cần đặt công thức. Học sự kiện đâu phải học như vậy. Trong ví dụ mới chỉ có mục I thì sẽ có II, III tiếp theo nên giả như có ai đó viết code cho bạn thì với khả năng của bạn làm sao sửa code để dùng cho bảng dữ liệu thực của bạn được.
Vâng em cảm ơn Anh đã tư vấn ạ!
 
Upvote 0
Vâng em cảm ơn Anh đã tư vấn ạ!
Nếu muốn học sự kiện thì tôi chỉ cho bạn cách đặt điều kiện cho sự kiện Worksheet_Change trong trường hợp của bạn:
Rich (BB code):
    If (Target.Column = 9 Or Target.Column = 13) And Target.Row > 4 And Target.Count = 1 Then
        If Cells(Target.Row, 1) = "" Then   'Nếu là dòng chi tiết thì mới thi hành
            'Code của bạn
        End If
    End If

Ngoài ra, bạn phải dùng sự kiện Worksheet_SelectionChange để lấy được 3 giá trị của dòng chứa Target trước khi chúng bị thay đổi tại các cột I, M và N
 
Upvote 0
Bạn satoshi viết ra được Bitcoin mà lại bí món này à. Tớ tưởng trước khi viết Bitcoin phải dùng excel để thống kê các kiểu mã hoá chứ nhẩy?

Nếu là tớ sẽ viết sub cho range === hàm bebo.
Rồi sự kiện call sub đấy.
:wallbash: :wallbash: :wallbash:
 
Upvote 0
Nếu muốn học sự kiện thì tôi chỉ cho bạn cách đặt điều kiện cho sự kiện Worksheet_Change trong trường hợp của bạn:
Rich (BB code):
    If (Target.Column = 9 Or Target.Column = 13) And Target.Row > 4 And Target.Count = 1 Then
        If Cells(Target.Row, 1) = "" Then   'Nếu là dòng chi tiết thì mới thi hành
            'Code của bạn
        End If
    End If

Ngoài ra, bạn phải dùng sự kiện Worksheet_SelectionChange để lấy được 3 giá trị của dòng chứa Target trước khi chúng bị thay đổi tại các cột I, M và N

Em cảm ơn anh đã hỗ trợ nhiệt tình cho em!

Sáng nay em cũng sửa code như sau và em cũng thấy ổn anh à, mặc dù em có tắt sự kiện kích đúp chuột nhưng
khi em kích vào các ô thuộc dòng màu xanh đại diện cho cấp 2 (ví dụ I4 và M4) cần tính tổng thì vẫn bị xảy ra lỗi. Em sử dụng bẫy lỗi
ở các vị trí này thì không bị nữa anh ạ. Cũng là lần đầu tập viết sự kiện em nghĩ chắc cũng chưa đúng lắm hoặc còn rườm rà, mong các

anh xem qua, góp ý và sửa giúp em cho code tốt hơn ạ!

1692850130423.png

Với Thisworkbook

Option Explicit

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)

Dim rngI As Range, rngM As Range
Dim lr_b1 As Long
Dim i As Integer, a As Integer, b As Integer, d As Integer, x As Integer
Dim c As Range, j As Integer, y As Integer, w As Long, z As Long

lr_b1 = Me.Sheets("B1").Range("F" & Rows.Count).End(xlUp).Row

Set rngI = Me.Sheets("B1").Range("I3:I" & lr_b1)
Set rngM = Me.Sheets("B1").Range("M3:M" & lr_b1)

If Target.CountLarge > 1 Then Exit Sub
If Target.CountLarge < 1 Then Exit Sub

'ElseIf Target.Column <> 9 And Target.Column <> 13 Then Exit Sub
If Not Intersect(Target, Union(rngI, rngM)) Is Nothing Then

Application.EnableEvents = False

If Not Intersect(Target, rngI) Is Nothing Then

If Target.Offset(0, -2) = "" And Target.Offset(0, -8) = "" Then

'----------xac dinh vi tri cap2 can tinh tong--------------

x = Target.Row

End If

End If

If Not Intersect(Target, rngM) Is Nothing Then

If Target.Offset(0, -12) = "" And Target.Offset(0, -7) = "" Then

x = Target.Row

End If

End If

With Sheets("B1")

a = x

Do Until a < x

For i = a To 3 Step -1

On Error Resume Next

If Range("A" & i).Value <> "" And Range("F" & i).Value <> "" Then

On Error GoTo 0
b = i

Exit Do

End If

Next

a = a - 1

Loop

a = x
Do Until a >= lr_b1

For i = a To lr_b1

On Error Resume Next

If Range("A" & i).Value <> "" And Range("F" & i).Value <> "" Then

On Error GoTo 0

d = i

Exit Do

End If

Next

a = a + 1

Loop

'Stop
'------------------xac dinh vi tri cap1 can tinh tong-------------------
a = x

Do Until a < x

For i = a To 3 Step -1

On Error Resume Next

If Left(Range("F" & i).Value, 4) Like "*-*" Or i = lr_b1 Then

On Error GoTo 0
j = i

Exit Do

End If

Next

a = a - 1
Loop

'Stop
a = x
Do Until a >= lr_b1

For i = a To lr_b1

On Error Resume Next

If Left(Range("F" & i).Value, 4) Like "*-*" Or i = lr_b1 Then

On Error GoTo 0

y = i

Exit Do

End If

Next

a = a + 1

Loop

On Error Resume Next

Cells(x, 14) = Cells(x, 9) - Cells(x, 13) 'cot N = Cot I - cot M
Cells(b, 9) = Application.WorksheetFunction.Sum(Range(Cells(b + 1, 9), Cells(d - 1, 9))) 'Tinh tong cho tieu chi cap2 cot I
Cells(b, 10) = Cells(b, 7) - Cells(b, 9) 'tieu chi cap2 cot J = cot G - cot I

Cells(b, 13) = Application.WorksheetFunction.Sum(Range(Cells(b + 1, 13), Cells(d - 1, 13))) 'Tinh tong cho tieu chi cap2 cot N
Cells(b, 14) = Cells(b, 9) - Cells(b, 13) 'tieu chi cap2 cot N = cot I - cot M

z = 0
w = 0
For i = j + 1 To y - 1 'dong vong lap de tim vung tinh tong cho c1

If Cells(i, 1) <> "" And Cells(i, 6) <> "" Then
'Stop
w = w + Cells(i, 9).Value
z = z + Cells(i, 13).Value
End If
Next i
'Stop
Cells(j, 9) = w 'tong cho C1 cot I
Cells(j, 10) = Cells(j, 7) - Cells(j, 9) 'tong cho C1 cot J = Cot G - COT N

Cells(j, 13) = z 'tong cho C1 cot M
Cells(j, 14) = Cells(j, 9) - Cells(j, 13) 'tong cho C1 cot N

On Error GoTo 0

End With

'End If

'End If

Application.EnableEvents = True

End If

End Sub

Với Worksheet

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

If Not Intersect(Target, Me.Range("I10,N57")) Is Nothing Then
Cancel = True 'huy bo su kien kich dup chuot
End If

End Sub
Bài đã được tự động gộp:

Em cảm ơn anh đã hỗ trợ nhiệt tình cho em!

Sáng nay em cũng sửa code như sau và em cũng thấy ổn anh à, mặc dù em có tắt sự kiện kích đúp chuột nhưng
khi em kích vào các ô thuộc dòng màu xanh đại diện cho cấp 2 (ví dụ I4 và M4) cần tính tổng thì vẫn bị xảy ra lỗi. Em sử dụng bẫy lỗi
ở các vị trí này thì không bị nữa anh ạ. Cũng là lần đầu tập viết sự kiện em nghĩ chắc cũng chưa đúng lắm hoặc còn rườm rà, mong các

anh xem qua, góp ý và sửa giúp em cho code tốt hơn ạ!

1692850130423.png

Với Thisworkbook

Option Explicit

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)

Dim rngI As Range, rngM As Range
Dim lr_b1 As Long
Dim i As Integer, a As Integer, b As Integer, d As Integer, x As Integer
Dim c As Range, j As Integer, y As Integer, w As Long, z As Long

lr_b1 = Me.Sheets("B1").Range("F" & Rows.Count).End(xlUp).Row

Set rngI = Me.Sheets("B1").Range("I3:I" & lr_b1)
Set rngM = Me.Sheets("B1").Range("M3:M" & lr_b1)

If Target.CountLarge > 1 Then Exit Sub
If Target.CountLarge < 1 Then Exit Sub

'ElseIf Target.Column <> 9 And Target.Column <> 13 Then Exit Sub
If Not Intersect(Target, Union(rngI, rngM)) Is Nothing Then

Application.EnableEvents = False

If Not Intersect(Target, rngI) Is Nothing Then

If Target.Offset(0, -2) = "" And Target.Offset(0, -8) = "" Then

'----------xac dinh vi tri cap2 can tinh tong--------------

x = Target.Row

End If

End If

If Not Intersect(Target, rngM) Is Nothing Then

If Target.Offset(0, -12) = "" And Target.Offset(0, -7) = "" Then

x = Target.Row

End If

End If

With Sheets("B1")

a = x

Do Until a < x

For i = a To 3 Step -1

On Error Resume Next

If Range("A" & i).Value <> "" And Range("F" & i).Value <> "" Then

On Error GoTo 0
b = i

Exit Do

End If

Next

a = a - 1

Loop

a = x
Do Until a >= lr_b1

For i = a To lr_b1

On Error Resume Next

If Range("A" & i).Value <> "" And Range("F" & i).Value <> "" Then

On Error GoTo 0

d = i

Exit Do

End If

Next

a = a + 1

Loop

'Stop
'------------------xac dinh vi tri cap1 can tinh tong-------------------
a = x

Do Until a < x

For i = a To 3 Step -1

On Error Resume Next

If Left(Range("F" & i).Value, 4) Like "*-*" Or i = lr_b1 Then

On Error GoTo 0
j = i

Exit Do

End If

Next

a = a - 1
Loop

'Stop
a = x
Do Until a >= lr_b1

For i = a To lr_b1

On Error Resume Next

If Left(Range("F" & i).Value, 4) Like "*-*" Or i = lr_b1 Then

On Error GoTo 0

y = i

Exit Do

End If

Next

a = a + 1

Loop

On Error Resume Next

Cells(x, 14) = Cells(x, 9) - Cells(x, 13) 'cot N = Cot I - cot M
Cells(b, 9) = Application.WorksheetFunction.Sum(Range(Cells(b + 1, 9), Cells(d - 1, 9))) 'Tinh tong cho tieu chi cap2 cot I
Cells(b, 10) = Cells(b, 7) - Cells(b, 9) 'tieu chi cap2 cot J = cot G - cot I

Cells(b, 13) = Application.WorksheetFunction.Sum(Range(Cells(b + 1, 13), Cells(d - 1, 13))) 'Tinh tong cho tieu chi cap2 cot N
Cells(b, 14) = Cells(b, 9) - Cells(b, 13) 'tieu chi cap2 cot N = cot I - cot M

z = 0
w = 0
For i = j + 1 To y - 1 'dong vong lap de tim vung tinh tong cho c1

If Cells(i, 1) <> "" And Cells(i, 6) <> "" Then
'Stop
w = w + Cells(i, 9).Value
z = z + Cells(i, 13).Value
End If
Next i
'Stop
Cells(j, 9) = w 'tong cho C1 cot I
Cells(j, 10) = Cells(j, 7) - Cells(j, 9) 'tong cho C1 cot J = Cot G - COT N

Cells(j, 13) = z 'tong cho C1 cot M
Cells(j, 14) = Cells(j, 9) - Cells(j, 13) 'tong cho C1 cot N

On Error GoTo 0

End With

'End If

'End If

Application.EnableEvents = True

End If

End Sub

Với Worksheet

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

If Not Intersect(Target, Me.Range("I10,N57")) Is Nothing Then
Cancel = True 'huy bo su kien kich dup chuot
End If

End Sub

Em chưa biết cách chỉnh code trên bài đăng cho dễ nhìn mong các anh thông cảm ạ!
 

File đính kèm

  • 1692849980017.png
    1692849980017.png
    6.8 KB · Đọc: 2
Upvote 0
No no no no, với code này thì NO.
Mình sẽ chỉ cách viết cho bạn, với điều kiện bạn đưa thêm dòng vào sao cho Cấp 1 từ 2 dòng trở lên (dòng vàng) thì code mới bao quát hết được.
 
Upvote 0
No no no no, với code này thì NO.
Mình sẽ chỉ cách viết cho bạn, với điều kiện bạn đưa thêm dòng vào sao cho Cấp 1 từ 2 dòng trở lên (dòng vàng) thì code mới bao quát hết được.

Cảm ơn anh. Anh có cách nào tổng quát thì chỉ dạy cho em với ạ!
 
Upvote 0
kích vào các ô thuộc dòng màu xanh đại diện cho cấp 2 (ví dụ I4 và M4) cần tính tổng thì vẫn bị xảy ra lỗi
Bạn phải đặt điều kiện ngay từ đầu như dòng thứ hai tôi đã chỉ ở bài #8 để code không tác động đến các dòng màu xanh
 
Upvote 0
Lạ nhỉ.
Công thức chả mấy phức tạp (theo bài #2), đem thay bằng code bẫy sự kiện là một chuyện vừa lằng nhằng vừa mất hiệu quả. Lại còn đòi "tối ưu".

Muốn học code sự kiện thì đầu tiên phải học cách dùng chúng, những hợp nào cần dùng chúng, những phản ứng phụ,...
Chứ code thì giản dị chỉ là dịch từ lô gic giải thuật ra thành ngữ pháp VBA, đâu cần phải học nhiều.
 
Upvote 0
Web KT

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

Back
Top Bottom