xác định xu hướng (1 người xem)

Liên hệ QC

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

Tôi tuân thủ nội quy khi đăng bài

vuthienfx

Thành viên mới
Tham gia
9/2/17
Bài viết
3
Được thích
0
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

31 2324221213183 312151 124
xu hướng cấp 1
xu hướng cấp 2
xu hướng cấp 3
[td]T[/td][td]T[/td][td]2T[/td][td]T[/td]
 

File đính kèm

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​


  1. 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.
  2. 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.
    • Áp dụng quy tắc:
      1. Nếu valNow = 1 và valPrev = valTruocPrev → Xu hướng "OD" (ổn định).
      2. Nếu valNow = 1 và valPrev ≠ valTruocPrev → Xu hướng "HL" (hỗn loạn).
      3. Nếu valNow > 1 và valNow - 1 = valPrev → Xu hướng "HL" (hỗn loạn).
      4. Nếu valNow > 1 và valNow - 1 ≠ valPrev → Xu hướng "OD" (ổn định).
  3. Cấp 1, 2, 3:
    • 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.
  4. 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.
  5. 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ã​


  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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ã​


  1. Mở Excel, nhấn Alt + F11 để vào VBA Editor.
  2. Thêm một Module mới (Insert > Module).
  3. Sao chép và dán mã trên vào Module.
  4. Thay đổi tên sheet (Sheet1) trong mã nếu cần.
  5. Đả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).
  6. 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 đề!
 
Upvote 0
  1. 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ố 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
  2. 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.
    • Áp dụng quy tắc:
      1. Nếu valNow = 1 và valPrev = valTruocPrev → Xu hướng "OD" (ổn định).
      2. Nếu valNow = 1 và valPrev ≠ valTruocPrev → Xu hướng "HL" (hỗn loạn).
      3. Nếu valNow > 1 và valNow - 1 = valPrev → Xu hướng "HL" (hỗn loạn).
      4. Nếu valNow > 1 và valNow - 1 ≠ valPrev → Xu hướng "OD" (ổn định).
  3. Cấp 1, 2, 3:
    • 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
ABCDE
3123
T


  • mã VBA đinh kèm sau
  1. 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

      End Sub
 
Upvote 0

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

Back
Top Bottom