Xin code thay thế công thức IF (1 người xem)

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

pinklove

Thành viên thường trực
Tham gia
21/1/08
Bài viết
336
Được thích
42
Em có file như file đính kèm theo.
Ở cột B em có dùng công thức IF. Nhưng nếu như ở cột C và D em delete và đánh số mới thì giá trị cột B mới thay đổi đúng theo công thức, còn nếu em Cut và Paste thì giá trị nó không thay đổi. Nhờ các bác sửa lỗi này giúp em.
Ngoài ra, File của em có gần 50 sheet như thế này nên em muốn nhờ các bác viết cho em cái code thay thế để nó xử lý file được nhanh hơn có được không ạ.
 
Tại C191 và D191, số liệu như bên dưới thì kết quả tại cột trạng thái là thế nào?
c1616367 1795173
---
Chớ quá lâu, viết đại đoạn code
Mã:
Public Sub Thay_The()
Dim DL, kq(), r As Long
DL = Sheet1.Range("A9", "D" & Sheet1.Range("A1000000").End(xlUp).Row)
ReDim kq(1 To UBound(DL), 1 To 1)

With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "[a-z]+"
For r = 1 To UBound(DL)

If DL(r, 3) <> "" Then
If .test(DL(r, 3)) Then
kq(r, 1) = UCase(.Execute(DL(r, 3))(0))
Else
DL(r, 3) = 1
End If
End If

If DL(r, 4) <> "" Then
If .test(DL(r, 4)) Then
kq(r, 1) = UCase(.Execute(DL(r, 4))(0))
Else
DL(r, 4) = 2
End If
End If

If .test(DL(r, 3)) = 0 And .test(DL(r, 4)) = 0 Then
kq(r, 1) = DL(r, 3) + DL(r, 4)

Select Case kq(r, 1)
Case Is = 1
kq(r, 1) = "A"
Case Is = 2
kq(r, 1) = "M"
Case Is = 3
kq(r, 1) = "A" & "+" & "M"
Case Is = 0
kq(r, 1) = "T"
End Select

End If
Next r
End With

Sheet1.Range("B9").Resize(UBound(kq), 1).ClearContents
Sheet1.Range("B9").Resize(UBound(kq), 1).Value = kq
End Sub
---
Chúc may mắn!
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn bạn. Tại C191 và D191 như thế thì kết quả cột trạng thái là M. Còn nếu như là
1616367 c1795173 thì kết quả là A.
Còn nếu
c1616367 c1795173 thì mới ra kết quả là C.
Nhờ bạn xem lại cái đó.

Còn 1 vấn đề nữa:
Khi mình paste code này vào modun thì nó không tự chạy để thay đổi kq cột trạng thái mà mỗi lần thay đổi số liệu mình lại phải chọn Run Macros nó mới thay đổi. Bạn chỉ giúp mình cách khắc phục với.
 
Upvote 0
Cảm ơn bạn. Tại C191 và D191 như thế thì kết quả cột trạng thái là M. Còn nếu như là
1616367 c1795173 thì kết quả là A.
Còn nếu
c1616367 c1795173 thì mới ra kết quả là C.
Nhờ bạn xem lại cái đó.

Còn 1 vấn đề nữa:
Khi mình paste code này vào modun thì nó không tự chạy để thay đổi kq cột trạng thái mà mỗi lần thay đổi số liệu mình lại phải chọn Run Macros nó mới thay đổi. Bạn chỉ giúp mình cách khắc phục với.
1. Thêm một vòng lặp xóa các ô có chứa chữ "C" sẽ đạt yêu cầu của bạn.
( code hơi dài nhưng chưa nghĩ được cách tuốt lại )
Mã:
Public Sub Thay_The()
Dim DL, kq(), r As Long
DL = Sheet1.Range("A9", "D" & Sheet1.Range("A1000000").End(xlUp).Row)
ReDim kq(1 To UBound(DL), 1 To 1)

