VBA lồng 2 phương thức Find

Liên hệ QC

chipiu3001

Thành viên hoạt động
Tham gia
22/8/15
Bài viết
105
Được thích
15
Chào anh chị em

Mình có tạo VBA tính toán số điểm cho NCC.
Giao chậm thì bị trừ điểm.

Mình có lồng 2 phương thức Find
- Tìm ngày KH về sau đó tìm ngày giao hàng.
Tuy nhiên bị báo lỗi này
1705283188451.png
Không biết có phải không thể lồng 2 phương thức find vào nhau không. Các bạn xem file đính kèm lý giải giúp mình với nhé.

Mình cảm ơn nhiều
1705283171394.png
 

File đính kèm

  • PHIẾU THEO DÕI ĐƠN HÀNG (2).xlsm
    24 KB · Đọc: 15
Cách trừ điểm của bạn được tính như nào. Mô tả rõ hơn 1 chút được không?
 
Upvote 0
Giải pháp
Cảm ơn bạn. Cái trừ điểm đó là 1 phần tính toán ( Mình nghĩ nó ko ảnh hưởng đến code chạy) . Cho dù mình xóa cái trừ đó đi thì vẫn bị lỗi.
Xóa cái phương thức Find thứ 2 đi thì chạy bình thường ko báo lỗi nữa. Nên mình nghi 2 cái find không lồng vào nhau được

If NgayGH - NgayKH < 1 Then 'giao hang truoc
D = D
ElseIf NgayGH - NgayKH < 3 Then ' Giao hang muon 1~2 ngay
D = D - 2
ElseIf NgayGH - NgayKH < 5 Then ' giao hang muon 3~4 ngay
D = D - 5
Else ' Giao hang muon tren 5 ngay
D = D - 7
End If

X ~ NgayKH: tương ứng ngày KH về
O ~ NgayGH : tương ứng ngày giao hàng

Cách tính thì như trên nhé.

Cảm ơn bạn
 
Upvote 0
Hình như thế gian này không có Loop While, chỉ có Do While ... Loop và vài thứ nữa
 
Upvote 0
Vâng . Xin lỗi anh e không hiểu rõ ý của anh.

Do While .... Loop => Kiểm tra điều khiện ở đầu vòng lặp.
Do ....Loop While => Kiểm tra điều khiện ở cuối vòng lặp.

Anh có thể chỉ lại giúp em được không ạ

Em cảm ơn
 
Upvote 0
Chào anh chị em

Mình có tạo VBA tính toán số điểm cho NCC.
Giao chậm thì bị trừ điểm.

Mình có lồng 2 phương thức Find
- Tìm ngày KH về sau đó tìm ngày giao hàng.
Tuy nhiên bị báo lỗi này
View attachment 298458
Không biết có phải không thể lồng 2 phương thức find vào nhau không. Các bạn xem file đính kèm lý giải giúp mình với nhé.

Mình cảm ơn nhiều

Một kỹ thuật tìm lỗi là bạn rê con chuột vào từng đối tượng ở dòng màu vàng để xem nó có trả giá trị gì về không. Cụ thể ở cái "KH.Address" là không có giá trị gì ==> lỗi chỗ "Set KH..."
 
Upvote 0
Lỗi ở dòng Loop While ở trên là KH lúc đó nó không phải là một Range Object, nên không để truy xuất Address

Bạn cần thêm lệnh bẫy lỗi đầu thủ tục: On Error Resume Next
Kiểm tra:
JavaScript:
    Err.Clear: Set KH = ...
    If Err <> 0 Or KH Is Nothing Then Exit Do
 
Upvote 0
Một kỹ thuật tìm lỗi là bạn rê con chuột vào từng đối tượng ở dòng màu vàng để xem nó có trả giá trị gì về không. Cụ thể ở cái "KH.Address" là không có giá trị gì ==> lỗi chỗ "Set KH..."
Cảm ơn bạn. Mình cũng đã biết việc này nhưng không hiểu tại sao lại lỗi.
Nếu xóa đoạn giữa này đi ( Xóa 1 phương thức Find) thì code chạy ko lỗi. Thêm Msgbox (KH.address) => chạy sẽ tìm ra được nhiều địa chỉ có chưa X.
Cảm ơn bạn

1705294175720.png
Bài đã được tự động gộp:

