Tôi có dãy số A4:AZ4 , các số nằm trên cột lẽ là các số lẽ, số trên cột chẵn là các số chẵn - xác định xu hướng các phần tử trong cột theo cấp 1,2,3 so với cột 1,2,3 trước đó theo quy tắc
1. Nếu valNow =1 & valPrev = valTruocPrev --> ổn định “OD”
2. Nếu valNow =1 & valPrev ≠ valTruocPrev --> hỗn loạn “HL”
3. Nếu valNow > 1 & valNow -1 = valPrev --> hỗn loạn “HL”
4. Nếu valNow >1 & valNow -1 ≠ valPrev --> ổn định “OD”
Với : valNow : phần tử dòng hiện tại ( j chỉ số dòng hiện tại trong cột i)
valPrev : giá trị cột trước 1 dòng hiện tại = sh.Cells(4, i-1).Value
valTruocPrev : giá trị cột trước 2 dòng hiện tại = sh.Cells(4, i-2).Value
T,2T hoặc 3T báo hiệu sẽ thay đổi đường đi của dãy (file đính kèm) - tôi có mã cho cấp 1 mà viết hoài không chạy đúng yêu cầu (trong file) - mong các Thầy, các sư phụ trợ giúp dùm - thanks
Yêu cầu : xác định xu hướng cấp 1,2,3 mã hoá thành số ghi chuỗi xu hướng vào A6:AZ6; A8:AZ8; A10:AZ10 theo các cấp 1,2,3
Tôi hiểu bạn cần xác định xu hướng cấp 1, 2, 3 cho dãy số từ A4:AZ4, với các cột lẻ chứa số lẻ và cột chẵn chứa số chẵn, dựa trên quy tắc đã cho, và ghi kết quả vào các ô A6:AZ6 (cấp 1), A8:AZ8 (cấp 2), A10:AZ10 (cấp 3). Bạn đã đề cập đến một file đính kèm, nhưng vì tôi không thể truy cập file, tôi sẽ dựa vào mô tả của bạn để cung cấp mã VBA chính xác và giải thích rõ ràng.
Phân tích yêu cầu
Dữ liệu đầu vào:
Dãy số nằm ở hàng 4, từ cột A đến AZ (cột 1 đến 52 trong Excel).
Cột lẻ (1, 3, 5, ..., 51) chứa số lẻ.
Cột chẵn (2, 4, 6, ..., 52) chứa số chẵn.
Mỗi cấp (1, 2, 3) được tính toán dựa trên các quy tắc xu hướng.
Quy tắc xu hướng:
Cho cột hiện tại i (với i từ 3 trở đi, vì cần tham chiếu đến valPrev và valTruocPrev):
valNow = sh.Cells(4, i).Value: Giá trị tại cột hiện tại.
valPrev = sh.Cells(4, i-1).Value: Giá trị tại cột trước đó.
valTruocPrev = sh.Cells(4, i-2).Value: Giá trị tại cột trước đó nữa.
Cấp 1: Phân tích xu hướng trực tiếp từ dãy số ở A4:AZ4, ghi kết quả vào A6:AZ6.
Cấp 2: Phân tích xu hướng của dãy xu hướng cấp 1 (A6:AZ6), ghi kết quả vào A8:AZ8.
Cấp 3: Phân tích xu hướng của dãy xu hướng cấp 2 (A8:AZ8), ghi kết quả vào A10:AZ10.
Giá trị xu hướng được mã hóa thành số:
"OD" → 0
"HL" → 1
"T", "2T", "3T" báo hiệu thay đổi đường đi, nhưng không rõ cách xác định → giả sử chúng là các giá trị đặc biệt được xác định từ dữ liệu.
Vấn đề của bạn:
Mã VBA hiện tại của bạn (trong file) không chạy đúng yêu cầu.
Bạn cần mã hóa xu hướng thành số và ghi vào các ô tương ứng.
Giả định:
Vì không có thông tin cụ thể về "T", "2T", "3T", tôi giả định rằng các giá trị này xuất hiện khi một chuỗi xu hướng (ví dụ: liên tục "OD" hoặc "HL") đạt đến một ngưỡng nào đó, hoặc chúng được xác định bởi một quy tắc bổ sung. Nếu bạn có quy tắc cụ thể cho "T", "2T", "3T", hãy cung cấp thêm để tôi điều chỉnh mã.
Tôi sẽ mã hóa "OD" = 0, "HL" = 1, và giả sử "T", "2T", "3T" sẽ được xử lý nếu có quy tắc rõ ràng. Nếu không, mã sẽ tập trung vào "OD" và "HL" trước.
Mã VBA đề xuất
Dưới đây là mã VBA để giải quyết yêu cầu của bạn. Mã này:
Tính xu hướng cấp 1 dựa trên A4:AZ4 và ghi vào A6:AZ6.
Tính xu hướng cấp 2 dựa trên A6:AZ6 và ghi vào A8:AZ8.
Tính xu hướng cấp 3 dựa trên A8:AZ8 và ghi vào A10:AZ10.
Mã hóa "OD" = 0, "HL" = 1.
vba
Mã:
Sub XuHuongCap123()
Dim sh As Worksheet
Dim i As Long
Dim valNow As Double, valPrev As Double, valTruocPrev As Double
Dim xuHuong As String
Dim lastCol As Long
' Thiết lập worksheet
Set sh = ThisWorkbook.Sheets("Sheet1") ' Thay "Sheet1" bằng tên sheet của bạn
' Xác định cột cuối (AZ = 52)
lastCol = 52 ' Từ cột A đến AZ
' Xóa dữ liệu cũ trong các ô kết quả
sh.Range("A6:AZ6").ClearContents
sh.Range("A8:AZ8").ClearContents
sh.Range("A10:AZ10").ClearContents
' Tính xu hướng cấp 1 (dựa trên A4:AZ4)
For i = 3 To lastCol
valNow = sh.Cells(4, i).Value
valPrev = sh.Cells(4, i - 1).Value
valTruocPrev = sh.Cells(4, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(6, i).Value = xuHuong
Next i
' Tính xu hướng cấp 2 (dựa trên A6:AZ6)
For i = 3 To lastCol
valNow = sh.Cells(6, i).Value
valPrev = sh.Cells(6, i - 1).Value
valTruocPrev = sh.Cells(6, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(8, i).Value = xuHuong
Next i
' Tính xu hướng cấp 3 (dựa trên A8:AZ8)
For i = 3 To lastCol
valNow = sh.Cells(8, i).Value
valPrev = sh.Cells(8, i - 1).Value
valTruocPrev = sh.Cells(8, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(10, i).Value = xuHuong
Next i
End Sub
Giải thích mã
Khởi tạo:
Đặt worksheet là "Sheet1" (bạn cần thay đổi nếu tên sheet khác).
Xác định cột cuối là 52 (tương ứng với AZ).
Xóa dữ liệu cũ trong các ô kết quả (A6:AZ6, A8:AZ8, A10:AZ10) để tránh chồng lấn.
Tính xu hướng cấp 1:
Duyệt từ cột 3 (C) đến cột 52 (AZ).
Lấy valNow, valPrev, valTruocPrev từ hàng 4.
Áp dụng 4 quy tắc để xác định xu hướng ("OD" = 0, "HL" = 1).
Ghi kết quả vào hàng 6.
Tính xu hướng cấp 2:
Tương tự, lấy dữ liệu từ hàng 6 (kết quả cấp 1).
Áp dụng cùng quy tắc để xác định xu hướng.
Ghi kết quả vào hàng 8.
Tính xu hướng cấp 3:
Lấy dữ liệu từ hàng 8 (kết quả cấp 2).
Áp dụng quy tắc và ghi kết quả vào hàng 10.
Mã hóa:
"OD" được mã hóa thành 0.
"HL" được mã hóa thành 1.
Về "T", "2T", "3T"
Bạn đề cập rằng "T", "2T", "3T" báo hiệu thay đổi đường đi, nhưng không cung cấp quy tắc cụ thể để xác định chúng.
Nếu chúng được xác định dựa trên một chuỗi "OD" hoặc "HL" liên tiếp (ví dụ: 3 lần "HL" liên tiếp → "T"), hãy cung cấp thêm chi tiết, tôi sẽ bổ sung logic để xử lý.
Hiện tại, mã trên chỉ xử lý "OD" và "HL" vì đây là các quy tắc rõ ràng bạn đã đưa ra.
Hướng dẫn chạy mã
Mở Excel, nhấn Alt + F11 để vào VBA Editor.
Thêm một Module mới (Insert > Module).
Sao chép và dán mã trên vào Module.
Thay đổi tên sheet (Sheet1) trong mã nếu cần.
Đảm bảo dữ liệu ở A4:AZ4 đã được nhập đúng (cột lẻ là số lẻ, cột chẵn là số chẵn).
Chạy macro (F5 hoặc từ menu Excel).
Nếu mã không chạy đúng
Kiểm tra dữ liệu đầu vào:
Đảm bảo A4:AZ4 chứa số hợp lệ (cột lẻ: số lẻ, cột chẵn: số chẵn).
Kiểm tra xem có ô trống hoặc giá trị không phải số trong A4:AZ4 không.
Kiểm tra lỗi:
Nếu mã báo lỗi, hãy cho tôi biết thông báo lỗi cụ thể để tôi sửa.
Cung cấp thêm thông tin:
Nếu có quy tắc cụ thể cho "T", "2T", "3T", hãy mô tả chi tiết.
Nếu bạn có mã cũ (mã bạn nói "không chạy đúng"), hãy chia sẻ để tôi so sánh và tìm lỗi.
Lưu ý
Mã hiện tại giả định dữ liệu ở A4:AZ4 là số. Nếu dữ liệu là văn bản hoặc có định dạng đặc biệt, cần điều chỉnh thêm.
Nếu bạn muốn kết quả hiển thị "OD"/"HL" thay vì 0/1, chỉ cần thay xuHuong = "0" thành xuHuong = "OD" và xuHuong = "1" thành xuHuong = "HL" trong mã.
Nếu cần thêm logic cho "T", "2T", "3T", hãy cung cấp quy tắc để tôi cập nhật mã.
Hãy chạy thử mã trên và cho tôi biết kết quả hoặc bất kỳ lỗi nào bạn gặp. Nếu bạn có thêm chi tiết về file hoặc quy tắc "T", "2T", "3T", tôi sẽ tinh chỉnh mã cho phù hợp. Cảm ơn bạn đã tin tưởng, hy vọng mã này giúp bạn giải quyết vấn đề!
Dãy số nằm ở hàng 4, từ cột A đến AZ (cột 1 đến 52 trong Excel).
Cột lẻ (1, 3, 5, ..., 51) chứa số cùng phần tử B.
Cột chẵn (2, 4, 6, ..., 52) chứa số cùng phần tử P.
Mỗi cấp (1, 2, 3) được so sánh với cột 1,2,3 trước đó, giả sử dãy dữ liệu ( A4:F4 lần lượt 2,3,5,5,1,1) tại vị trí hiện tại cột D4 =5 có 5 phần tử so sánh với cột 1 (C4=5=valPrev) sẽ có 5 xu hướng cấp 1; tương tự cấp 2 (B4=3) sẽ có 5 xu hướng cấp 2 và cấp 3 (A4=2) sẽ có 5 xu hướng cấp 3
Quy tắc xu hướng:
Cho cột hiện tại i (với i = 2 và valNow > 1 đã có xu hướng, tham chiếu quy tắc 3,4 chỉ cần xét đến cột trước valPrev và valNow - 1 =1 giá trị nguyên dương hợp lệ):
valNow = sh.Cells(4, i).Value: Giá trị tại cột hiện tại.
valPrev = sh.Cells(4, i-1).Value: Giá trị tại cột trước đó.
valTruocPrev = sh.Cells(4, i-2).Value: Giá trị tại cột trước đó nữa.
Cấp 1: Phân tích xu hướng so với cột thứ 1 trước đó trực tiếp từ dãy số ở A4:AZ4, ghi kết quả vào A6:AZ6.
Cấp 2: Phân tích xu hướng so với cột thứ 2 trước đó từ dãy số ở A4:AZ4, ghi kết quả vào A8:AZ8
Cấp 3: Phân tích xu hướng so với cột thứ 3 trước đó từ dãy số ở A4:AZ4, ghi kết quả vào A10:AZ10.
Giá trị xu hướng được mã hóa thành số:
"OD" → 1 và được cộng dồn khi xu hướng cùng loại OD liên tiếp xuất hiện ( ví dụ: dãy A4=6, B4=7 ta xác định xu hướng cấp 1 tại cột B4 ( có 7 phần tử nhưng phần tử B4=1 không có valTruocPrev nên không có xu hướng) là OD, OD, OD, OD, OD, HL ghi kết quả vào cột lẽ là cột A6 = 5 cột B6=1
"HL" → 1 và được cộng dồn khi xu hướng cùng loại HL liên tiếp xuất hiện
xu hướng OD được ghi vào cột lẽ và HL ghi vào cột chẵn
"T", "2T", "3T" báo hiệu ngắt mảng xu hướng hiện tại và tiếp tục chuỗi xu hướng mới với cột bắt đầu là cột kề tiếp theo. Nếu cột tiếp theo sau T là khác loại chẵn/lẽ - xu hướng sẽ chuỗi mới xác định bình thường theo quy tắc xu hướng; Nếu cột tiếp theo sau T là cùng loại chẵn/lẽ thì sẽ được cộng dồn vào cột trước T và tiếp tục xác định hướng. Giả sử dãy dữ liệu nhập A4:E4 theo bảng khi T xuất hiện nhưng phần tử chẵn (P) vẫn xuất hiện nên dữ liệu ghi vào cột chẵn (D) và xu hướng khi T xuất hiện sẽ được cộng 2+1=3 và xác định tiếp chuổi xu hướng mới với 2 phần tử D nhưng được gộp vào B và vẫn tính xu hướng cấp 1 so với A theo quy tắc
A
B
C
D
E
3
1
2
3
T
mã VBA đinh kèm sau
vấn đề :
với 4 quy tắc khi dùng hàm for ..... IF .... thì không đồng bộ nhau ( ví dụ khi điều chỉnh các điều kiện của Quy tắc 1,2 thì mã chạy sai quy tắc 3,4 và ngược lại - Mong Thầy giúp - Thanks
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("A4:AZ4")) Is Nothing Then
Application.EnableEvents = False
XacDinhXuHuongCap1
Application.EnableEvents = True
End If
End Sub
Function XuHuongCap1(valNow As Long, valPrev As Variant, valTruocPrev As Variant) As String
If valNow = 1 Then
If valPrev = valTruocPrev Then
XuHuongCap1 = "L" ' ?n d?nh
Else
XuHuongCap1 = "C" ' H?n lo?n
End If
Else
If valNow - 1 = valPrev Then
XuHuongCap1 = "C"
Else
XuHuongCap1 = "L"
End If
End If
End Function
Sub XacDinhXuHuongCap1()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets(1)
Dim i As Long, valNow As Long
Dim valPrev As Variant, valTruocPrev As Variant
Dim xuHuong As String
Dim danhSachXuHuong() As String
Dim xuHuongTruoc As String
Dim dem As Long
Dim ketQua() As Long
Dim k As Long: k = 1
Dim lastCol As Long: lastCol = 52 ' AZ
ReDim danhSachXuHuong(1 To 1000)
For i = 2 To lastCol
Dim soPhanTu As Long
soPhanTu = sh.Cells(4, i).Value
If soPhanTu < 1 Then GoTo NextCol
For valNow = 1 To soPhanTu
If valNow = 1 Then
If i < 3 Then GoTo NextVal ' Không ?? d? li?u
valPrev = sh.Cells(4, i - 1).Value
valTruocPrev = sh.Cells(4, i - 2).Value
If valPrev = valTruocPrev Then
xuHuong = "OD"
Else
xuHuong = "HL"
End If
Else
If i < 2 Then GoTo NextVal ' Không ?? d? li?u
valPrev = sh.Cells(4, i - 1).Value
If (valNow - 1) = valPrev Then
xuHuong = "HL"
Else
xuHuong = "OD"
End If
End If
danhSachXuHuong(k) = xuHuong
k = k + 1
NextVal:
Next valNow
NextCol:
Next i
ReDim ketQua(1 To 500)
Dim ketQuaIndex As Long: ketQuaIndex = 1
If k = 1 Then Exit Sub
xuHuongTruoc = danhSachXuHuong(1)
dem = 1
For i = 2 To k - 1
If danhSachXuHuong(i) = xuHuongTruoc Then
dem = dem + 1
Else
ketQua(ketQuaIndex) = dem
ketQuaIndex = ketQuaIndex + 1
xuHuongTruoc = danhSachXuHuong(i)
dem = 1
End If
Next i
ketQua(ketQuaIndex) = dem
sh.Range("A6:AZ6").ClearContents
For i = 1 To ketQuaIndex
sh.Cells(6, i).Value = ketQua(i)
Next i
Tôi hiểu bạn cần xác định xu hướng cấp 1, 2, 3 cho dãy số từ A4:AZ4, với các cột lẻ chứa số lẻ và cột chẵn chứa số chẵn, dựa trên quy tắc đã cho, và ghi kết quả vào các ô A6:AZ6 (cấp 1), A8:AZ8 (cấp 2), A10:AZ10 (cấp 3). Bạn đã đề cập đến một file đính kèm, nhưng vì tôi không thể truy cập file, tôi sẽ dựa vào mô tả của bạn để cung cấp mã VBA chính xác và giải thích rõ ràng.
Phân tích yêu cầu
Dữ liệu đầu vào:
Dãy số nằm ở hàng 4, từ cột A đến AZ (cột 1 đến 52 trong Excel).
Cột lẻ (1, 3, 5, ..., 51) chứa số lẻ.
Cột chẵn (2, 4, 6, ..., 52) chứa số chẵn.
Mỗi cấp (1, 2, 3) được tính toán dựa trên các quy tắc xu hướng.
Quy tắc xu hướng:
Cho cột hiện tại i (với i từ 3 trở đi, vì cần tham chiếu đến valPrev và valTruocPrev):
valNow = sh.Cells(4, i).Value: Giá trị tại cột hiện tại.
valPrev = sh.Cells(4, i-1).Value: Giá trị tại cột trước đó.
valTruocPrev = sh.Cells(4, i-2).Value: Giá trị tại cột trước đó nữa.
Cấp 1: Phân tích xu hướng trực tiếp từ dãy số ở A4:AZ4, ghi kết quả vào A6:AZ6.
Cấp 2: Phân tích xu hướng của dãy xu hướng cấp 1 (A6:AZ6), ghi kết quả vào A8:AZ8.
Cấp 3: Phân tích xu hướng của dãy xu hướng cấp 2 (A8:AZ8), ghi kết quả vào A10:AZ10.
Giá trị xu hướng được mã hóa thành số:
"OD" → 0
"HL" → 1
"T", "2T", "3T" báo hiệu thay đổi đường đi, nhưng không rõ cách xác định → giả sử chúng là các giá trị đặc biệt được xác định từ dữ liệu.
Vấn đề của bạn:
Mã VBA hiện tại của bạn (trong file) không chạy đúng yêu cầu.
Bạn cần mã hóa xu hướng thành số và ghi vào các ô tương ứng.
Giả định:
Vì không có thông tin cụ thể về "T", "2T", "3T", tôi giả định rằng các giá trị này xuất hiện khi một chuỗi xu hướng (ví dụ: liên tục "OD" hoặc "HL") đạt đến một ngưỡng nào đó, hoặc chúng được xác định bởi một quy tắc bổ sung. Nếu bạn có quy tắc cụ thể cho "T", "2T", "3T", hãy cung cấp thêm để tôi điều chỉnh mã.
Tôi sẽ mã hóa "OD" = 0, "HL" = 1, và giả sử "T", "2T", "3T" sẽ được xử lý nếu có quy tắc rõ ràng. Nếu không, mã sẽ tập trung vào "OD" và "HL" trước.
Mã VBA đề xuất
Dưới đây là mã VBA để giải quyết yêu cầu của bạn. Mã này:
Tính xu hướng cấp 1 dựa trên A4:AZ4 và ghi vào A6:AZ6.
Tính xu hướng cấp 2 dựa trên A6:AZ6 và ghi vào A8:AZ8.
Tính xu hướng cấp 3 dựa trên A8:AZ8 và ghi vào A10:AZ10.
Mã hóa "OD" = 0, "HL" = 1.
vba
Mã:
Sub XuHuongCap123()
Dim sh As Worksheet
Dim i As Long
Dim valNow As Double, valPrev As Double, valTruocPrev As Double
Dim xuHuong As String
Dim lastCol As Long
' Thiết lập worksheet
Set sh = ThisWorkbook.Sheets("Sheet1") ' Thay "Sheet1" bằng tên sheet của bạn
' Xác định cột cuối (AZ = 52)
lastCol = 52 ' Từ cột A đến AZ
' Xóa dữ liệu cũ trong các ô kết quả
sh.Range("A6:AZ6").ClearContents
sh.Range("A8:AZ8").ClearContents
sh.Range("A10:AZ10").ClearContents
' Tính xu hướng cấp 1 (dựa trên A4:AZ4)
For i = 3 To lastCol
valNow = sh.Cells(4, i).Value
valPrev = sh.Cells(4, i - 1).Value
valTruocPrev = sh.Cells(4, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(6, i).Value = xuHuong
Next i
' Tính xu hướng cấp 2 (dựa trên A6:AZ6)
For i = 3 To lastCol
valNow = sh.Cells(6, i).Value
valPrev = sh.Cells(6, i - 1).Value
valTruocPrev = sh.Cells(6, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(8, i).Value = xuHuong
Next i
' Tính xu hướng cấp 3 (dựa trên A8:AZ8)
For i = 3 To lastCol
valNow = sh.Cells(8, i).Value
valPrev = sh.Cells(8, i - 1).Value
valTruocPrev = sh.Cells(8, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(10, i).Value = xuHuong
Next i
End Sub
Giải thích mã
Khởi tạo:
Đặt worksheet là "Sheet1" (bạn cần thay đổi nếu tên sheet khác).
Xác định cột cuối là 52 (tương ứng với AZ).
Xóa dữ liệu cũ trong các ô kết quả (A6:AZ6, A8:AZ8, A10:AZ10) để tránh chồng lấn.
Tính xu hướng cấp 1:
Duyệt từ cột 3 (C) đến cột 52 (AZ).
Lấy valNow, valPrev, valTruocPrev từ hàng 4.
Áp dụng 4 quy tắc để xác định xu hướng ("OD" = 0, "HL" = 1).
Ghi kết quả vào hàng 6.
Tính xu hướng cấp 2:
Tương tự, lấy dữ liệu từ hàng 6 (kết quả cấp 1).
Áp dụng cùng quy tắc để xác định xu hướng.
Ghi kết quả vào hàng 8.
Tính xu hướng cấp 3:
Lấy dữ liệu từ hàng 8 (kết quả cấp 2).
Áp dụng quy tắc và ghi kết quả vào hàng 10.
Mã hóa:
"OD" được mã hóa thành 0.
"HL" được mã hóa thành 1.
Về "T", "2T", "3T"
Bạn đề cập rằng "T", "2T", "3T" báo hiệu thay đổi đường đi, nhưng không cung cấp quy tắc cụ thể để xác định chúng.
Nếu chúng được xác định dựa trên một chuỗi "OD" hoặc "HL" liên tiếp (ví dụ: 3 lần "HL" liên tiếp → "T"), hãy cung cấp thêm chi tiết, tôi sẽ bổ sung logic để xử lý.
Hiện tại, mã trên chỉ xử lý "OD" và "HL" vì đây là các quy tắc rõ ràng bạn đã đưa ra.
Hướng dẫn chạy mã
Mở Excel, nhấn Alt + F11 để vào VBA Editor.
Thêm một Module mới (Insert > Module).
Sao chép và dán mã trên vào Module.
Thay đổi tên sheet (Sheet1) trong mã nếu cần.
Đảm bảo dữ liệu ở A4:AZ4 đã được nhập đúng (cột lẻ là số lẻ, cột chẵn là số chẵn).
Chạy macro (F5 hoặc từ menu Excel).
Nếu mã không chạy đúng
Kiểm tra dữ liệu đầu vào:
Đảm bảo A4:AZ4 chứa số hợp lệ (cột lẻ: số lẻ, cột chẵn: số chẵn).
Kiểm tra xem có ô trống hoặc giá trị không phải số trong A4:AZ4 không.
Kiểm tra lỗi:
Nếu mã báo lỗi, hãy cho tôi biết thông báo lỗi cụ thể để tôi sửa.
Cung cấp thêm thông tin:
Nếu có quy tắc cụ thể cho "T", "2T", "3T", hãy mô tả chi tiết.
Nếu bạn có mã cũ (mã bạn nói "không chạy đúng"), hãy chia sẻ để tôi so sánh và tìm lỗi.
Lưu ý
Mã hiện tại giả định dữ liệu ở A4:AZ4 là số. Nếu dữ liệu là văn bản hoặc có định dạng đặc biệt, cần điều chỉnh thêm.
Nếu bạn muốn kết quả hiển thị "OD"/"HL" thay vì 0/1, chỉ cần thay xuHuong = "0" thành xuHuong = "OD" và xuHuong = "1" thành xuHuong = "HL" trong mã.
Nếu cần thêm logic cho "T", "2T", "3T", hãy cung cấp quy tắc để tôi cập nhật mã.
Hãy chạy thử mã trên và cho tôi biết kết quả hoặc bất kỳ lỗi nào bạn gặp. Nếu bạn có thêm chi tiết về file hoặc quy tắc "T", "2T", "3T", tôi sẽ tinh chỉnh mã cho phù hợp. Cảm ơn bạn đã tin tưởng, hy vọng mã này giúp bạn giải quyết vấn đề!
Tôi hiểu bạn cần xác định xu hướng cấp 1, 2, 3 cho dãy số từ A4:AZ4, với các cột lẻ chứa số lẻ và cột chẵn chứa số chẵn, dựa trên quy tắc đã cho, và ghi kết quả vào các ô A6:AZ6 (cấp 1), A8:AZ8 (cấp 2), A10:AZ10 (cấp 3). Bạn đã đề cập đến một file đính kèm, nhưng vì tôi không thể truy cập file, tôi sẽ dựa vào mô tả của bạn để cung cấp mã VBA chính xác và giải thích rõ ràng.
Phân tích yêu cầu
Dữ liệu đầu vào:
Dãy số nằm ở hàng 4, từ cột A đến AZ (cột 1 đến 52 trong Excel).
Cột lẻ (1, 3, 5, ..., 51) chứa số lẻ.
Cột chẵn (2, 4, 6, ..., 52) chứa số chẵn.
Mỗi cấp (1, 2, 3) được tính toán dựa trên các quy tắc xu hướng.
Quy tắc xu hướng:
Cho cột hiện tại i (với i từ 3 trở đi, vì cần tham chiếu đến valPrev và valTruocPrev):
valNow = sh.Cells(4, i).Value: Giá trị tại cột hiện tại.
valPrev = sh.Cells(4, i-1).Value: Giá trị tại cột trước đó.
valTruocPrev = sh.Cells(4, i-2).Value: Giá trị tại cột trước đó nữa.
Cấp 1: Phân tích xu hướng trực tiếp từ dãy số ở A4:AZ4, ghi kết quả vào A6:AZ6.
Cấp 2: Phân tích xu hướng của dãy xu hướng cấp 1 (A6:AZ6), ghi kết quả vào A8:AZ8.
Cấp 3: Phân tích xu hướng của dãy xu hướng cấp 2 (A8:AZ8), ghi kết quả vào A10:AZ10.
Giá trị xu hướng được mã hóa thành số:
"OD" → 0
"HL" → 1
"T", "2T", "3T" báo hiệu thay đổi đường đi, nhưng không rõ cách xác định → giả sử chúng là các giá trị đặc biệt được xác định từ dữ liệu.
Vấn đề của bạn:
Mã VBA hiện tại của bạn (trong file) không chạy đúng yêu cầu.
Bạn cần mã hóa xu hướng thành số và ghi vào các ô tương ứng.
Giả định:
Vì không có thông tin cụ thể về "T", "2T", "3T", tôi giả định rằng các giá trị này xuất hiện khi một chuỗi xu hướng (ví dụ: liên tục "OD" hoặc "HL") đạt đến một ngưỡng nào đó, hoặc chúng được xác định bởi một quy tắc bổ sung. Nếu bạn có quy tắc cụ thể cho "T", "2T", "3T", hãy cung cấp thêm để tôi điều chỉnh mã.
Tôi sẽ mã hóa "OD" = 0, "HL" = 1, và giả sử "T", "2T", "3T" sẽ được xử lý nếu có quy tắc rõ ràng. Nếu không, mã sẽ tập trung vào "OD" và "HL" trước.
Mã VBA đề xuất
Dưới đây là mã VBA để giải quyết yêu cầu của bạn. Mã này:
Tính xu hướng cấp 1 dựa trên A4:AZ4 và ghi vào A6:AZ6.
Tính xu hướng cấp 2 dựa trên A6:AZ6 và ghi vào A8:AZ8.
Tính xu hướng cấp 3 dựa trên A8:AZ8 và ghi vào A10:AZ10.
Mã hóa "OD" = 0, "HL" = 1.
vba
Mã:
Sub XuHuongCap123()
Dim sh As Worksheet
Dim i As Long
Dim valNow As Double, valPrev As Double, valTruocPrev As Double
Dim xuHuong As String
Dim lastCol As Long
' Thiết lập worksheet
Set sh = ThisWorkbook.Sheets("Sheet1") ' Thay "Sheet1" bằng tên sheet của bạn
' Xác định cột cuối (AZ = 52)
lastCol = 52 ' Từ cột A đến AZ
' Xóa dữ liệu cũ trong các ô kết quả
sh.Range("A6:AZ6").ClearContents
sh.Range("A8:AZ8").ClearContents
sh.Range("A10:AZ10").ClearContents
' Tính xu hướng cấp 1 (dựa trên A4:AZ4)
For i = 3 To lastCol
valNow = sh.Cells(4, i).Value
valPrev = sh.Cells(4, i - 1).Value
valTruocPrev = sh.Cells(4, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(6, i).Value = xuHuong
Next i
' Tính xu hướng cấp 2 (dựa trên A6:AZ6)
For i = 3 To lastCol
valNow = sh.Cells(6, i).Value
valPrev = sh.Cells(6, i - 1).Value
valTruocPrev = sh.Cells(6, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(8, i).Value = xuHuong
Next i
' Tính xu hướng cấp 3 (dựa trên A8:AZ8)
For i = 3 To lastCol
valNow = sh.Cells(8, i).Value
valPrev = sh.Cells(8, i - 1).Value
valTruocPrev = sh.Cells(8, i - 2).Value
If valNow = 1 Then
If valPrev = valTruocPrev Then
xuHuong = "0" ' OD
Else
xuHuong = "1" ' HL
End If
ElseIf valNow > 1 Then
If valNow - 1 = valPrev Then
xuHuong = "1" ' HL
Else
xuHuong = "0" ' OD
End If
End If
sh.Cells(10, i).Value = xuHuong
Next i
End Sub
Giải thích mã
Khởi tạo:
Đặt worksheet là "Sheet1" (bạn cần thay đổi nếu tên sheet khác).
Xác định cột cuối là 52 (tương ứng với AZ).
Xóa dữ liệu cũ trong các ô kết quả (A6:AZ6, A8:AZ8, A10:AZ10) để tránh chồng lấn.
Tính xu hướng cấp 1:
Duyệt từ cột 3 (C) đến cột 52 (AZ).
Lấy valNow, valPrev, valTruocPrev từ hàng 4.
Áp dụng 4 quy tắc để xác định xu hướng ("OD" = 0, "HL" = 1).
Ghi kết quả vào hàng 6.
Tính xu hướng cấp 2:
Tương tự, lấy dữ liệu từ hàng 6 (kết quả cấp 1).
Áp dụng cùng quy tắc để xác định xu hướng.
Ghi kết quả vào hàng 8.
Tính xu hướng cấp 3:
Lấy dữ liệu từ hàng 8 (kết quả cấp 2).
Áp dụng quy tắc và ghi kết quả vào hàng 10.
Mã hóa:
"OD" được mã hóa thành 0.
"HL" được mã hóa thành 1.
Về "T", "2T", "3T"
Bạn đề cập rằng "T", "2T", "3T" báo hiệu thay đổi đường đi, nhưng không cung cấp quy tắc cụ thể để xác định chúng.
Nếu chúng được xác định dựa trên một chuỗi "OD" hoặc "HL" liên tiếp (ví dụ: 3 lần "HL" liên tiếp → "T"), hãy cung cấp thêm chi tiết, tôi sẽ bổ sung logic để xử lý.
Hiện tại, mã trên chỉ xử lý "OD" và "HL" vì đây là các quy tắc rõ ràng bạn đã đưa ra.
Hướng dẫn chạy mã
Mở Excel, nhấn Alt + F11 để vào VBA Editor.
Thêm một Module mới (Insert > Module).
Sao chép và dán mã trên vào Module.
Thay đổi tên sheet (Sheet1) trong mã nếu cần.
Đảm bảo dữ liệu ở A4:AZ4 đã được nhập đúng (cột lẻ là số lẻ, cột chẵn là số chẵn).
Chạy macro (F5 hoặc từ menu Excel).
Nếu mã không chạy đúng
Kiểm tra dữ liệu đầu vào:
Đảm bảo A4:AZ4 chứa số hợp lệ (cột lẻ: số lẻ, cột chẵn: số chẵn).
Kiểm tra xem có ô trống hoặc giá trị không phải số trong A4:AZ4 không.
Kiểm tra lỗi:
Nếu mã báo lỗi, hãy cho tôi biết thông báo lỗi cụ thể để tôi sửa.
Cung cấp thêm thông tin:
Nếu có quy tắc cụ thể cho "T", "2T", "3T", hãy mô tả chi tiết.
Nếu bạn có mã cũ (mã bạn nói "không chạy đúng"), hãy chia sẻ để tôi so sánh và tìm lỗi.
Lưu ý
Mã hiện tại giả định dữ liệu ở A4:AZ4 là số. Nếu dữ liệu là văn bản hoặc có định dạng đặc biệt, cần điều chỉnh thêm.
Nếu bạn muốn kết quả hiển thị "OD"/"HL" thay vì 0/1, chỉ cần thay xuHuong = "0" thành xuHuong = "OD" và xuHuong = "1" thành xuHuong = "HL" trong mã.
Nếu cần thêm logic cho "T", "2T", "3T", hãy cung cấp quy tắc để tôi cập nhật mã.
Hãy chạy thử mã trên và cho tôi biết kết quả hoặc bất kỳ lỗi nào bạn gặp. Nếu bạn có thêm chi tiết về file hoặc quy tắc "T", "2T", "3T", tôi sẽ tinh chỉnh mã cho phù hợp. Cảm ơn bạn đã tin tưởng, hy vọng mã này giúp bạn giải quyết vấn đề!
Dãy số nằm ở hàng 4, từ cột A đến AZ (cột 1 đến 52 trong Excel).
Cột lẻ (1, 3, 5, ..., 51) chứa số cùng phần tử B.
Cột chẵn (2, 4, 6, ..., 52) chứa số cùng phần tử P.
Mỗi cấp (1, 2, 3) được so sánh với cột 1,2,3 trước đó, giả sử dãy dữ liệu ( A4:F4 lần lượt 2,3,5,5,1,1) tại vị trí hiện tại cột D4 =5 có 5 phần tử so sánh với cột 1 (C4=5=valPrev) sẽ có 5 xu hướng cấp 1; tương tự cấp 2 (B4=3) sẽ có 5 xu hướng cấp 2 và cấp 3 (A4=2) sẽ có 5 xu hướng cấp 3
Quy tắc xu hướng:
Cho cột hiện tại i (với i = 2 và valNow > 1 đã có xu hướng, tham chiếu quy tắc 3,4 chỉ cần xét đến cột trước valPrev và valNow - 1 =1 giá trị nguyên dương hợp lệ):
valNow = sh.Cells(4, i).Value: Giá trị tại cột hiện tại.
valPrev = sh.Cells(4, i-1).Value: Giá trị tại cột trước đó.
valTruocPrev = sh.Cells(4, i-2).Value: Giá trị tại cột trước đó nữa.
Cấp 1: Phân tích xu hướng so với cột thứ 1 trước đó trực tiếp từ dãy số ở A4:AZ4, ghi kết quả vào A6:AZ6.
Cấp 2: Phân tích xu hướng so với cột thứ 2 trước đó từ dãy số ở A4:AZ4, ghi kết quả vào A8:AZ8
Cấp 3: Phân tích xu hướng so với cột thứ 3 trước đó từ dãy số ở A4:AZ4, ghi kết quả vào A10:AZ10.
Giá trị xu hướng được mã hóa thành số:
"OD" → 1 và được cộng dồn khi xu hướng cùng loại OD liên tiếp xuất hiện ( ví dụ: dãy A4=6, B4=7 ta xác định xu hướng cấp 1 tại cột B4 ( có 7 phần tử nhưng phần tử B4=1 không có valTruocPrev nên không có xu hướng) là OD, OD, OD, OD, OD, HL ghi kết quả vào cột lẽ là cột A6 = 5 cột B6=1
"HL" → 1 và được cộng dồn khi xu hướng cùng loại HL liên tiếp xuất hiện
xu hướng OD được ghi vào cột lẽ và HL ghi vào cột chẵn
"T", "2T", "3T" báo hiệu ngắt mảng xu hướng hiện tại và tiếp tục chuỗi xu hướng mới với cột bắt đầu là cột kề tiếp theo. Nếu cột tiếp theo sau T là khác loại chẵn/lẽ - xu hướng sẽ chuỗi mới xác định bình thường theo quy tắc xu hướng; Nếu cột tiếp theo sau T là cùng loại chẵn/lẽ thì sẽ được cộng dồn vào cột trước T và tiếp tục xác định hướng. Giả sử dãy dữ liệu nhập A4:E4 theo bảng khi T xuất hiện nhưng phần tử chẵn (P) vẫn xuất hiện nên dữ liệu ghi vào cột chẵn (D) và xu hướng khi T xuất hiện sẽ được cộng 2+1=3 và xác định tiếp chuổi xu hướng mới với 2 phần tử D nhưng được gộp vào B và vẫn tính xu hướng cấp 1 so với A theo quy tắc
A
B
C
D
E
3
1
2
3
T
mã VBA đinh kèm sau
vấn đề :
với 4 quy tắc khi dùng hàm for ..... IF .... thì không đồng bộ nhau ( ví dụ khi điều chỉnh các điều kiện của Quy tắc 1,2 thì mã chạy sai quy tắc 3,4 và ngược lại - Mong Thầy giúp - Thanks
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("A4:AZ4")) Is Nothing Then
Application.EnableEvents = False
XacDinhXuHuongCap1
Application.EnableEvents = True
End If
End Sub
Function XuHuongCap1(valNow As Long, valPrev As Variant, valTruocPrev As Variant) As String
If valNow = 1 Then
If valPrev = valTruocPrev Then
XuHuongCap1 = "L" ' on dinh
Else
XuHuongCap1 = "C" ' Hon loan
End If
Else
If valNow - 1 = valPrev Then
XuHuongCap1 = "C"
Else
XuHuongCap1 = "L"
End If
End If
End Function
Sub XacDinhXuHuongCap1()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets(1)
Dim i As Long, valNow As Long
Dim valPrev As Variant, valTruocPrev As Variant
Dim xuHuong As String
Dim danhSachXuHuong() As String
Dim xuHuongTruoc As String
Dim dem As Long
Dim ketQua() As Long
Dim k As Long: k = 1
Dim lastCol As Long: lastCol = 52 ' AZ
ReDim danhSachXuHuong(1 To 100)
For i = 2 To lastCol
Dim soPhanTu As Long
soPhanTu = sh.Cells(4, i).Value
If soPhanTu < 1 Then GoTo NextCol
For valNow = 1 To soPhanTu
If valNow = 1 Then
If i < 3 Then GoTo NextVal ' Không ?? d? li?u
valPrev = sh.Cells(4, i - 1).Value
valTruocPrev = sh.Cells(4, i - 2).Value
If valPrev = valTruocPrev Then
xuHuong = "OD"
Else
xuHuong = "HL"
End If
Else
If i < 2 Then GoTo NextVal ' Không ?? d? li?u
valPrev = sh.Cells(4, i - 1).Value
If (valNow - 1) = valPrev Then
xuHuong = "HL"
Else
xuHuong = "OD"
End If
End If
danhSachXuHuong(k) = xuHuong
k = k + 1
NextVal:
Next valNow
NextCol:
Next i
ReDim ketQua(1 To 500)
Dim ketQuaIndex As Long: ketQuaIndex = 1
If k = 1 Then Exit Sub
xuHuongTruoc = danhSachXuHuong(1)
dem = 1
For i = 2 To k - 1
If danhSachXuHuong(i) = xuHuongTruoc Then
dem = dem + 1
Else
ketQua(ketQuaIndex) = dem
ketQuaIndex = ketQuaIndex + 1
xuHuongTruoc = danhSachXuHuong(i)
dem = 1
End If
Next i
ketQua(ketQuaIndex) = dem
sh.Range("A6:AZ6").ClearContents
For i = 1 To ketQuaIndex
sh.Cells(6, i).Value = ketQua(i)
Next i