With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "[a-z]+"

For r = 1 To UBound(DL) 'Thêm để xóa ô có chứa chữ "C"
If .test(DL(r, 3)) Then
If .Execute(DL(r, 3))(0) = "c" Then
DL(r, 3) = "c"
End If
End If

If .test(DL(r, 4)) Then
If .Execute(DL(r, 4))(0) = "c" Then
DL(r, 4) = "c"
End If
End If
Next r

For r = 1 To UBound(DL)
If DL(r, 3) <> "" Then
If .test(DL(r, 3)) Then
kq(r, 1) = UCase(.Execute(DL(r, 3))(0))
Else
DL(r, 3) = 1
End If
End If

If DL(r, 4) <> "" Then
If .test(DL(r, 4)) Then
kq(r, 1) = UCase(.Execute(DL(r, 4))(0))
Else
DL(r, 4) = 2
End If
End If

If .test(DL(r, 3)) = 0 And .test(DL(r, 4)) = 0 Then
kq(r, 1) = DL(r, 3) + DL(r, 4)

Select Case kq(r, 1)
Case Is = 1
kq(r, 1) = "A"
Case Is = 2
kq(r, 1) = "M"
Case Is = 3
kq(r, 1) = "A" & "+" & "M"
Case Is = 0
kq(r, 1) = "T"
End Select

End If
Next r
End With

Sheet1.Range("B9").Resize(UBound(kq), 1).ClearContents
Sheet1.Range("B9").Resize(UBound(kq), 1).Value = kq
End Sub

2.Bạn thông báo xem dữ liệu nhập tay vào vùng nào mới tính được
 
Lần chỉnh sửa cuối:
Upvote 0
Vẫn chưa được bạn ạ. Ví dụ ở C26 và D26 nhập vào c1616281 và 1795051 nhưng trạng thái vẫn là C trong khi đúng phải là M.
Dữ liệu nhập tay của mình là vào các cột A,C,D từ dòng 9 đến dòng 840.
 
Lần chỉnh sửa cuối:
Upvote 0
Vẫn chưa được bạn ạ. Ví dụ ở C26 và D26 nhập vào c1616281 và 1795051 nhưng trạng thái vẫn là C trong khi đúng phải là M.
Dữ liệu nhập tay của mình là vào các cột A,C,D từ dòng 9 đến dòng 840.

Bạn dán lại code của bài 4 rồi kiểm tra lại kết quả xem sao ( Đã sửa lại: Đổi Empty---> "c". )
Có lẽ là bạn đính kèm file giả định gần như thật để tính một thể
---
Cũng cần làm cụ thể các trường hợp tính toán vì như trường hợp "- Thuê bao bị cắt thì ghi "C" phía trước số thuê bao, đóng lại thì xóa" ghi trong file đính kèm không nói rõ là cắt cả 2 thuê bao hay còn giữ lại một phần
 
Lần chỉnh sửa cuối:
Upvote 0
Mình thử lại rồi vẫn ko được bạn à. File mình đính kèm ở bài 1 là file thật đó. Mình copy nguyên một sheet trong file của mình đó. Tất cả các sheet giống nhau mà. Chỉ có số liệu mỗi trạm khác nhau thôi. Nếu có thể bạn nt vào số điện thoại mình gửi cho bạn trong tin nhắn. Mình sẽ gọi lại nói rõ hơn ý của mình cho bạn. Thanks bạn nhiều.
 
Upvote 0
Cũng cần làm cụ thể các trường hợp tính toán vì như trường hợp "- Thuê bao bị cắt thì ghi "C" phía trước số thuê bao, đóng lại thì xóa" ghi trong file đính kèm không nói rõ là cắt cả 2 thuê bao hay còn giữ lại một phần
Ý mình là nếu thuê bao bị cắt thì ghi C trước số, đóng lại thì xóa chữ C đi, nên nếu như cổng đang sử dụng 2 dịch vụ là A+M mà A bị cắt thì còn lại M và ngược lại chứ không phải cổng cắt "C". Khi cắt cả 2 dịch vụ, tức là có C trước cả 2 số của A và M thì khi đó nó mới là "C"
 