Lỗi ở dòng Loop While ở trên là KH lúc đó nó không phải là một Range Object, nên không để truy xuất Address

Bạn cần thêm lệnh bẫy lỗi đầu thủ tục: On Error Resume Next
Kiểm tra:
JavaScript:
    Err.Clear: Set KH = ...
    If Err <> 0 Or KH Is Nothing Then Exit Do
Chào bạn. Thêm đoạn bẫy lỗi thì sẽ chỉ tìm được 1 lần Kế hoạch "X" duy nhất thôi, Không tìm được các lần kế hoạch về tiếp theo để so sánh.
Mình chưa hiểu tại sao set KH vậy lại bằng nothing.

Cảm ơn bạn nhiều
Bài đã được tự động gộp:

Lỗi ở dòng Loop While ở trên là KH lúc đó nó không phải là một Range Object, nên không để truy xuất Address

Bạn cần thêm lệnh bẫy lỗi đầu thủ tục: On Error Resume Next
Kiểm tra:
JavaScript:
    Err.Clear: Set KH = ...
    If Err <> 0 Or KH Is Nothing Then Exit Do
Chào bạn. Thêm đoạn bẫy lỗi thì sẽ chỉ tìm được 1 lần Kế hoạch "X" duy nhất thôi, Không tìm được các lần kế hoạch về tiếp theo để so sánh.
Mình chưa hiểu tại sao set KH vậy lại bằng nothing.

Cảm ơn bạn nhiều
 

File đính kèm

  • 1705294156570.png
    1705294156570.png
    134.4 KB · Đọc: 3
Upvote 0
Gán Vùng ô nguồn vào một biến rồi mới dùng Find bạn nhé
JavaScript:
Dim rg, KH
Set rg = Sheet1.Range(Sheet1.Cells(...),Sheet1.Cells(...))
Set KH= rg.Find(...)
Set KH= rg.FindNext(KH)
 
Upvote 0
@Chủ bài đăng: Phương thức FIND() không thể lồng vô nhau được;
& mình cũng chưa rõ khái niệm 'tìm ngày khách hàng (KH) về' là như thế nào?
Thứ nữa: Các ô chứa dữ liệu không nên trộn như bạn; Tuy có đẹp như lắm phiền phức khi xài VBA
 
Upvote 0
Lỗi ở dòng Loop While ở trên là KH lúc đó nó không phải là một Range Object, nên không để truy xuất Address

Bạn cần thêm lệnh bẫy lỗi đầu thủ tục: On Error Resume Next
Kiểm tra:
JavaScript:
    Err.Clear: Set KH = ...
    If Err <> 0 Or KH Is Nothing Then Exit Do
Chào bạn. Thêm đoạn bẫy lỗi thì sẽ chỉ tìm được 1 lần Kế hoạch "X" duy nhất thôi, Không tìm được các lần kế hoạch về tiếp theo để so sánh.
Mình chưa hiểu tại sao set KH vậy lại bằng nothing.

Cảm ơn bạn nhiều
Gán Vùng ô nguồn vào một biến rồi mới dùng Find bạn nhé
JavaScript:
Dim rg, KH
Set rg = Sheet1.Range(Sheet1.Cells(...),Sheet1.Cells(...))
Set KH= rg.Find(...)
Set KH= rg.FindNext(KH)
Cảm ơn bạn.
Gán biến bên trên theo mình thấy chỉ thu gọn code lại thôi. Mình chạy vẫn bị lỗi. Mình gửi file đã sửa. Bạn xem giúp mình nhé.

Cảm ơn bạn.
Bài đã được tự động gộp:

Lỗi ở dòng Loop While ở trên là KH lúc đó nó không phải là một Range Object, nên không để truy xuất Address

Bạn cần thêm lệnh bẫy lỗi đầu thủ tục: On Error Resume Next
Kiểm tra:
JavaScript:
    Err.Clear: Set KH = ...
    If Err <> 0 Or KH Is Nothing Then Exit Do
Chào bạn. Thêm đoạn bẫy lỗi thì sẽ chỉ tìm được 1 lần Kế hoạch "X" duy nhất thôi, Không tìm được các lần kế hoạch về tiếp theo để so sánh.
Mình chưa hiểu tại sao set KH vậy lại bằng nothing.