Upvote 0
Thêm một vấn đề nữa là nó code vẫn chưa tự chạy được mà sau mỗi lần mình thay đổi số liệu thì phải chọn Run Macros bạn ạ.

Nếu không sử dụng VBA mà để nguyên công thức, khi mình xóa dữ liệu ở cột C và D rồi nhập lại thủ công thì trạng thái chuyển đúng, nhưng khi mình CUT và PASTE, ví dụ cổng 1 hỏng nên chuyển sang cổng 2, CUT số PASTE sang thì trạng thái nó không đổi được, nhờ bạn chỉ giúp cách sửa luôn.
 
Lần chỉnh sửa cuối:
Upvote 0
Thêm một vấn đề nữa là nó code vẫn chưa tự chạy được mà sau mỗi lần mình thay đổi số liệu thì phải chọn Run Macros bạn ạ.

Nếu không sử dụng VBA mà để nguyên công thức, khi mình xóa dữ liệu ở cột C và D rồi nhập lại thủ công thì trạng thái chuyển đúng, nhưng khi mình CUT và PASTE, ví dụ cổng 1 hỏng nên chuyển sang cổng 2, CUT số PASTE sang thì trạng thái nó không đổi được, nhờ bạn chỉ giúp cách sửa luôn.
Việc sử dụng công thức với nhiều điều kiện như của bạn có lẽ là chờ cao thủ trên diễn đàn giúp đỡ vậy.
Gửi bạn file đính kèm dùng vba, bạn kiểm tra các yêu cầu xem sao.
 

File đính kèm

Upvote 0
Thêm một vấn đề nữa là nó code vẫn chưa tự chạy được mà sau mỗi lần mình thay đổi số liệu thì phải chọn Run Macros bạn ạ.

Nếu không sử dụng VBA mà để nguyên công thức, khi mình xóa dữ liệu ở cột C và D rồi nhập lại thủ công thì trạng thái chuyển đúng, nhưng khi mình CUT và PASTE, ví dụ cổng 1 hỏng nên chuyển sang cổng 2, CUT số PASTE sang thì trạng thái nó không đổi được, nhờ bạn chỉ giúp cách sửa luôn.
Nút bấm không đk à bác.
 
Upvote 0
Vấn đề của bạn nằm ở chỗ có một số hàm bị mất điểm mốc khi dùng cut/paste - Excel đếm cells theo điểm mốc.

Để giải quyết, ở các nơi COUNT, COUNTIF, nếu ô tham chiếu có khả năng bị cut (tức là các cột C, D), bạn dùng hàm Offset để tham chiếu.
Muốn tham chiếu C9 thì dùng OFFSET(A9,,2).Muốn tham chiếu D9 thì dùng OFFSET(A9,,3).Muốn tham chiếu C9:D9 thì dùng OFFSET(A9,,2,,2)

Tính tôi chỉ đưa ra giải pháp thôi chứ rất lười làm A đến Z. Bạn chịu khó tự sửa công thức của mình.
 
Upvote 0
Bổ xung:
Mình cứ tưởng là chủ thớt tự làm công thức mà bị kẹt. Xem kỹ lại thì bài này chủ thớt đã hỏi ở thớt khác. Bây giờ lại mở thêm thớt này để hỏi.
Kiểu này thì để cho tác giả công thức giải quyết. Tôi không xía vào nữa.
 
Upvote 0
Ý mình là nếu thuê bao bị cắt thì ghi C trước số, đóng lại thì xóa chữ C đi, nên nếu như cổng đang sử dụng 2 dịch vụ là A+M mà A bị cắt thì còn lại M và ngược lại chứ không phải cổng cắt "C". Khi cắt cả 2 dịch vụ, tức là có C trước cả 2 số của A và M thì khi đó nó mới là "C"
Bạn dùng thử cách này xem sao.
 

File đính kèm

Upvote 0
Mình đã áp dụng tốt code của bạn. Bạn có thể cho mình hỏi thêm nếu mình muốn áp dụng code này cho riêng từng sheet trong file chứ không phải với tất cả các sheets thì mình phải làm thế nào không????
 
Upvote 0
Mình đã áp dụng tốt code của bạn. Bạn có thể cho mình hỏi thêm nếu mình muốn áp dụng code này cho riêng từng sheet trong file chứ không phải với tất cả các sheets thì mình phải làm thế nào không????
PHP:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Long, Cll As Range, j As Long
If Not Intersect(Target, [A9:A65000,C9:D65000]) Is Nothing Then
For Each Cll In Intersect(Target, [A9:A65000,C9:D65000])
i = Cll.Row
    If Cells(i, 1) = Empty Then
        Cells(i, 2) = Empty
    ElseIf IsNumeric(Cells(i, 3)) And IsNumeric(Cells(i, 4)) And Cells(i, 3) > 0 And Cells(i, 4) > 0 Then
       Cells(i, 2) = "A+M"
    ElseIf IsNumeric(Cells(i, 3)) And Cells(i, 3) > 0 Then
       Cells(i, 2) = "A"
    ElseIf IsNumeric(Cells(i, 4)) And Cells(i, 4) > 0 Then
       Cells(i, 2) = "M"
    ElseIf UCase(Cells(i, 3)) Like "*MW*" Or UCase(Cells(i, 4)) Like "*MW*" Then
       Cells(i, 2) = "MW"
    ElseIf UCase(Cells(i, 3)) Like "*H*" Or UCase(Cells(i, 4)) Like "*H*" Then
       Cells(i, 2) = "H"
    ElseIf UCase(Cells(i, 3)) Like "*C*" Or UCase(Cells(i, 4)) Like "*C*" Then
       Cells(i, 2) = "C"
    Else
       Cells(i, 2) = "T"
    End If
Next Cll
End If
End Sub
Bạn chếp đoạn này vào thẳng sheet nhé, vẫn code của bác Phuocam
 
Upvote 0
PHP:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Long, Cll As Range, j As Long
If Not Intersect(Target, [A9:A65000,C9:D65000]) Is Nothing Then
For Each Cll In Intersect(Target, [A9:A65000,C9:D65000])
i = Cll.Row
    If Cells(i, 1) = Empty Then
        Cells(i, 2) = Empty
    ElseIf IsNumeric(Cells(i, 3)) And IsNumeric(Cells(i, 4)) And Cells(i, 3) > 0 And Cells(i, 4) > 0 Then
       Cells(i, 2) = "A+M"
    ElseIf IsNumeric(Cells(i, 3)) And Cells(i, 3) > 0 Then
       Cells(i, 2) = "A"
    ElseIf IsNumeric(Cells(i, 4)) And Cells(i, 4) > 0 Then
       Cells(i, 2) = "M"
    ElseIf UCase(Cells(i, 3)) Like "*MW*" Or UCase(Cells(i, 4)) Like "*MW*" Then
       Cells(i, 2) = "MW"
    ElseIf UCase(Cells(i, 3)) Like "*H*" Or UCase(Cells(i, 4)) Like "*H*" Then
       Cells(i, 2) = "H"
    ElseIf UCase(Cells(i, 3)) Like "*C*" Or UCase(Cells(i, 4)) Like "*C*" Then
       Cells(i, 2) = "C"
    Else
       Cells(i, 2) = "T"
    End If
Next Cll
End If
End Sub
Bạn chếp đoạn này vào thẳng sheet nhé, vẫn code của bác Phuocam