Cảm ơn bạn nhiều
Gán Vùng ô nguồn vào một biến rồi mới dùng Find bạn nhé
JavaScript:
Dim rg, KH
Set rg = Sheet1.Range(Sheet1.Cells(...),Sheet1.Cells(...))
Set KH= rg.Find(...)
Set KH= rg.FindNext(KH)
Cảm ơn bạn.
Gán biến bên trên theo mình thấy chỉ thu gọn code lại thôi. Mình chạy vẫn bị lỗi. Mình gửi file đã sửa. Bạn xem giúp mình nhé.

Cảm ơn bạn.
Bài đã được tự động gộp:

Lỗi ở dòng Loop While ở trên là KH lúc đó nó không phải là một Range Object, nên không để truy xuất Address

Bạn cần thêm lệnh bẫy lỗi đầu thủ tục: On Error Resume Next
Kiểm tra:
JavaScript:
    Err.Clear: Set KH = ...
    If Err <> 0 Or KH Is Nothing Then Exit Do
Chào bạn. Thêm đoạn bẫy lỗi thì sẽ chỉ tìm được 1 lần Kế hoạch "X" duy nhất thôi, Không tìm được các lần kế hoạch về tiếp theo để so sánh.
Mình chưa hiểu tại sao set KH vậy lại bằng nothing.

Cảm ơn bạn nhiều
Gán Vùng ô nguồn vào một biến rồi mới dùng Find bạn nhé
JavaScript:
Dim rg, KH
Set rg = Sheet1.Range(Sheet1.Cells(...),Sheet1.Cells(...))
Set KH= rg.Find(...)
Set KH= rg.FindNext(KH)
Cảm ơn bạn.
Gán biến bên trên theo mình thấy chỉ thu gọn code lại thôi. Mình chạy vẫn bị lỗi. Mình gửi file đã sửa. Bạn xem giúp mình nhé.

Cảm ơn bạn.
@Chủ bài đăng: Phương thức FIND() không thể lồng vô nhau được;
& mình cũng chưa rõ khái niệm 'tìm ngày khách hàng (KH) về' là như thế nào?
Thứ nữa: Các ô chứa dữ liệu không nên trộn như bạn; Tuy có đẹp như lắm phiền phức khi xài VBA
Chào anh.
Đúng là VBA mà trộn ô thì sau phát triển tiếp rất khó.
File này em chỉ làm code trong phạm vi không trộn ô thôi.
Em giải thích lại .