Cảm ơn bạn. Mình đã thử nhưng khi thay đổi các giá trị cột C và D thì cột B ko tự động nhảy như khi làm với cả file mà phải click chuột vào ô mới thay đổi giá trị một lần nữa thì cột B mới thay đổi. Xem lại hộ mình được không ạ
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn bạn. Mình đã thử nhưng khi thay đổi các giá trị cột C và D thì cột B ko tự động nhảy như khi làm với cả file mà phải click chuột vào ô mới thay đổi giá trị một lần nữa thì cột B mới thay đổi. Xem lại hộ mình được không ạ
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long, Cll As Range, j As Long
If Not Intersect(Target, [A9:A65000,C9:D65000]) Is Nothing Then
For Each Cll In Intersect(Target, [A9:A65000,C9:D65000])
i = Cll.Row
    If Cells(i, 1) = Empty Then
        Cells(i, 2) = Empty
    ElseIf IsNumeric(Cells(i, 3)) And IsNumeric(Cells(i, 4)) And Cells(i, 3) > 0 And Cells(i, 4) > 0 Then
       Cells(i, 2) = "A+M"
    ElseIf IsNumeric(Cells(i, 3)) And Cells(i, 3) > 0 Then
       Cells(i, 2) = "A"
    ElseIf IsNumeric(Cells(i, 4)) And Cells(i, 4) > 0 Then
       Cells(i, 2) = "M"
    ElseIf UCase(Cells(i, 3)) Like "*MW*" Or UCase(Cells(i, 4)) Like "*MW*" Then
       Cells(i, 2) = "MW"
    ElseIf UCase(Cells(i, 3)) Like "*H*" Or UCase(Cells(i, 4)) Like "*H*" Then
       Cells(i, 2) = "H"
    ElseIf UCase(Cells(i, 3)) Like "*C*" Or UCase(Cells(i, 4)) Like "*C*" Then
       Cells(i, 2) = "C"
    Else
       Cells(i, 2) = "T"
    End If
Next Cll
End If
End Sub
Bạn thử lại xem
 
Upvote 0
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long, Cll As Range, j As Long
If Not Intersect(Target, [A9:A65000,C9:D65000]) Is Nothing Then
For Each Cll In Intersect(Target, [A9:A65000,C9:D65000])
i = Cll.Row
    If Cells(i, 1) = Empty Then
        Cells(i, 2) = Empty
    ElseIf IsNumeric(Cells(i, 3)) And IsNumeric(Cells(i, 4)) And Cells(i, 3) > 0 And Cells(i, 4) > 0 Then
       Cells(i, 2) = "A+M"
    ElseIf IsNumeric(Cells(i, 3)) And Cells(i, 3) > 0 Then
       Cells(i, 2) = "A"
    ElseIf IsNumeric(Cells(i, 4)) And Cells(i, 4) > 0 Then
       Cells(i, 2) = "M"
    ElseIf UCase(Cells(i, 3)) Like "*MW*" Or UCase(Cells(i, 4)) Like "*MW*" Then
       Cells(i, 2) = "MW"
    ElseIf UCase(Cells(i, 3)) Like "*H*" Or UCase(Cells(i, 4)) Like "*H*" Then
       Cells(i, 2) = "H"
    ElseIf UCase(Cells(i, 3)) Like "*C*" Or UCase(Cells(i, 4)) Like "*C*" Then
       Cells(i, 2) = "C"
    Else
       Cells(i, 2) = "T"
    End If
Next Cll
End If
End Sub
Bạn thử lại xem

Cảm ơn bạn, đã ngon lành rồi. Bây giờ vẫn code đó nhưng mình muốn đổi sang vùng làm việc khác như trong file kèm theo. Mình đã thử đổi range nhưng không được. Bạn xem hộ mình với.
 