1 NCC có 2 dòng.
- 1 dòng tương ứng ngày kế hoạch giao : Đánh "X"
- 1 dòng tương ứng ngày giao hàng thực tế : Đánh"O"
- Trong tháng ( file chỉ 1 tháng 1) có nhiều lần KH và GH ("X" và "O)
Code:

+ So sánh ngày kế hoạch và ngày giao hàng.
-Nếu giao trước thì dc 0 điểm ( ko bị trừ)
- Nếu giao muộn 1~2 ngày thì bị trừ 2 điểm
- Nếu giao muộn 3~4 ngày bị trừ 5 điểm
- Nếu giao muộn trên 5 ngày trừ 7 điểm.

Em cảm ơn a
 

File đính kèm

  • PHIẾU THEO DÕI ĐƠN HÀNG (2) Ver 01.xlsm
    24.1 KB · Đọc: 5
Lần chỉnh sửa cuối:
Upvote 0
Tôi chỉ giúp bạn sửa mã, còn bài toán đáng lý ra là phải đăng ngay từ bài viết đầu để nhận trợ giúp về bài toán.

JavaScript:
Sub tinh_toan()

  Dim NgayGH%, NgayKH%, D%, n%, GH_BD%
  Dim cell As Range, rg0 As Range, rg As Range, KH As Range, KHFirstAddress As String
  Dim GH As Range, GHFirstAddress As String
  Const KH_BD = 5 ' cot Ngay KH bat dau
  Const KH_KT = 35 ' cot Ngay KH ket thuc
  Const GH_KT = 35 ' cot Ngay GH ket thuc
  Set cell = [A5]
  For n = 1 To 32 Step 2 ' SL NCC
    D = 0: GH_BD = 5 ' cot Ngay GH bat dau
    Set rg = cell(n, KH_BD).Resize(, 31)
    Set KH = rg.Find("X", After:=rg(1, 31), LookIn:=xlValues, LookAt:=xlWhole)
    If Not KH Is Nothing Then
      KHFirstAddress = KH.Address
      Do
        NgayKH = KH.Column
        Set rg0 = cell(n + 1, GH_BD).Resize(, GH_KT - GH_BD + 1)
        Set GH = rg0.Find("O", After:=rg0(1, rg0.Columns.Count), LookIn:=xlValues, LookAt:=xlWhole)
        If Not GH Is Nothing Then
          GHFirstAddress = GH.Address
          NgayGH = GH.Column
          GH_BD = NgayGH + 1 ' Vùng tim kiem "O" se duoc thu hep lai trong lan Loop tìm "X" tiep theo
        Else
          D = D - 7: Exit Do' Khong co ngay giao hang ( chua giao hang)
        End If
        Select Case NgayGH - NgayKH
        Case Is < 1: D = D     'giao hang truoc
        Case Is < 3: D = D - 2 ' Giao hang muon 1~2 ngay
        Case Is < 5: D = D - 5 ' giao hang muon 3~4 ngay
        Case Else: D = D - 7   ' Giao hang muon tren 5 ngay
        End Select
        Set KH = rg.FindNext(KH)
        If KH Is Nothing Then Exit Do
        If KHFirstAddress = KH.Address Then Exit Do
      Loop
      cell(n, KH_KT + 1).Value = D ' Diem
    Else
    End If
  Next
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Giải bài toán của bạn:

JavaScript:
Sub tinh_toan()
  Dim NgayKH%, D%, n%, i%, cell As Range, rg As Range
  Const KH_BD = 5 ' cot Ngay KH bat dau
  Const KH_KT = 35 ' cot Ngay KH ket thuc
  Set cell = [A5]: n = 1
  While cell(n, 1).Value <> Empty
    D = 0
    Set rg = cell(n, KH_BD).Resize(2, 31)
    For i = 1 To 31
      If CStr(rg(1, i).Value) = "X" Then
        If NgayKH > 0 Then D = D - 7
        NgayKH = i
      End If
      If CStr(rg(2, i).Value) = "O" Then GoSub v: NgayKH = 0
    Next
    rg(1, i).Value = D
    n = n + cell(n, 1).MergeArea.Rows.Count
  Wend
Exit Sub
v:
  Select Case i - NgayKH
  Case Is < 1: D = D     ' giao hang truoc
  Case Is < 3: D = D - 2 ' Giao hang muon 1~2 ngay
  Case Is < 5: D = D - 5 ' giao hang muon 3~4 ngay
  Case Else: D = D - 7   ' Giao hang muon tren 5 ngay
  End Select
Return
End Sub
 
Upvote 0
Chào anh chị em

Mình có tạo VBA tính toán số điểm cho NCC.
Giao chậm thì bị trừ điểm.

Mình có lồng 2 phương thức Find
- Tìm ngày KH về sau đó tìm ngày giao hàng.
Tuy nhiên bị báo lỗi này
View attachment 298458
Không biết có phải không thể lồng 2 phương thức find vào nhau không. Các bạn xem file đính kèm lý giải giúp mình với nhé.

Mình cảm ơn nhiều
View attachment 298457
Dùng mảng và vòng For
Mã:
Sub XYZ()
  Dim arr(), res(), sRow&, sCol&, i&, j&, c&, d&, fC&, cl&
 
  arr = Range("B5", Range("AI" & Range("B1000000").End(xlUp).Row + 1)).Value
  sRow = UBound(arr):             sCol = UBound(arr, 2)
  ReDim res(1 To sRow, 1 To 1)
  For i = 1 To sRow
    If arr(i, 1) <> Empty Then
      d = 0: fC = 4
      For j = 4 To sCol
        If UCase(arr(i, j)) = "X" Then
          For c = fC To sCol
            If UCase(arr(i + 1, c)) = "O" Then
              cl = c - j
              If cl > 4 Then 'Tru 7 diem
                d = d - 7
              ElseIf cl > 2 Then 'Tru 5 diem
                d = d - 5
              ElseIf cl > 0 Then 'Tru 2 diem
                d = d - 2
              End If
              fC = c + 1
              Exit For
            End If
          Next c
          If c = sCol + 1 Then d = d - 7 'Tru 7 diem
        End If
      Next j
      res(i, 1) = d
    End If
  Next i
  Range("AJ5").Resize(sRow) = res
End Sub
 
Upvote 0
Lỗi ở dòng Loop While ở trên là KH lúc đó nó không phải là một Range Object, nên không để truy xuất Address

Bạn cần thêm lệnh bẫy lỗi đầu thủ tục: On Error Resume Next
Kiểm tra:
JavaScript:
    Err.Clear: Set KH = ...
    If Err <> 0 Or KH Is Nothing Then Exit Do
Chào bạn. Thêm đoạn bẫy lỗi thì sẽ chỉ tìm được 1 lần Kế hoạch "X" duy nhất thôi, Không tìm được các lần kế hoạch về tiếp theo để so sánh.
Mình chưa hiểu tại sao set KH vậy lại bằng nothing.

Cảm ơn bạn nhiều
Gán Vùng ô nguồn vào một biến rồi mới dùng Find bạn nhé
JavaScript:
Dim rg, KH
Set rg = Sheet1.Range(Sheet1.Cells(...),Sheet1.Cells(...))
Set KH= rg.Find(...)
Set KH= rg.FindNext(KH)
Cảm ơn bạn.
Gán biến bên trên theo mình thấy chỉ thu gọn code lại thôi. Mình chạy vẫn bị lỗi. Mình gửi file đã sửa. Bạn xem giúp mình nhé.

Cảm ơn bạn.
@Chủ bài đăng: Phương thức FIND() không thể lồng vô nhau được;
& mình cũng chưa rõ khái niệm 'tìm ngày khách hàng (KH) về' là như thế nào?
Thứ nữa: Các ô chứa dữ liệu không nên trộn như bạn; Tuy có đẹp như lắm phiền phức khi xài VBA
Chào anh.
Đúng là VBA mà trộn ô thì sau phát triển tiếp rất khó.
File này em chỉ làm code trong phạm vi không trộn ô thôi.
Em giải thích lại .

1 NCC có 2 dòng.
- 1 dòng tương ứng ngày kế hoạch giao : Đánh "X"
- 1 dòng tương ứng ngày giao hàng thực tế : Đánh"O"
- Trong tháng ( file chỉ 1 tháng 1) có nhiều lần KH và GH ("X" và "O)
Code:

+ So sánh ngày kế hoạch và ngày giao hàng.
-Nếu giao trước thì dc 0 điểm ( ko bị trừ)
- Nếu giao muộn 1~2 ngày thì bị trừ 2 điểm
- Nếu giao muộn 3~4 ngày bị trừ 5 điểm
- Nếu giao muộn trên 5 ngày trừ 7 điểm.

Em cảm ơn a
Tôi chỉ giúp bạn sửa mã, còn bài toán đáng lý ra là phải đăng ngay từ bài viết đầu để nhận trợ giúp về bài toán.

JavaScript:
Sub tinh_toan()

  Dim NgayGH%, NgayKH%, D%, n%, GH_BD%
  Dim cell As Range, rg0 As Range, rg As Range, KH As Range, KHFirstAddress As String
  Dim GH As Range, GHFirstAddress As String
  Const KH_BD = 5 ' cot Ngay KH bat dau
  Const KH_KT = 35 ' cot Ngay KH ket thuc
  Const GH_KT = 35 ' cot Ngay GH ket thuc
  Set cell = [A5]
  For n = 1 To 32 Step 2 ' SL NCC
    D = 0: GH_BD = 5 ' cot Ngay GH bat dau
    Set rg = cell(n, KH_BD).Resize(, 31)
    Set KH = rg.Find("X", After:=rg(1, 31), LookIn:=xlValues, LookAt:=xlWhole)
    If Not KH Is Nothing Then
      KHFirstAddress = KH.Address
      Do
        NgayKH = KH.Column
        Set rg0 = cell(n + 1, GH_BD).Resize(, GH_KT - GH_BD + 1)
        Set GH = rg0.Find("O", After:=rg0(1, rg0.Columns.Count), LookIn:=xlValues, LookAt:=xlWhole)
        If Not GH Is Nothing Then
          GHFirstAddress = GH.Address
          NgayGH = GH.Column
          GH_BD = NgayGH + 1 ' Vùng tim kiem "O" se duoc thu hep lai trong lan Loop tìm "X" tiep theo
        Else
          D = D - 7: Exit Do' Khong co ngay giao hang ( chua giao hang)
        End If
        Select Case NgayGH - NgayKH
        Case Is < 1: D = D     'giao hang truoc
        Case Is < 3: D = D - 2 ' Giao hang muon 1~2 ngay
        Case Is < 5: D = D - 5 ' giao hang muon 3~4 ngay
        Case Else: D = D - 7   ' Giao hang muon tren 5 ngay
        End Select
        Set KH = rg.FindNext(KH)
        If KH Is Nothing Then Exit Do
        If KHFirstAddress = KH.Address Then Exit Do
      Loop
      cell(n, KH_KT + 1).Value = D ' Diem
    Else
    End If
  Next
End Sub
Cảm ơn bạn đã sửa code giúp mình.
Set KH = rg.FindNext(KH)
If KH Is Nothing Then Exit Do
If KHFirstAddress = KH.Address Then Exit Do
Đoạn này làm cho chỉ tìm được 1 ngày KH~ X trong khi đó 1 tháng có nhiều ngày đánh X.
Mình vẫn chưa hiểu lồng 2 phương thức Find thì KH lại bằng nothing với lần FindNext thứ 2.

Cảm ơn bạn nhiều
Bài đã được tự động gộp:

Lỗi ở dòng Loop While ở trên là KH lúc đó nó không phải là một Range Object, nên không để truy xuất Address

Bạn cần thêm lệnh bẫy lỗi đầu thủ tục: On Error Resume Next
Kiểm tra:
JavaScript:
    Err.Clear: Set KH = ...
    If Err <> 0 Or KH Is Nothing Then Exit Do
Chào bạn. Thêm đoạn bẫy lỗi thì sẽ chỉ tìm được 1 lần Kế hoạch "X" duy nhất thôi, Không tìm được các lần kế hoạch về tiếp theo để so sánh.
Mình chưa hiểu tại sao set KH vậy lại bằng nothing.

Cảm ơn bạn nhiều
Gán Vùng ô nguồn vào một biến rồi mới dùng Find bạn nhé
JavaScript:
Dim rg, KH
Set rg = Sheet1.Range(Sheet1.Cells(...),Sheet1.Cells(...))
Set KH= rg.Find(...)
Set KH= rg.FindNext(KH)
Cảm ơn bạn.
Gán biến bên trên theo mình thấy chỉ thu gọn code lại thôi. Mình chạy vẫn bị lỗi. Mình gửi file đã sửa. Bạn xem giúp mình nhé.

Cảm ơn bạn.
@Chủ bài đăng: Phương thức FIND() không thể lồng vô nhau được;
& mình cũng chưa rõ khái niệm 'tìm ngày khách hàng (KH) về' là như thế nào?
Thứ nữa: Các ô chứa dữ liệu không nên trộn như bạn; Tuy có đẹp như lắm phiền phức khi xài VBA
Chào anh.
Đúng là VBA mà trộn ô thì sau phát triển tiếp rất khó.
File này em chỉ làm code trong phạm vi không trộn ô thôi.
Em giải thích lại .

1 NCC có 2 dòng.
- 1 dòng tương ứng ngày kế hoạch giao : Đánh "X"
- 1 dòng tương ứng ngày giao hàng thực tế : Đánh"O"
- Trong tháng ( file chỉ 1 tháng 1) có nhiều lần KH và GH ("X" và "O)
Code:

+ So sánh ngày kế hoạch và ngày giao hàng.
-Nếu giao trước thì dc 0 điểm ( ko bị trừ)
- Nếu giao muộn 1~2 ngày thì bị trừ 2 điểm
- Nếu giao muộn 3~4 ngày bị trừ 5 điểm
- Nếu giao muộn trên 5 ngày trừ 7 điểm.

Em cảm ơn a
Tôi chỉ giúp bạn sửa mã, còn bài toán đáng lý ra là phải đăng ngay từ bài viết đầu để nhận trợ giúp về bài toán.

JavaScript:
Sub tinh_toan()

  Dim NgayGH%, NgayKH%, D%, n%, GH_BD%
  Dim cell As Range, rg0 As Range, rg As Range, KH As Range, KHFirstAddress As String
  Dim GH As Range, GHFirstAddress As String
  Const KH_BD = 5 ' cot Ngay KH bat dau
  Const KH_KT = 35 ' cot Ngay KH ket thuc
  Const GH_KT = 35 ' cot Ngay GH ket thuc
  Set cell = [A5]
  For n = 1 To 32 Step 2 ' SL NCC
    D = 0: GH_BD = 5 ' cot Ngay GH bat dau
    Set rg = cell(n, KH_BD).Resize(, 31)
    Set KH = rg.Find("X", After:=rg(1, 31), LookIn:=xlValues, LookAt:=xlWhole)
    If Not KH Is Nothing Then
      KHFirstAddress = KH.Address
      Do
        NgayKH = KH.Column
        Set rg0 = cell(n + 1, GH_BD).Resize(, GH_KT - GH_BD + 1)
        Set GH = rg0.Find("O", After:=rg0(1, rg0.Columns.Count), LookIn:=xlValues, LookAt:=xlWhole)
        If Not GH Is Nothing Then
          GHFirstAddress = GH.Address
          NgayGH = GH.Column
          GH_BD = NgayGH + 1 ' Vùng tim kiem "O" se duoc thu hep lai trong lan Loop tìm "X" tiep theo
        Else
          D = D - 7: Exit Do' Khong co ngay giao hang ( chua giao hang)
        End If
        Select Case NgayGH - NgayKH
        Case Is < 1: D = D     'giao hang truoc
        Case Is < 3: D = D - 2 ' Giao hang muon 1~2 ngay
        Case Is < 5: D = D - 5 ' giao hang muon 3~4 ngay
        Case Else: D = D - 7   ' Giao hang muon tren 5 ngay
        End Select
        Set KH = rg.FindNext(KH)
        If KH Is Nothing Then Exit Do
        If KHFirstAddress = KH.Address Then Exit Do
      Loop
      cell(n, KH_KT + 1).Value = D ' Diem
    Else
    End If
  Next
End Sub
Cảm ơn bạn đã sửa code giúp mình.
Set KH = rg.FindNext(KH)
If KH Is Nothing Then Exit Do
If KHFirstAddress = KH.Address Then Exit Do
Đoạn này làm cho chỉ tìm được 1 ngày KH~ X trong khi đó 1 tháng có nhiều ngày đánh X.
Mình vẫn chưa hiểu lồng 2 phương thức Find thì KH lại bằng nothing với lần FindNext thứ 2.

Cảm ơn bạn nhiều
Giải bài toán của bạn:

JavaScript:
Sub tinh_toan()
  Dim NgayKH%, D%, n%, i%, cell As Range, rg As Range
  Const KH_BD = 5 ' cot Ngay KH bat dau
  Const KH_KT = 35 ' cot Ngay KH ket thuc
  Set cell = [A5]: n = 1
  While cell(n, 1).Value <> Empty
    D = 0
    Set rg = cell(n, KH_BD).Resize(2, 31)
    For i = 1 To 31
      If CStr(rg(1, i).Value) = "X" Then
        If NgayKH > 0 Then D = D - 7
        NgayKH = i
      End If
      If CStr(rg(2, i).Value) = "O" Then GoSub v: NgayKH = 0
    Next
    rg(1, i).Value = D
    n = n + cell(n, 1).MergeArea.Rows.Count
  Wend
Exit Sub
v:
  Select Case i - NgayKH
  Case Is < 1: D = D     ' giao hang truoc
  Case Is < 3: D = D - 2 ' Giao hang muon 1~2 ngay
  Case Is < 5: D = D - 5 ' giao hang muon 3~4 ngay
  Case Else: D = D - 7   ' Giao hang muon tren 5 ngay
  End Select
Return
End Sub
Xin lỗi. Code chạy không cho ra kết quả chính xác.
Bạn test lại giúp mình.
Mình cảm ơn
 
Lần chỉnh sửa cuối:
Upvote 0
Mình mong muốn kết quả ra như hình. Nhờ bạn chỉnh code giúp.
Mình cảm ơn
1705369610994.png
Bài đã được tự động gộp:

Dùng mảng và vòng For
Mã:
Sub XYZ()
  Dim arr(), res(), sRow&, sCol&, i&, j&, c&, d&, fC&, cl&
 
  arr = Range("B5", Range("AI" & Range("B1000000").End(xlUp).Row + 1)).Value
  sRow = UBound(arr):             sCol = UBound(arr, 2)
  ReDim res(1 To sRow, 1 To 1)
  For i = 1 To sRow
    If arr(i, 1) <> Empty Then
      d = 0: fC = 4
      For j = 4 To sCol
        If UCase(arr(i, j)) = "X" Then
          For c = fC To sCol
            If UCase(arr(i + 1, c)) = "O" Then
              cl = c - j
              If cl > 4 Then 'Tru 7 diem
                d = d - 7
              ElseIf cl > 2 Then 'Tru 5 diem
                d = d - 5
              ElseIf cl > 0 Then 'Tru 2 diem
                d = d - 2
              End If
              fC = c + 1
              Exit For
            End If
          Next c
          If c = sCol + 1 Then d = d - 7 'Tru 7 diem
        End If
      Next j
      res(i, 1) = d
    End If
  Next i
  Range("AJ5").Resize(sRow) = res
End Sub
Code của bạn chạy đúng yêu cầu rồi .
Tuy nhiên hơi khó nhìn chút. Mình sẽ xem lại chi tiết .
Cảm ơn bạn nhiều.
 
Upvote 0
Bạn xem lại mã này, Bạn đưa ra bài toán thiếu khá nhiều dữ kiện

Còn trường hợp này thì tính sao:


XX
OO



JavaScript:
Sub tinh_toan()
  Dim NgayKH%, NgayGH%, D%, n%, i%, cell As Range, rg As Range
  Const KH_BD = 5 ' cot Ngay KH bat dau
  Const KH_KT = 35 ' cot Ngay KH ket thuc
  Set cell = [A5]: n = 1
  While cell(n, 1).Value <> Empty
    D = 0
    Set rg = cell(n, KH_BD).Resize(2, 31)
    For i = 1 To 31
      If CStr(rg(1, i).Value) = "X" Then
        If NgayGH > 0 Then
          NgayGH = 0: NgayKH = 0
        Else
          If NgayKH > 0 Then D = D - 7
          NgayKH = i
        End If
      End If
      If CStr(rg(2, i).Value) = "O" Then
        If NgayKH > 0 Then
          Select Case i - NgayKH
          Case Is < 1: D = D     ' giao hang truoc
          Case Is < 3: D = D - 2 ' Giao hang muon 1~2 ngay
          Case Is < 5: D = D - 5 ' giao hang muon 3~4 ngay
          Case Else: D = D - 7   ' Giao hang muon tren 5 ngay
          End Select
        Else
          NgayGH = i
        End If
        NgayKH = 0
      End If
    Next
    rg(1, i).Value = D
    n = n + cell(n, 1).MergeArea.Rows.Count
  Wend
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn xem lại mã này, Bạn đưa ra bài toán thiếu khá nhiều dữ kiện

Còn trường hợp này thì tính sao:


XX
OO



JavaScript:
Sub tinh_toan()
  Dim NgayKH%, NgayGH%, D%, n%, i%, cell As Range, rg As Range
  Const KH_BD = 5 ' cot Ngay KH bat dau
  Const KH_KT = 35 ' cot Ngay KH ket thuc
  Set cell = [A5]: n = 1
  While cell(n, 1).Value <> Empty
    D = 0
    Set rg = cell(n, KH_BD).Resize(2, 31)
    For i = 1 To 31
      If CStr(rg(1, i).Value) = "X" Then
        If NgayGH > 0 Then
          NgayGH = 0: NgayKH = 0
        Else
          If NgayKH > 0 Then D = D - 7
          NgayKH = i
        End If
      End If
      If CStr(rg(2, i).Value) = "O" Then
        If NgayKH > 0 Then
          Select Case i - NgayKH
          Case Is < 1: D = D     ' giao hang truoc
          Case Is < 3: D = D - 2 ' Giao hang muon 1~2 ngay
          Case Is < 5: D = D - 5 ' giao hang muon 3~4 ngay
          Case Else: D = D - 7   ' Giao hang muon tren 5 ngay
          End Select
        Else
          NgayGH = i
        End If
        NgayKH = 0
      End If
    Next
    cell(n, i).Value = D
    n = n + cell(n, 1).MergeArea.Rows.Count
  Wend
End Sub
Trường hợp này sẽ đều giao chậm
Lần 1 giao chậm 5 ngày
Lần 2 giao chậm 3 ngày.
Cảm ơn bạn
Bài đã được tự động gộp:

Code so sánh, X được tìm thấy đầu tiên từ trái qua phải với O đầu tiên từ trái qua phải.
Và tiếp theo.
 
Upvote 0
Web KT
Back
Top Bottom