Upvote 0
Cảm ơn bạn, đã ngon lành rồi. Bây giờ vẫn code đó nhưng mình muốn đổi sang vùng làm việc khác như trong file kèm theo. Mình đã thử đổi range nhưng không được. Bạn xem hộ mình với.
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long, Cll As Range, j As Long
If Not Intersect(Target, [C10:C65000,E10:F65000]) Is Nothing Then
For Each Cll In Intersect(Target, [C10:C65000,E10:F65000])
i = Cll.Row
    If Cells(i, 3) = Empty Then
        Cells(i, 4) = Empty
    ElseIf IsNumeric(Cells(i, 4)) And IsNumeric(Cells(i, 5)) And Cells(i, 4) > 0 And Cells(i, 5) > 0 Then
       Cells(i, 3) = "A+M"
    ElseIf IsNumeric(Cells(i, 4)) And Cells(i, 4) > 0 Then
       Cells(i, 3) = "A"
    ElseIf IsNumeric(Cells(i, 5)) And Cells(i, 5) > 0 Then
       Cells(i, 3) = "M"
    ElseIf UCase(Cells(i, 4)) Like "*MW*" Or UCase(Cells(i, 5)) Like "*MW*" Then
       Cells(i, 3) = "MW"
    ElseIf UCase(Cells(i, 4)) Like "*TB*" Or UCase(Cells(i, 5)) Like "*TB*" Then
       Cells(i, 3) = "TB"
    ElseIf UCase(Cells(i, 4)) Like "*H*" Or UCase(Cells(i, 5)) Like "*H*" Then
       Cells(i, 3) = "H"
    ElseIf UCase(Cells(i, 4)) Like "*C*" Or UCase(Cells(i, 5)) Like "*C*" Then
       Cells(i, 3) = "C"
    Else
       Cells(i, 3) = "T"
    End If
Next Cll
End If
End Sub
Bạn thay số cột cells(i, số cột phù hợp là được thôi) . Ko biết mình đã thay hết chưa,c ó gì bạn check lại nhé
 
Lần chỉnh sửa cuối:
Upvote 0
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long, Cll As Range, j As Long
If Not Intersect(Target, [C10:C65000,E10:F65000]) Is Nothing Then
For Each Cll In Intersect(Target, [C10:C65000,E10:F65000])
i = Cll.Row
    If Cells(i, 3) = Empty Then
        Cells(i, 4) = Empty
    ElseIf IsNumeric(Cells(i, 4)) And IsNumeric(Cells(i, 5)) And Cells(i, 4) > 0 And Cells(i, 5) > 0 Then
       Cells(i, 3) = "A+M"
    ElseIf IsNumeric(Cells(i, 4)) And Cells(i, 4) > 0 Then
       Cells(i, 3) = "A"
    ElseIf IsNumeric(Cells(i, 5)) And Cells(i, 5) > 0 Then
       Cells(i, 3) = "M"
    ElseIf UCase(Cells(i, 4)) Like "*MW*" Or UCase(Cells(i, 5)) Like "*MW*" Then
       Cells(i, 3) = "MW"
    ElseIf UCase(Cells(i, 4)) Like "*TB*" Or UCase(Cells(i, 5)) Like "*TB*" Then
       Cells(i, 3) = "TB"
    ElseIf UCase(Cells(i, 4)) Like "*H*" Or UCase(Cells(i, 5)) Like "*H*" Then
       Cells(i, 3) = "H"
    ElseIf UCase(Cells(i, 4)) Like "*C*" Or UCase(Cells(i, 5)) Like "*C*" Then
       Cells(i, 3) = "C"
    Else
       Cells(i, 3) = "T"
    End If
Next Cll
End If
End Sub
Bạn thay số cột cells(i, số cột phù hợp là được thôi) . Ko biết mình đã thay hết chưa,c ó gì bạn check lại nhé
Cảm ơn bạn nhé. Bạn đổi có sai về số cột nhưng bạn chỉ như vậy mình đã hiểu và đã sửa lại được rồi.
 
Upvote 0

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

Back
Top Bottom