Hỏi về sự kiện di chuyển chuột tạo hiệu ứng trong Excel? (1 người xem)

  • Thread starter Thread starter KUMI
  • Ngày gửi Ngày gửi
Liên hệ QC

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

KUMI

Bụi phấn
Tham gia
17/1/12
Bài viết
564
Được thích
571
Xin chào Thầy Cô và Anh Chị trong GPE!
Mọi người xem trường hợp dưới đây của Em có thể thực hiện được không ạ?

Ví dụ trong vùng A3:K10 trong sheet1 Em tô màu vàng và em muốn làm sao khi em di chuyển con chuột trong vùng này đến ô nào thì ô đó đổi chuyển sang màu xanh lá cây tại ô mà con chuột chỉ đến được không ạ! (Ô này không phải là em kích chuột vào đâu ạ, mà chỉ là chỉ con chuột vào thôi ạ).

Xin hỏi cách trên có thể thục hiện được không ạ?
Thầy Cô và Anh Chị giúp em với ạ!
Xin cảm ơn!
 
Xin chào Thầy Cô và Anh Chị trong GPE!
Mọi người xem trường hợp dưới đây của Em có thể thực hiện được không ạ?

Ví dụ trong vùng A3:K10 trong sheet1 Em tô màu vàng và em muốn làm sao khi em di chuyển con chuột trong vùng này đến ô nào thì ô đó đổi chuyển sang màu xanh lá cây tại ô mà con chuột chỉ đến được không ạ! (Ô này không phải là em kích chuột vào đâu ạ, mà chỉ là chỉ con chuột vào thôi ạ).

Xin hỏi cách trên có thể thục hiện được không ạ?
Thầy Cô và Anh Chị giúp em với ạ!
Xin cảm ơn!


Đặt trong module sheet mà bạn cần tạo "hiệu ứng" những thủ tục dưới đây, nhưng lưu ý, nếu trong vùng mà bạn muốn thay đổi mà có màu thì bạn cứ làm màu cho vùng đó trước, sau đó mới chép code vào module sheet bạn nhé, vì nó sẽ không cho bạn thay đổi màu nền nữa đâu!

Mã:
Private OldTarget As Range, Color As Long, isColor As Boolean


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    On Error Resume Next

    'Thu tuc khi ban roi khoi cell da chon thi tra ve mau sac cua cell do:
    If isColor Then
        OldTarget.Interior.Color = Color
    Else
        OldTarget.Interior.Pattern = xlNone
    End If

    'Thu tuc nhan gia tri cua cell vua chon, dong thoi chuyen mau cell do:
    If Not Intersect(Range("A3:K10"), Target) Is Nothing Then
                 
        If Target.Interior.Pattern = xlNone Then
            isColor = False
        Else
            isColor = True
            Color = Target.Interior.Color
        End If
    
        Target.Interior.Color = 65280
        Set OldTarget = Target
    End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Đúng là cao thủ! Cảm ơn anh Nghĩa nhiều lắm ạ!
 
Upvote 0
Đúng là cao thủ! Cảm ơn anh Nghĩa nhiều lắm ạ!

Nhưng thật tâm mà nói thì mình chả thích cái vụ này tí nào cả, nó không giải quyết triệt để những gì mình mong muốn, chẳng hạn chọn vùng nhiều ô có nhiều màu khác nhau, thì khi trả về chúng nó biến thành màu đen thui luôn! Nó chỉ có thể chọn 1 ô thì mới hiệu quả; chọn màu trong vùng đó nó cũng chẳng cho, nếu đặt thủ tục cho phép thì thoát ra nó không trả lại vùng màu... Vì không giải quyết được triệt để nên tôi không khuyến khích cái kiểu màu mè rắc rối này vì nó chẳng giúp ích gì được nhiều vì khi ta chọn vào vùng nào bản thân vùng đó nó cũng được boder rất đậm để ta biết vùng được chọn.
 
Upvote 0
Đặt trong module sheet mà bạn cần tạo "hiệu ứng" những thủ tục dưới đây, nhưng lưu ý, nếu trong vùng mà bạn muốn thay đổi mà có màu thì bạn cứ làm màu cho vùng đó trước, sau đó mới chép code vào module sheet bạn nhé, vì nó sẽ không cho bạn thay đổi màu nền nữa đâu!

Mã:
Private OldTarget As Range, Color As Long, isColor As Boolean


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    On Error Resume Next

    'Thu tuc khi ban roi khoi cell da chon thi tra ve mau sac cua cell do:
    If isColor Then
        OldTarget.Interior.Color = Color
    Else
        OldTarget.Interior.Pattern = xlNone
    End If

    'Thu tuc nhan gia tri cua cell vua chon, dong thoi chuyen mau cell do:
    If Not Intersect(Range("A3:K10"), Target) Is Nothing Then
                 
        If Target.Interior.Pattern = xlNone Then
            isColor = False
        Else
            isColor = True
            Color = Target.Interior.Color
        End If
    
        Target.Interior.Color = 65280
        Set OldTarget = Target
    End If
End Sub
Xem lại yêu cầu này nhé:
Xin chào Thầy Cô và Anh Chị trong GPE!
Mọi người xem trường hợp dưới đây của Em có thể thực hiện được không ạ?

Ví dụ trong vùng A3:K10 trong sheet1 Em tô màu vàng và em muốn làm sao khi em di chuyển con chuột trong vùng này đến ô nào thì ô đó đổi chuyển sang màu xanh lá cây tại ô mà con chuột chỉ đến được không ạ! (Ô này không phải là em kích chuột vào đâu ạ, mà chỉ là chỉ con chuột vào thôi ạ).

Xin hỏi cách trên có thể thục hiện được không ạ?
Thầy Cô và Anh Chị giúp em với ạ!
Xin cảm ơn!
Chổ màu đỏ ấy!
 
Upvote 0
Xem lại yêu cầu này nhé:

Chổ màu đỏ ấy!

Nếu là sự kiện rê chuột (Mouse Move) thì xin thưa với mọi người là trong sự kiện của Sheet hoàn toàn không có, nhưng tác giả nói "không kích vào" được hiểu là không chọn vào chế độ sửa trong ô, còn "chỉ con chuột vào" thì rõ ràng được hiểu là chọn vào một ô bất kỳ nào đó rồi còn gì?
 
Upvote 0
Nếu là sự kiện rê chuột (Mouse Move) thì xin thưa với mọi người là trong sự kiện của Sheet hoàn toàn không có, nhưng tác giả nói "không kích vào" được hiểu là không chọn vào chế độ sửa trong ô, còn "chỉ con chuột vào" thì rõ ràng được hiểu là chọn vào một ô bất kỳ nào đó rồi còn gì?
Không có sự kiện đó cũng không có nghĩa là không làm được
Ta có API SetTimer, KillTimer để làm gì
----------------------
Dám cá với Nghĩa là tác giả muốn nói Mouse Move đấy (chứ SelectionChange thì nói làm quái gì cho mệt ---> Ai cũng quá biết rồi)
 
Upvote 0
Xin chào Thầy Cô và Anh Chị trong GPE!
Mọi người xem trường hợp dưới đây của Em có thể thực hiện được không ạ?

Ví dụ trong vùng A3:K10 trong sheet1 Em tô màu vàng và em muốn làm sao khi em di chuyển con chuột trong vùng này đến ô nào thì ô đó đổi chuyển sang màu xanh lá cây tại ô mà con chuột chỉ đến được không ạ! (Ô này không phải là em kích chuột vào đâu ạ, mà chỉ là chỉ con chuột vào thôi ạ).

Xin hỏi cách trên có thể thục hiện được không ạ?
Thầy Cô và Anh Chị giúp em với ạ!
Xin cảm ơn!
Thấy các thày có ý kiến rồi, mình không dám tham gia . bạn xem file đính kèm xem đúng ý bạn không ? không trúng chắc là trật lấc rồi .
 

File đính kèm

Upvote 0
Không có sự kiện đó cũng không có nghĩa là không làm được
Ta có API SetTimer, KillTimer để làm gì
----------------------
Dám cá với Nghĩa là tác giả muốn nói Mouse Move đấy (chứ SelectionChange thì nói làm quái gì cho mệt ---> Ai cũng quá biết rồi)

Đúng rồi ạ!Mong muốn của con,Thầy diễn tả như vậy là rất chĩnh xác.
Có thể do con chưa diễn tả cụ thể hơn nên khiến Anh Nghĩa và một số người đọc hiểu lầm sang dạng selectionChange.
Thực chất bài này con chỉ mang tính chất hỏi thêm thôi. Chứ nó cũng không cần thiết gì cho công việc.
Sở dĩ hỏi như vậy là vì con thấy trên trang web có những hiệu ứng chỉ chuột vào các chỗ có đường links thì nó có rất nhiều kiểu hiệu ứng.
Vì vậy con mới nghĩ đến Excel có thể làm được như vậy không? Biết đâu thấy hay ta có thể áp dụng được cho công việc liên quan đến Excel.
Theo tư duy của Thầy thì bài này cũng có thể thực hiện được nên con cũng hi vọng rằng chủ đề này vẫn còn được tiếp tục để có kết quả ưng ý. Hì hì... Thầy cũng đừng cố gằng quá nhé.
Bài này con cũng chỉ mang tính chất là hỏi chơi thôi ạ! Chứ không muốn ai phải mệt mỏi vì nó! ^^
 
Upvote 0
Theo tư duy của Thầy thì bài này cũng có thể thực hiện được nên con cũng hi vọng rằng chủ đề này vẫn còn được tiếp tục để có kết quả ưng ý. Hì hì... Thầy cũng đừng cố gằng quá nhé.
Bài này con cũng chỉ mang tính chất là hỏi chơi thôi ạ! Chứ không muốn ai phải mệt mỏi vì nó!
^^

Bạn đừng khéo "lo bò trắng răng", một khi Thầy đã nói như thế thì 100% Thầy đang nắm trong tay cái đó, nếu bạn đã nói như Thầy nói thì trong phút chốc Thầy sẽ gửi lên mà thôi; học Thầy riết rồi tôi có nhiều kinh nghiệm về điều đó!
 
Upvote 0
Bạn đừng khéo "lo bò trắng răng", một khi Thầy đã nói như thế thì 100% Thầy đang nắm trong tay cái đó, nếu bạn đã nói như Thầy nói thì trong phút chốc Thầy sẽ gửi lên mà thôi; học Thầy riết rồi tôi có nhiều kinh nghiệm về điều đó!
Hi, Cảm ơn Anh Nghĩa nhiều nhiều ạ! Bài #2 của Anh Em thấy rất hữu ích đấy ạ!Vì nó có thể áp dụng được cho công việc của mình! Cảm ơn Anh.
 
Upvote 0
Thấy các thày có ý kiến rồi, mình không dám tham gia . bạn xem file đính kèm xem đúng ý bạn không ? không trúng chắc là trật lấc rồi .

Cảm ơn bạn nhé! Đó là kiểu bài kiểu bài HighLight mà.
Với bài HighLight này gần đây mình cũng đã áp dụng vào công việc của mình rồi.Đúng là rất tuyệt!
Nhưng mình vẫn thấy thích code của Thầy NDU hơn. Vì code của Thầy mình không thấy bị nhấp nháy trong quá trình thao tác và nhập liệu. Còn code của bạn thì nhấp nháy. (Vấn đề nhấp nháy khiến mắt nhanh mỏi hơn).
Bạn xem file kèm này của Thầy NDU nhé!
-----------
Với bài HighLight này mình cũng thấy Thầy Nguyễn Duy Tuân cũng đã làm một chương trình và đóng gói thành phần mềm cài cũng rất hay đó, nếu bạn chưa biết thì thử tìm xem.
Với mình chỉ thích sử dụng kiểu file mềm mà có thể học hỏi và có thể tùy biến tự do sửa đổi theo sở thích của mình hơn. Nếu xảy ra lỗi mình cũng còn phát hiện lỗi ở đâu để tìm cách khắc phục.
Chứ phần mềm thì sử dụng cũng hay và tiện đấy. Nhưng bên trong có những cái gì ta cũng không thể biết được nếu muốn học cũng khómà hỏi thì cũng thấy ngài ngại. Hì!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn bạn nhé! Đó là kiểu bài kiểu bài HighLight mà.
Với bài HighLight này gần đây mình cũng đã áp dụng vào công việc của mình rồi.Đúng là rất tuyệt!
Nhưng mình vẫn thấy thích code của Thầy NDU hơn. Vì code của Thầy mình không thấy bị nhấp nháy trong quá trình thao tác và nhập liệu. Còn code của bạn thì nhấp nháy. (Vấn đề nhấp nháy khiến mắt nhanh mỏi hơn).
Bạn xem file kèm này của Thầy NDU nhé!
-----------
Với bài HighLight này mình cũng thấy Thầy Nguyễn Duy Tuân cũng đã làm một chương trình và đóng gói thành phần mềm cài cũng rất hay đó, nếu bạn chưa biết thì thử tìm xem.
Với mình chỉ thích sử dụng kiểu file mềm mà có thể học hỏi và có thể tùy biến tự do sửa đổi theo sở thích của mình hơn. Nếu xảy ra lỗi mình cũng còn phát hiện lỗi ở đâu để tìm cách khắc phục.
Chứ phần mềm thì sử dụng cũng hay và tiện đấy. Nhưng bên trong có những cái gì ta cũng không thể biết được nếu muốn học cũng khómà hỏi thì cũng thấy ngài ngại. Hì!

Tạm thời bạn thử xem file này, chờ các cao thủ có giải pháp, tuy nhiên tôi thấy không ổn tí nào cho cái này vì khó xác định chính xác cell nào mình đang rê tới. Tôi có thể giúp bạn tới đây. Bó tay rồi đó!

1) Trong Standard Module:

Mã:
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long


Public Type POINTAPI
    x As Long
    y As Long
End Type


Private Type Coordinates
    lngLeft As Long
    lngRight As Long
    lngTop As Long
    lngBottom As Long
    rngCell As Range
End Type


Public lngCurPos As POINTAPI, Cancel As Boolean




Sub ChangeCellColor()
    Dim r As Range, coorCells() As Coordinates, l As Long, c As Range
    
    Set r = Sheet1.Range("A3:K10")
    
    ReDim coorCells(r.Count)
    
    Cancel = False
    
    For l = 1 To r.Count
        Set c = r.Cells(l)
        With ActiveWindow
            coorCells(l).lngLeft = .PointsToScreenPixelsX(c.Left)
            coorCells(l).lngRight = .PointsToScreenPixelsX(c.Offset(, 1).Left)
            coorCells(l).lngTop = .PointsToScreenPixelsY(c.Top)
            coorCells(l).lngBottom = .PointsToScreenPixelsY(c.Offset(1).Top)
        End With
        Set coorCells(l).rngCell = c
    Next
    
    Do
        For l = 1 To r.Count
            GetCursorPos lngCurPos
            If lngCurPos.x > coorCells(l).lngLeft And lngCurPos.x < coorCells(l).lngRight _
                And lngCurPos.y > coorCells(l).lngTop And lngCurPos.y < coorCells(l).lngBottom Then
                    coorCells(l).rngCell.Interior.Color = 65280 'vbYellow
                Else
                    coorCells(l).rngCell.Interior.ColorIndex = 0
                End If
            
            DoEvents
        Next
    Loop Until Cancel = True


End Sub


Sub CancelProcedure()
    Cancel = True
End Sub

2) Trong Sheet Module:

Kích hoạt khi chọn vào sheet, và thoát code khi chọn sheet khác:

Mã:
Private Sub Worksheet_Activate()
    ChangeCellColor
End Sub


Private Sub Worksheet_Deactivate()
    CancelProcedure
End Sub
 

File đính kèm

Upvote 0
Tạm thời bạn thử xem file này, chờ các cao thủ có giải pháp, tuy nhiên tôi thấy không ổn tí nào cho cái này vì khó xác định chính xác cell nào mình đang rê tới. Tôi có thể giúp bạn tới đây. Bó tay rồi đó!

Không biết có chỗ nào thừa chỗ nào thiếu không nhưng cứ thử xem sao

code Module1
Mã:
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

Private Type POINTAPI
    x As Long
    y As Long
End Type

Private lastCell As Range, currCell As Range, Cancel As Boolean

Sub ChangeCellColor()
Dim pt As POINTAPI
    Cancel = False
    
    Do
        GetCursorPos pt
        Set currCell = ActiveWindow.RangeFromPoint(pt.x, pt.y)
        If Not currCell Is Nothing Then
            If Not Intersect(currCell, Sheet1.Range("A3:K10")) Is Nothing Then
                If lastCell Is Nothing Then
                    currCell.Interior.Color = RGB(0, 0, 255)
                    Set lastCell = currCell
                Else
                    If currCell.Address <> lastCell.Address Then
                        lastCell.Interior.ColorIndex = 0
                        currCell.Interior.Color = RGB(0, 0, 255)
                        Set lastCell = currCell
                    End If
                End If
            Else
                If Not lastCell Is Nothing Then
                    lastCell.Interior.ColorIndex = 0
                    Set lastCell = Nothing
                End If
            End If
        End If
            
        DoEvents
    Loop Until Cancel = True
End Sub

Sub CancelProcedure()
    Cancel = True
End Sub
 
Upvote 0
Bạn đừng khéo "lo bò trắng răng", một khi Thầy đã nói như thế thì 100% Thầy đang nắm trong tay cái đó, nếu bạn đã nói như Thầy nói thì trong phút chốc Thầy sẽ gửi lên mà thôi; học Thầy riết rồi tôi có nhiều kinh nghiệm về điều đó!

1> Code trong Module (tên: modTimer)
Mã:
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Public Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long

Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Private Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Type POINTAPI
  X As Long
  Y As Long
End Type
Dim bChk As Boolean
Public curCell As Range
Public curColorIndex As Integer

Private Const GWL_HWNDPARENT As Long = (-8)
Public Const ActiveColor = 24
Public Sub TimerProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal oTimer As clsTimer, ByVal dwTime As Long)
  oTimer.RaiseTimer
End Sub
Public Function hWndMain() As Long
  Call EnumThreadWindows(GetCurrentThreadId(), AddressOf EnumThreadWndProc, VarPtr(hWndMain))
End Function
Private Function EnumThreadWndProc(ByVal hWnd As Long, ByVal lpResult As Long) As Long
  If bChk = False Then
    If GetWindowLong(hWnd, GWL_HWNDPARENT) Then
      EnumThreadWndProc = True
    Else
      Call CopyMemory(ByVal lpResult, hWnd, 4)
      EnumThreadWndProc = False
    End If
  ElseIf bChk = True Then
    Dim WindowText As String
    EnumThreadWndProc = True
    If GetWindowLong(hWnd, GWL_HWNDPARENT) = 0 Then
      WindowText = Space$(512)
      If GetWindowText(hWnd, WindowText, Len(WindowText)) Then
        If InStr(WindowText, Application.Name) Then
          Call CopyMemory(ByVal lpResult, hWnd, 4&)
          EnumThreadWndProc = False
        End If
      End If
    End If
  End If
End Function
2> Code trong Module (tên modMain)
Mã:
Dim m_Event As New clsControl
Sub Event_Start()
  m_Event.Timer_Start
End Sub
Sub Event_Stop()
  m_Event.Timer_Stop
End Sub
3> Code trong Class Module (tên clsTimer)
Mã:
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long

Private m_TmrID As Long
Private m_hWnd As Long
Private m_Enabled As Boolean
Private m_Interval As Long

Private Const defEnabled As Boolean = False
Private Const defInterval As Long = 0

Public Event Timer()
Private Sub Class_Initialize()
  m_Enabled = defEnabled
  m_Interval = defInterval
  m_hWnd = hWndMain()
End Sub
Private Sub Class_Terminate()
  Call KillTimer(m_hWnd, m_TmrID)
End Sub
Public Property Get Enabled() As Boolean
  Enabled = m_Enabled
End Property
Public Property Let Enabled(ByVal NewEnabled As Boolean)
  If m_Enabled Then
    Call KillTimer(m_hWnd, m_TmrID)
    m_TmrID = 0
  End If
  m_Enabled = NewEnabled
  If m_Interval > 0 Then
    If m_Enabled Then
      m_TmrID = SetTimer(m_hWnd, ObjPtr(Me), m_Interval, AddressOf TimerProc)
    End If
  End If
End Property
Public Property Get Interval() As Long
  Interval = m_Interval
End Property
Public Property Let Interval(ByVal NewInterval As Long)
  If NewInterval >= 0 Then
    m_Interval = NewInterval
    Me.Enabled = m_Enabled
  End If
End Property
Public Sub RaiseTimer()
  RaiseEvent Timer
End Sub
4> Code trong class Module (tên clsControl)
Mã:
Dim WithEvents tmr As clsTimer
Private CursorPos As POINTAPI
Private CursorCell As Range
Public Sub Timer_Start()
  Set tmr = New clsTimer
  tmr.Interval = 100
  tmr.Enabled = True
End Sub
Public Sub Timer_Stop()
  Set tmr = Nothing
End Sub
Private Sub tmr_Timer()
  Dim RetVal As Long
  Dim rng As Range
  RetVal = GetCursorPos(CursorPos)
  RetVal = WindowFromPoint(CursorPos.X, CursorPos.Y)
  On Error Resume Next
  Set CursorCell = Application.Windows(1).RangeFromPoint(CursorPos.X, CursorPos.Y)
  If Err.Number = 0 Then
    If CursorCell.Address <> curCell.Address Then
      curCell.Interior.ColorIndex = curColorIndex
      Set curCell = CursorCell
      curColorIndex = curCell.Interior.ColorIndex
      curCell.Interior.ColorIndex = ActiveColor
    End If
  End If
End Sub
Gọi Sub Event_Start để kịch hoạt và Event_Stop để tắt
(việc giới hạn vùng hoạt động, các bạn tự nghiên cứu nhé)
 

File đính kèm

Upvote 0

...

Gọi Sub Event_Start để kịch hoạt và Event_Stop để tắt
Hix! Nhìn code thật là khủng khiếp!
Con đã test thử bài của Thầy rất đúng với ý muốn của con.
Còn bài bài Anh Nghĩa và Thầy Siwtom trong quá trình di chuyển chuột con thấy bị mất màu nền cũ.

(việc giới hạn vùng hoạt động, các bạn tự nghiên cứu nhé)
Con cũng định hỏi thêm cái này nhưng Thầy nói vậy nên cứ từ từ xem sao vậy.
Cảm ơn 2 Thầy và Anh Nghĩa nhiều nhé! Cảm ơn GPE!
 
Upvote 0
Hix! Nhìn code thật là khủng khiếp!

Bởi vậy mới thấy rằng cái việc màu mè nó chả cần thiết tí nào. Tôi nghiên cứu chơi chơi thôi chứ nói thật là tôi chưa từng xài bao giờ
Excel là để tính toán. Kết quả đúng + nhanh mới là thứ ta cần. Màu mè có cũng tốt nhưng cũng nên tiết chế sao cho vừa phải... Đừng bao giờ viết 1 ứng dụng mà PHẦN CODE CHÍNH chỉ có 3 dòng còn PHẦN MÀU MÈ chiếm đến 4 trang giấy
 
Upvote 0
Hix! Nhìn code thật là khủng khiếp!
Con đã test thử bài của Thầy rất đúng với ý muốn của con.
Còn bài bài Anh Nghĩa và Thầy Siwtom trong quá trình di chuyển chuột con thấy bị mất màu nền cũ.

Con cũng định hỏi thêm cái này nhưng Thầy nói vậy nên cứ từ từ xem sao vậy.
Cảm ơn 2 Thầy và Anh Nghĩa nhiều nhé! Cảm ơn GPE!

Tôi lại tiếp tục cải tiến lại theo code của Thầy siwtom như sau:

Bổ sung lại phần màu cũ, đồng thời, nếu ô đã có màu giống với màu mà con trỏ rê vào, thì nó sẽ đổi sang màu khác, với code này thì nó xác định ô rất mượt mà; và ngắn gọn hơn của Thầy ndu96081631 (mặc dù với code của Thầy tôi sẽ không áp dụng vào bài của tôi, nhưng tính học thuật rất cao, xem để học thuật thì tuyệt vời).

Toàn bộ code chỉ trong 1 module:

Mã:
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long


Private Type POINTAPI
    x As Long
    y As Long
End Type


Private lastCell As Range, currCell As Range, _
        Cancel As Boolean, IsColor As Boolean, _
        Color As Long
        
Private Const CursorColor1 As Long = 65280
Private Const CursorColor2 As Long = 16761087


Sub ChangeCellColor()
    On Error Resume Next
    Dim pt As POINTAPI
    Cancel = False
    
    Do
        GetCursorPos pt
        Set currCell = ActiveWindow.RangeFromPoint(pt.x, pt.y)
        If Not currCell Is Nothing Then
            If Not Intersect(currCell, Sheet1.Range("A3:K10")) Is Nothing Then
                If lastCell Is Nothing Then
                    ''Dieu kien nay van giu duoc grid line khi _
                    ''gap cell khong co fill color:
                    If currCell.Interior.Pattern = xlNone Then
                        IsColor = False
                    Else
                        IsColor = True
                        Color = currCell.Interior.Color
                    End If
                    ''Neu cell cung mau voi su kien thi chuyen mau khac:
                    If currCell.Interior.Color = CursorColor1 Then
                        currCell.Interior.Color = CursorColor2
                    Else
                        currCell.Interior.Color = CursorColor1
                    End If
                    Set lastCell = currCell
                    
                Else
                    If currCell.Address <> lastCell.Address Then
                        ''Tra lai gia tri mau hoac khong co mau cho o truoc:
                        If IsColor Then
                            lastCell.Interior.Color = Color
                        Else
                            lastCell.Interior.Pattern = xlNone
                        End If
                        
                        If currCell.Interior.Pattern = xlNone Then
                            IsColor = False
                        Else
                            IsColor = True
                            Color = currCell.Interior.Color
                        End If
                        
                        If currCell.Interior.Color = CursorColor1 Then
                            currCell.Interior.Color = CursorColor2
                        Else
                            currCell.Interior.Color = CursorColor1
                        End If
                        Set lastCell = currCell
                    End If
                End If
            Else
                If Not lastCell Is Nothing Then
                    If IsColor Then
                        lastCell.Interior.Color = Color
                    Else
                        lastCell.Interior.Pattern = xlNone
                    End If
                    Set lastCell = Nothing
                End If
            End If
        End If
            
        DoEvents
    Loop Until Cancel = True
End Sub


Sub CancelProcedure()
    Cancel = True
End Sub

Và một thủ tục cho nút lệnh đặt tại Sheet Module:

Mã:
Private Sub CommandButton1_Click()
    If CommandButton1.Caption = "START CHANGE COLOR" Then
        CommandButton1.Caption = "STOP CHANGE COLOR"
        Range("A1").Select
        Call ChangeCellColor
    Else
        CommandButton1.Caption = "START CHANGE COLOR"
        Call CancelProcedure
    End If
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Tôi lại tiếp tục cải tiến lại theo code của Thầy siwtom như sau:

Bổ sung lại phần màu cũ, đồng thời, nếu ô đã có màu giống với màu mà con trỏ rê vào, thì nó sẽ đổi sang màu khác, với code này thì nó xác định ô rất mượt mà; và ngắn gọn hơn của Thầy ndu96081631

Đúng là ngắn hơn nhưng mà... khi code chạy, toàn bộ các button trên toolbar đều bị tê liệt, chẳng xài được gì
Ẹc... Ẹc...
 
Upvote 0
Đúng là ngắn hơn nhưng mà... khi code chạy, toàn bộ các button trên toolbar đều bị tê liệt, chẳng xài được gì
Ẹc... Ẹc...


Đúng là bấm trên nút lệnh để chạy code thì nó sẽ bị trường hợp "tê liệt", nhưng chạy code bằng sự kiện hay vào VBA bấm F5 thì không bị trường hợp này.

Nguyên do là khi ta bấm vào nút lệnh, code thực thi, trong quá trình focus trên nút lệnh (mặc dù em đã cho nó câu lệnh Range("A1").Select), nhưng nó vẫn giữ trạng thái ban đầu, như ta vẫn đang select trên nút lệnh mà không trả về trạng thái đang select trên Range nên mới bị tình trạng "đóng băng" toolbar như thế.

Để em tìm giải pháp cho trường hợp này xem. Nếu không thì mình dùng sự kiện hoặc chạy bằng tổ hợp phím thôi.
 
Upvote 0
Tìm ra giải pháp rồi! Cách nhanh nhất là chọn nút lệnh, chọn chế độ Design, chọn Properties, mục TakeFocusOnClick, chọn False là giải quyết được tình trạng "tê liệt" Toolbar!

Đúng như em "chẩn đoán bệnh"!

Và trong thủ tục của nút lệnh, không cần dòng này nữa:

Range("A1").Select
 
Upvote 0
Tìm ra giải pháp rồi! Cách nhanh nhất là chọn nút lệnh, chọn chế độ Design, chọn Properties, mục TakeFocusOnClick, chọn False là giải quyết được tình trạng "tê liệt" Toolbar!

Đúng như em "chẩn đoán bệnh"!

Và trong thủ tục của nút lệnh, không cần dòng này nữa:

Range("A1").Select

He he! Ngon rồi Anh Nghĩa ơi! Cảm ơn Anh nhiều nhé!
Em thấy2 Thầy Trò nói chuyện về tê liệt các nút lệnh mà em không hiểu gì cả. Mãi sau mới để ý có một số nút bị mờ đi. sau đó xử lý theo cách của Anh. Thấy ổn rồi ạ! Cảm ơn 2 Thầy trò nhà Anh nhé!hihi.
-----------
Nhân đây Có thể áp dụng Mouse move cho bài HighLight này của Thầy NDU được không Anh.
Em rất thích bài HighLight này nếu thay bằng Mouse move thì pro quá. hihi!
Thầy và Anh tìm cách giúp em với nhé!
Xin cảm ơn!
 

File đính kèm

Upvote 0
Nhân đây Có thể áp dụng Mouse move cho bài HighLight này của Thầy NDU được không Anh.
Em rất thích bài HighLight này nếu thay bằng Mouse move thì pro quá. hihi!
Thầy và Anh tìm cách giúp em với nhé!
Xin cảm ơn!

Bạn chưa hỏi thì tôi cũng đã nghĩ qua (mà chắc các đại ca khác cũng đã nghĩ qua)
Tuy nhiên, sẽ có chút khó khăn về mặc kỹ thuật:
- Highlight 1 cell duy nhất sẽ dễ trả lại màu gốc của những cell mà con trỏ đi qua (vì chỉ có 1 cell)
- Highlight nguyên dòng, nếu muốn trả lại màu gốc cho những cell đã bị Highlight trước đó mà dòng này lại có quá nhiều màu khác nhau thì thật là... tê ---> Để nhớ hết tất cả các giá trị màu của các cell, buộc phải dùng vòng lập rồi khi muốn trả lại màu gốc cũng phải dùng vòng lập (2 lần lập) ---> E rằng sẽ làm bảng tính chậm rì rì
--------------
Tuy nhiên, nếu phối hợp với Conditional Formating thì chắc là không có vấn đề
Các đại ca khác nghiên cứu xem
 
Upvote 0
Làm thử cái chơi xem sao
Toàn bộ code
Mã:
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Private Type POINTAPI
  x As Long
  y As Long
End Type
Dim rngCursor As Range, rngArea As Range
[COLOR=#ff0000][B]Const HL_COLOR = 40[/B][/COLOR] '<---- Màu Highlight
[COLOR=#ff0000][B]Const HL_TYPE = 3[/B][/COLOR]   '<---- Kieu Highlight
Private Sub Auto_Open()
  DelCBar
  With Application.CommandBars(1).Controls.Add(1, , , 1)
    .Caption = "Start Cells Mouse Move"
    .OnAction = "Event_Start"
    .FaceId = 156
  End With
End Sub
Private Sub Auto_Close()
  Event_Stop
  DelCBar
End Sub
Private Sub DelCBar()
  On Error Resume Next
  Dim cBar As CommandBarButton
  With Application.CommandBars(1)
    Set cBar = .Controls("Start Cells Mouse Move")
    If cBar Is Nothing Then Set cBar = .Controls("Stop Cells Mouse Move")
  End With
  If Not cBar Is Nothing Then cBar.Delete
End Sub
Function TimerProc(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
  Dim lPoint As POINTAPI
  On Error Resume Next
  GetCursorPos lPoint
  Set rngCursor = ActiveWindow.RangeFromPoint(lPoint.x, lPoint.y)
  If Not rngCursor Is Nothing Then
    Highlight rngArea, rngCursor, HL_COLOR, HL_TYPE
  End If
End Function
Private Sub Event_Start()
  On Error Resume Next
  If TypeOf Selection Is Range Then
    Set rngArea = Selection
    rngArea(1, 1).Select
    With Application.CommandBars(1).Controls("Start Cells Mouse Move")
      .Caption = "Stop Cells Mouse Move"
      .OnAction = "Event_Stop"
      .FaceId = 189
    End With
    SetTimer Application.hwnd, 1, 10, AddressOf TimerProc
  End If
End Sub
Private Sub Event_Stop()
  On Error Resume Next
  If Not rngArea Is Nothing Then
    rngArea.FormatConditions.Delete
    Set rngArea = Nothing
  End If
  With Application.CommandBars(1).Controls("Stop Cells Mouse Move")
    .Caption = "Start Cells Mouse Move"
    .OnAction = "Event_Start"
    .FaceId = 156
  End With
  KillTimer Application.hwnd, 1
End Sub
Private Sub Highlight(ByVal Area As Range, ByVal Target As Range, ByVal ColorIndex As Long, _
                     Optional ByVal Highlight_Type As Long = 1)
  Dim rngTmp As Range
  On Error Resume Next
  Area.FormatConditions.Delete
  If Not Intersect(Area, Target) Is Nothing Then
    With Area
      Select Case Highlight_Type
        Case 1:
          Set rngTmp = Intersect(.Cells, Target.EntireRow)
        Case 2:
          Set rngTmp = Intersect(.Cells, Target.EntireColumn)
        Case 3:
          Set rngTmp = Intersect(.Cells, Union(Target.EntireColumn, Target.EntireRow))
        Case 4:
          Set rngTmp = Intersect(Range(.Cells(1, 1), Target), Union(Target.EntireColumn, Target.EntireRow))
      End Select
    End With
    If Application.CutCopyMode = False Then
      rngTmp.FormatConditions.Add 2, , "TRUE"
      rngTmp.FormatConditions(1).Interior.ColorIndex = ColorIndex
    End If
  End If
End Sub
Cách dùng:
- Mở file lên, sẽ thấy 1 menu mới xuất hiện
- Quét chọn vùng dữ liệu (giới hạn HighLight) rồi bấm vào nút "Start Cells Mouse Move"
- Khi nào hết thích HighLight, lại bấm vào nút ấy lần nữa
Lưu ý: Chổ màu đỏ ở code trên là màu sắc và kiểu HighLight tùy bạn chọn (kiểu HighLight tùy chọn từ 1 đến 4)
--------------
Để tạo thành 1 ứng dụng thật sự (AddIn chẳng hạn) thì còn phải thêm chút "màu mè" nữa mới hoàn hảo
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Bạn chưa hỏi thì tôi cũng đã nghĩ qua (mà chắc các đại ca khác cũng đã nghĩ qua)
...
Các đại ca khác nghiên cứu xem

Vâng công nhận là HighLight cũng rất cần thiết đối với công việc nhất là bảng dữ liệu nhiều cột nhiều dòng và lại nhỏ li ti nữa ạ.

Làm thử cái chơi xem sao
...
Cách dùng:
- Mở file lên, sẽ thấy 1 menu mới xuất hiện
- Quét chọn vùng dữ liệu (giới hạn HighLight) rồi bấm vào nút "Start Cells Mouse Move"
- Khi nào hết thích HighLight, lại bấm vào nút ấy lần nữa

Chỗ nào là ở đâu vậy Thầy, con không nhìn thấy! Thầy chụp ảnh chỉ con với.


Để tạo thành 1 ứng dụng thật sự (AddIn chẳng hạn) thì còn phải thêm chút "màu mè" nữa mới hoàn hảo

Cái này con thấy rất hữu ích Thầy cố gắng nghiên cứu để nó hoàn hảo nhé hihi!
 
Upvote 0
À! con run code được rồi! Thầy nghiên cứu thêm xem có thể giải quyết được cái vụ khỏi nháy nháy đấy không ạ. ^^
Nháy kinh hơn cả đèn chớp trong vũ trường... :v
 
Upvote 0
Chỗ nào là ở đâu vậy Thầy, con không nhìn thấy! Thầy chụp ảnh chỉ con với.
Bạn mở file lên, tại tab Add-ins sẽ xuất hiện 1 nhóm mới chỉ có 1 nút lệnh (giống nút Play hay nút Run trong cửa sổ VBE ấy mà). Bạn quét chọn vùng cần áp dụng highlight và nhấn vào nút lệnh này. Tiếp theo, bạn di chuyển chuột vào vùng mà bạn vừa quét chọn lúc nãy, bạn sẽ thấy tác dụng của code.
À! con run code được rồi! Thầy nghiên cứu thêm xem có thể giải quyết được cái vụ khỏi nháy nháy đấy không ạ. ^^
Nháy kinh hơn cả đèn chớp trong vũ trường... :v

Vấn đề "nháy nháy" đó hình như do máy của bạn "yếu" nên nó mới vậy chứ tôi thấy cũng mượt mà lắm đấy chứ.
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn mở file lên, tại tab Add-ins sẽ xuất hiện 1 nhóm mới chỉ có 1 nút lệnh (giống nút Play hay nút Run trong cửa sổ VBE ấy mà). Bạn quét chọn vùng cần áp dụng highlight và nhấn vào nút lệnh này. Tiếp theo, bạn di chuyển chuột vào vùng mà bạn vừa quét chọn lúc nãy, bạn sẽ thấy tác dụng của code.

Vấn đề "nháy nháy" đó hình như do máy của bạn "yếu" nên nó mới vậy chứ tôi thấy cũng mượt mà lắm đấy chứ.

Hi,Anh phúc!
Cấu hình máy của em cũng không đến nỗi yếu lắm.
Em không tab addin đâu ạ! Anh chỉ cho em cách show nó lên với. Em kiểm tra trong Options thấy đã tích hiển thị tab này rồi nhưng không thấy anh ạ:
Untitled.jpgUntitled.jpg

Anh xem thêm video trong file kèm để thấy sự nháy nháy ở máy em nhé! liệu có phải do máy không ạ?
 

File đính kèm

Upvote 0
Hi,Anh phúc!
Cấu hình máy của em cũng không đến nỗi yếu lắm.
Em không tab addin đâu ạ! Anh chỉ cho em cách show nó lên với. Em kiểm tra trong Options thấy đã tích hiển thị tab này rồi nhưng không thấy anh ạ:
View attachment 108193View attachment 108193

Anh xem thêm video trong file kèm để thấy sự nháy nháy ở máy em nhé! liệu có phải do máy không ạ?
Tab Add-ins chỉ xuất hiện khi trên Excel có chạy 1 add-in nào đó mà có đặt lệnh hoặc nút lệnh trên thanh công cụ. Trong Sub Auto_Open có các lệnh để tạo ra nút lệnh này nên khi mở file ra là bạn sẽ nhìn thấy tab Add-Ins.
Còn cái vụ "nháy nháy" kia thì có lẽ là bạn di chuyển chuột nhiều và nhanh quá nên máy tính nó... mệt. Cái này thì đành phải nhờ đến tác giả rồi.
 
Upvote 0
Tab Add-ins chỉ xuất hiện khi trên Excel có chạy 1 add-in nào đó mà có đặt lệnh hoặc nút lệnh trên thanh công cụ. Trong Sub Auto_Open có các lệnh để tạo ra nút lệnh này nên khi mở file ra là bạn sẽ nhìn thấy tab Add-Ins.
Còn cái vụ "nháy nháy" kia thì có lẽ là bạn di chuyển chuột nhiều và nhanh quá nên máy tính nó... mệt. Cái này thì đành phải nhờ đến tác giả rồi.

--=0 haha! Anh Phúc, vậy mà cũng vui tính thiệt đó!
Vâng vậy thì đợi Thầy olnine rồi để Thầy xem xét vậy.
-----------------
Anh phúc ơi! Anh có thể viết code chạy highlight đó khi mở file được không ạ?
Ví dụ em muốn khi mở file lên thì vùng dữ liệu K3:T100 của sheet3,4,5 hoạt động chế độ highlight này.
Còn ngoài vùng kể trên và ngòai các sheet kể trên này không có dấu hiệu gì hết.
Sau đó khi đóng file thì tất nhiên chế độ này sẽ tắt đi để tránh ảnh hưởng đến các vấn đề khác(nếu có).

Em muốn như vậy là vì Em có nhiều file dữ liệu có một số sheet cũng đồng nhất với nhau về mặt cấu trúc. ví dụ như bảng chấm công của các bộ phận.
Anh giúp em với nhé!
Cảm ơn Anh!
 
Lần chỉnh sửa cuối:
Upvote 0
Tab Add-ins chỉ xuất hiện khi trên Excel có chạy 1 add-in nào đó mà có đặt lệnh hoặc nút lệnh trên thanh công cụ. Trong Sub Auto_Open có các lệnh để tạo ra nút lệnh này nên khi mở file ra là bạn sẽ nhìn thấy tab Add-Ins.
Còn cái vụ "nháy nháy" kia thì có lẽ là bạn di chuyển chuột nhiều và nhanh quá nên máy tính nó... mệt. Cái này thì đành phải nhờ đến tác giả rồi.

A! Em thấy rồi!
Sao lần trước mở lên không thấy đâu nhỉ trong video em gửi lên cũng không thấy!
Cảm ơn Anh!
 

File đính kèm

  • Untitled.jpg
    Untitled.jpg
    146.4 KB · Đọc: 142
Lần chỉnh sửa cuối:
Upvote 0

Vấn đề "nháy nháy" đó hình như do máy của bạn "yếu" nên nó mới vậy chứ tôi thấy cũng mượt mà lắm đấy chứ.

Bạn viết code liên tục thì chỉ xem code thôi bạn cũng phải thấy "nháy, chớp" là hiển nhiên. Thậm chí cả khi chuột đứng im tại chỗ.

Tại sao thậm chí cả khi chuột không động ̣đậy vẫn chớp liên tục? Vì dòng (cột, ô giao dòng cột, hoặc cả dòng và cột) chứa trỏ chuột được Highlight với tần số 100 lần trong 1 giây bất chấp nó đã được Highlight hay chưa.

Gợi ý giải quyết
Chuẩn phải là: dòng (cột, ô giao dòng cột, hoặc cả dòng và cột) chứa trỏ chuột chỉ nên Highlight một lần duy nhất khi trỏ chuột "đi vào" dòng đó (cột đó, ...).

Không phải vô cớ mà trong bài #14 ngoài currCell tôi còn dùng lastCell.

Bạn có đứng cạnh học sinh nào thì bạn cũng chỉ nên cốc đầu 1 lần thôi nhé. Cái tay "ấy" đã cốc cái đầu này 1 lần thì phải nghỉ. Khi bạn chuyển sang học sinh khác thì tay mới lại cốc 1 lần. Chứ nếu bạn nghỉ chân lâu ở cạnh ai và bất chấp đã cốc người ta chưa mà bạn cốc liên tiếp với tần số 100 lần trong một giây thì họ sẽ nhảy cỡn lên như động kinh ấy.
 
Upvote 0
A! Em thấy rồi!
Sao lần trước mở lên không thấy đâu nhỉ trong video em gửi lên cũng không thấy!
Cảm ơn Anh!

Cuối cùng thì hoạt động sao rồi?
Tôi ghi chú rõ rồi nha: Phải quét chọn vùng nào đó (mà bạn muốn làm khu vực Highlight) rồi mới bấm nút
 
Upvote 0
Cuối cùng thì hoạt động sao rồi?
Tôi ghi chú rõ rồi nha: Phải quét chọn vùng nào đó (mà bạn muốn làm khu vực Highlight) rồi mới bấm nút
Theo các bài trên thì cuối cùng đồng chí KUMI cũng đã chạy được rồi nhưng mà cái máy nó "mệt", nó "thở gấp".
 
Upvote 0
Theo các bài trên thì cuối cùng đồng chí KUMI cũng đã chạy được rồi nhưng mà cái máy nó "mệt", nó "thở gấp".

Cũng có thể...
Do khi test code là test trên nền không có dữ liệu nên không nhận ra cái vụ "giật giật" này. Giờ thử trên bảng tính có nhiều dữ liệu thì đúng là có "thở gấp" thật
Vậy thì sửa thế này:
Dòng khai báo biến trên cùng:
Mã:
Dim rngCursor As Range, rngArea As Range
Sửa thành:
Mã:
Dim rngCursor As Range, rngArea As Range[COLOR=#ff0000], rngOld As Range[/COLOR]
Sub TimerProc sửa thành:
Mã:
Function TimerProc(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
  Dim lPoint As POINTAPI
  On Error Resume Next
  GetCursorPos lPoint
  Set rngCursor = ActiveWindow.RangeFromPoint(lPoint.x, lPoint.y)
  If Not rngCursor Is Nothing Then
    [COLOR=#ff0000]If rngCursor.Address <> rngOld.Address Then[/COLOR]
      Highlight rngArea, rngCursor, HL_COLOR, HL_TYPE
      [COLOR=#ff0000]Set rngOld = rngCursor[/COLOR]
   [COLOR=#ff0000] End If[/COLOR]
  End If
End Function
Chổ màu đỏ là những chổ thêm vào
 

File đính kèm

Upvote 0
Tặng các bạn hiệu ứng MouseMove cho cột và hàng mới nè!

Không sử dụng Conditional Formatting, dễ dàng giới hạn hàng cột hiệu ứng. Hàng có màu khác, cột có màu khác, điểm giao nhau giữa hàng và cột cũng khác. Code chạy mượt mà, trả lại màu chính xác!

Toàn bộ code của "tui" đây, kekeke:

Mã:
Option Explicit
''******************************************************************************************
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
''******************************************************************************************
Private Type POINTAPI
    x As Long
    y As Long
End Type
''******************************************************************************************
Private Cancel As Boolean
''******************************************************************************************


Sub ChangeCellColor()


    On Error Resume Next
    Dim pt As POINTAPI
    
    Dim RowsColor(), ColsColor(), RowsBoolean(), ColsBoolean(), _
        LastColRange As Range, CurrColRange As Range, _
        LastRowRange As Range, CurrRowRange As Range, _
        LastCell As Range, CurrCell As Range
        
    Dim StartRow As Long, EndRow As Long, StartCol As Long, EndCol As Long, _
        LastRow As Long, CurrRow As Long, LastCol As Long, CurrCol As Long, _
        RowColor As Long, ColColor As Long, MidColor As Long, _
        c As Long, r As Long, ir As Long, ic As Long
    
[COLOR=#ff0000][B]    ''Muon thay doi so HANG? Tai day:[/B][/COLOR]
    StartRow = 5: EndRow = 24
    
[COLOR=#ff0000][B]    ''Muon thay doi so COT? Tai day:[/B][/COLOR]
    StartCol = 3: EndCol = 27
    
[B][COLOR=#ff0000]    ''Muon thay doi Interior.Color? Tai day:[/COLOR][/B]
    RowColor = 13408767: ColColor = 10079487: MidColor = 65280
    
    ir = StartRow - 1: ic = StartCol - 1
    
    ReDim RowsColor(StartCol To EndCol)
    ReDim RowsBoolean(StartCol To EndCol)
    ReDim ColsColor(StartRow To EndRow)
    ReDim ColsBoolean(StartRow To EndRow)
    
    Cancel = False
    
    Do
    
[COLOR=#ff0000][B]        ''Gioi han SHEET can tao hieu ung:[/B][/COLOR]
        If ActiveSheet.Name <> "TrongNghia" Then Exit Sub
        GetCursorPos pt
        Set CurrCell = ActiveWindow.RangeFromPoint(pt.x, pt.y)
        If Not CurrCell Is Nothing Then
        
            If Not Intersect(CurrCell, Range(Cells(StartRow, StartCol), Cells(EndRow, EndCol))) Is Nothing Then
            
                If LastCell Is Nothing Then
                
                    CurrRow = CurrCell.Row
                    CurrCol = CurrCell.Column
                    
[COLOR=#008000]                    ''Xac dinh Hang:[/COLOR]
                    Set CurrRowRange = Range(Cells(CurrRow, StartCol), Cells(CurrRow, EndCol))
                    For c = StartCol To EndCol
                        If CurrRowRange(c - ic).Interior.Pattern = xlNone Then
                            RowsBoolean(c) = False
                        Else
                            RowsBoolean(c) = True
                            RowsColor(c) = CurrRowRange(c - ic).Interior.Color
                        End If
                    Next
                    
[COLOR=#008000]                    ''Xac dinh Cot:[/COLOR]
                    Set CurrColRange = Range(Cells(StartRow, CurrCol), Cells(EndRow, CurrCol))
                    For r = StartRow To EndRow
                        If CurrColRange(r - ir).Interior.Pattern = xlNone Then
                            ColsBoolean(r) = False
                        Else
                            ColsBoolean(r) = True
                            ColsColor(r) = CurrColRange(r - ir).Interior.Color
                        End If
                    Next
                    
                    CurrRowRange.Interior.Color = RowColor
                    CurrColRange.Interior.Color = ColColor
                    CurrCell.Interior.Color = MidColor


                    Set LastRowRange = CurrRowRange
                    Set LastColRange = CurrColRange
                    Set LastCell = CurrCell
                    
                Else
                
                    If CurrCell.Address <> LastCell.Address Then
                        
                        CurrRow = CurrCell.Row
                        CurrCol = CurrCell.Column
                        
                        For c = StartCol To EndCol
                            If RowsBoolean(c) = True Then
                                LastRowRange(c - ic).Interior.Color = RowsColor(c)
                            Else
                                LastRowRange(c - ic).Interior.Pattern = xlNone
                            End If
                        Next
                        
                        For r = StartRow To EndRow
                            If ColsBoolean(r) = True Then
                                LastColRange(r - ir).Interior.Color = ColsColor(r)
                            Else
                                LastColRange(r - ir).Interior.Pattern = xlNone
                            End If
                        Next
                        
                        Set CurrRowRange = Range(Cells(CurrRow, StartCol), Cells(CurrRow, EndCol))
                        
                        For c = StartCol To EndCol
                            If CurrRowRange(c - ic).Interior.Pattern = xlNone Then
                                RowsBoolean(c) = False
                            Else
                                RowsBoolean(c) = True
                                RowsColor(c) = CurrRowRange(c - ic).Interior.Color
                            End If
                        Next
                    
                        Set CurrColRange = Range(Cells(StartRow, CurrCol), Cells(EndRow, CurrCol))
                        
                        For r = StartRow To EndRow
                            If CurrColRange(r - ir).Interior.Pattern = xlNone Then
                                ColsBoolean(r) = False
                            Else
                                ColsBoolean(r) = True
                                ColsColor(r) = CurrColRange(r - ir).Interior.Color
                            End If
                        Next
                        
                        CurrRowRange.Interior.Color = RowColor
                        CurrColRange.Interior.Color = ColColor
                        CurrCell.Interior.Color = MidColor
                        
                        Set LastRowRange = CurrRowRange
                        Set LastColRange = CurrColRange
                        Set LastCell = CurrCell
                        
                    End If
                    
                End If
                
            Else
            
                If Not LastCell Is Nothing Then
                
                    For c = StartCol To EndCol
                        If RowsBoolean(c) = True Then
                            LastRowRange(c - ic).Interior.Color = RowsColor(c)
                        Else
                            LastRowRange(c - ic).Interior.Pattern = xlNone
                        End If
                    Next
                    
                    For r = StartRow To EndRow
                        If ColsBoolean(r) = True Then
                            LastColRange(r - ir).Interior.Color = ColsColor(r)
                        Else
                            LastColRange(r - ir).Interior.Pattern = xlNone
                        End If
                    Next
                    
                End If
                
            End If
            
        End If
            
        DoEvents
        
    Loop Until Cancel = True
    
End Sub
''******************************************************************************************


Sub CancelProcedure()
    Cancel = True
End Sub
''******************************************************************************************
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Cũng có thể...
Do khi test code là test trên nền không có dữ liệu nên không nhận ra cái vụ "giật giật" này. Giờ thử trên bảng tính có nhiều dữ liệu thì đúng là có "thở gấp" thật
....

Một hạn chế lớn nhất của code này là nếu dữ liệu có đặt sẳn Conditional Formatting thì sẽ mất hết Thầy ơi. Nhưng thật sự mà nói thì nó chạy cũng rất mượt mà.
 
Upvote 0
Một hạn chế lớn nhất của code này là nếu dữ liệu có đặt sẳn Conditional Formatting thì sẽ mất hết Thầy ơi. Nhưng thật sự mà nói thì nó chạy cũng rất mượt mà.
Tại đồng chí CỦ MÌ nói thích loại này mà (loại mà anhtuan1066 đã làm, cũng bằng CF)
------------------------------------------
Tôi đang cố gắng viết thành 1 ứng dụng hoàn chỉnh (để ai xài thì xài) và ứng dụng này phải có tính năng cho phép cấu hình: Màu sắc highlight, kiểu highlight, vùng giới hạn highlight... vân vân...
Vậy nên chắc chắn tôi sẽ chọn 1 trong 2 cách: Dùng conditonal format hoặc lát 1 shape trên bảng tính để highlight chứ không chơi chiêu tô màu trực tiếp
Tôi ưu tiên dùng CF. Dù nó có xóa những CF trước đó cũng chả sao (tôi sẽ cảnh báo bằng MsgBox)
Vấn đề khó khăn hiện tại: Suy nghĩ sao cho thiết kế mang tính thẩm mỹ cao + thân thiện với người dùng (còn code thì chẳng có vấn đề gì)
Ẹc... Ẹc...
 
Upvote 0
Một hạn chế lớn nhất của code này là nếu dữ liệu có đặt sẳn Conditional Formatting thì sẽ mất hết Thầy ơi. Nhưng thật sự mà nói thì nó chạy cũng rất mượt mà.

Em test trên Win 8 64bit thì nó báo lỗi sau anh Nghĩa ah:

---------------------------
Microsoft Visual Basic for Applications
---------------------------
Compile error:

The code in this project must be updated for use on 64-bit systems. Please review and update Declare statements and then mark them with the PtrSafe attribute.
---------------------------
OK Help
---------------------------
 
Upvote 0
Tại đồng chí CỦ MÌ nói thích loại này mà (loại mà anhtuan1066 đã làm, cũng bằng CF)
------------------------------------------
Tôi đang cố gắng viết thành 1 ứng dụng hoàn chỉnh (để ai xài thì xài) và ứng dụng này phải có tính năng cho phép cấu hình: Màu sắc highlight, kiểu highlight, vùng giới hạn highlight... vân vân...
Vậy nên chắc chắn tôi sẽ chọn 1 trong 2 cách: Dùng conditonal format hoặc lát 1 shape trên bảng tính để highlight chứ không chơi chiêu tô màu trực tiếp
Tôi ưu tiên dùng CF. Dù nó có xóa những CF trước đó cũng chả sao (tôi sẽ cảnh báo bằng MsgBox)
Vấn đề khó khăn hiện tại: Suy nghĩ sao cho thiết kế mang tính thẩm mỹ cao + thân thiện với người dùng (còn code thì chẳng có vấn đề gì)
Ẹc... Ẹc...

Em có nghĩ vấn đề này (màu đỏ), nhưng không khả thi, bởi nó sẽ che mất dữ liệu, nó không trong suốt, nếu nó trong suốt thì không hiện màu.
 
Upvote 0
Em test trên Win 8 64bit thì nó báo lỗi sau anh Nghĩa ah:

Nó không chạy được có lẽ do thằng em này:

Mã:
[COLOR=#000000]Private Declare Function GetCursorPos Lib [/COLOR][COLOR=#ff0000][B]"user32"[/B][/COLOR][COLOR=#000000] (lpPoint As POINTAPI) As Long

Có hàm API nào chạy được trên "User64" không vậy mọi người?[/COLOR]
 
Upvote 0
Tại đồng chí CỦ MÌ nói thích loại này mà (loại mà anhtuan1066 đã làm, cũng bằng CF)
------------------------------------------

AAA!! Vì con áp dụng cái Highlight đó của Thầy vào công việc thấy rất chuyên nghiệp và hiệu quả cho công việc... nên con mới "KẾT" chứ! Nhưng mà điều này liên quan gì đến Thầy viết code mà làm mất cả CF đâu nhỉ hôhô!! Đó là vì tại Thầy nhiệt huyết quá đà chứ ạ!^^
Mà biệt danh "CỦ MÌ" cuả Thầy đặt con thấy rất dễ thương(ở chỗ con gọi củ này là củ sắn)! Cái củ này nó gợi cho con nhớ về thời thơ ấu...!Con Cảm ơn Thầy vì cái tên gọi dân gian này! (^_-)!
----------------------------

------------------------------------------
Tôi đang cố gắng viết thành 1 ứng dụng hoàn chỉnh (để ai xài thì xài) và ứng dụng này phải có tính năng cho phép cấu hình: Màu sắc highlight, kiểu highlight, vùng giới hạn highlight... vân vân...
Vậy nên chắc chắn tôi sẽ chọn 1 trong 2 cách: Dùng conditonal format hoặc lát 1 shape trên bảng tính để highlight chứ không chơi chiêu tô màu trực tiếp
Tôi ưu tiên dùng CF. Dù nó có xóa những CF trước đó cũng chả sao (tôi sẽ cảnh báo bằng MsgBox)
Vấn đề khó khăn hiện tại: Suy nghĩ sao cho thiết kế mang tính thẩm mỹ cao + thân thiện với người dùng (còn code thì chẳng có vấn đề gì)
Ẹc... Ẹc...

Tiện thể Thầy nghiên cứu làm sao cho gắn code vào sự kiện mở file ý Thầy! không dùng nút nữa.(còn Addin vẫn có thể để được) Vì file là người dùng chung nên con muốn đặt sẵn cái tính năng này khi mở file giống như cái file highlight của Thầy đó ạ!
Và một mong muốn nữa là chế độ highlight khác nhau giữa các sheet. Ví dụ: sheet1 không highlight. Sheet2 highlight từ vùng A2:K10 sheet3 đến Sheet9 highlight từ vùng E3:T123 chẳng hạn! Nghĩa là làm sao để có thể kiểm soát được vấn highlight ạ!

Hì làm thì con không biết nhưng đưa ra đòi hỏi chẳng kèm gì ai!!! hahaha (tại Thầy mị, Thầy bảo với con trong chủ đề cảm nhận về GPE là hỏi cũng là một cách đóng góp, không có người hỏi thì khác gì tự chơi cờ một mình - con luôn nhớ câu này..hihi).
 
Upvote 0
Không sử dụng Conditional Formatting, dễ dàng giới hạn hàng cột hiệu ứng. Hàng có màu khác, cột có màu khác, điểm giao nhau giữa hàng và cột cũng khác. Code chạy mượt mà, trả lại màu chính xác!

Toàn bộ code của "tui" đây, kekeke:

Mã:
Option Explicit
''******************************************************************************************
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
''******************************************************************************************
Private Type POINTAPI
    x As Long
    y As Long
End Type
''******************************************************************************************
Private Cancel As Boolean
''******************************************************************************************


Sub ChangeCellColor()


    On Error Resume Next
    Dim pt As POINTAPI
    
    Dim RowsColor(), ColsColor(), RowsBoolean(), ColsBoolean(), _
        LastColRange As Range, CurrColRange As Range, _
        LastRowRange As Range, CurrRowRange As Range, _
        LastCell As Range, CurrCell As Range
        
    Dim StartRow As Long, EndRow As Long, StartCol As Long, EndCol As Long, _
        LastRow As Long, CurrRow As Long, LastCol As Long, CurrCol As Long, _
        RowColor As Long, ColColor As Long, MidColor As Long, _
        c As Long, r As Long, ir As Long, ic As Long
    
[COLOR=#ff0000][B]    ''Muon thay doi so HANG? Tai day:[/B][/COLOR]
    StartRow = 5: EndRow = 24
    
[COLOR=#ff0000][B]    ''Muon thay doi so COT? Tai day:[/B][/COLOR]
    StartCol = 3: EndCol = 27
    
[B][COLOR=#ff0000]    ''Muon thay doi Interior.Color? Tai day:[/COLOR][/B]
    RowColor = 13408767: ColColor = 10079487: MidColor = 65280
    
    ir = StartRow - 1: ic = StartCol - 1
    
    ReDim RowsColor(StartCol To EndCol)
    ReDim RowsBoolean(StartCol To EndCol)
    ReDim ColsColor(StartRow To EndRow)
    ReDim ColsBoolean(StartRow To EndRow)
    
    Cancel = False
    
    Do
    
[COLOR=#ff0000][B]        ''Gioi han SHEET can tao hieu ung:[/B][/COLOR]
        If ActiveSheet.Name <> "TrongNghia" Then Exit Sub
        GetCursorPos pt
        Set CurrCell = ActiveWindow.RangeFromPoint(pt.x, pt.y)
        If Not CurrCell Is Nothing Then
        
            If Not Intersect(CurrCell, Range(Cells(StartRow, StartCol), Cells(EndRow, EndCol))) Is Nothing Then
            
                If LastCell Is Nothing Then
                
                    CurrRow = CurrCell.Row
                    CurrCol = CurrCell.Column
                    
[COLOR=#008000]                    ''Xac dinh Hang:[/COLOR]
                    Set CurrRowRange = Range(Cells(CurrRow, StartCol), Cells(CurrRow, EndCol))
                    For c = StartCol To EndCol
                        If CurrRowRange(c - ic).Interior.Pattern = xlNone Then
                            RowsBoolean(c) = False
                        Else
                            RowsBoolean(c) = True
                            RowsColor(c) = CurrRowRange(c - ic).Interior.Color
                        End If
                    Next
                    
[COLOR=#008000]                    ''Xac dinh Cot:[/COLOR]
                    Set CurrColRange = Range(Cells(StartRow, CurrCol), Cells(EndRow, CurrCol))
                    For r = StartRow To EndRow
                        If CurrColRange(r - ir).Interior.Pattern = xlNone Then
                            ColsBoolean(r) = False
                        Else
                            ColsBoolean(r) = True
                            ColsColor(r) = CurrColRange(r - ir).Interior.Color
                        End If
                    Next
                    
                    CurrRowRange.Interior.Color = RowColor
                    CurrColRange.Interior.Color = ColColor
                    CurrCell.Interior.Color = MidColor


                    Set LastRowRange = CurrRowRange
                    Set LastColRange = CurrColRange
                    Set LastCell = CurrCell
                    
                Else
                
                    If CurrCell.Address <> LastCell.Address Then
                        
                        CurrRow = CurrCell.Row
                        CurrCol = CurrCell.Column
                        
                        For c = StartCol To EndCol
                            If RowsBoolean(c) = True Then
                                LastRowRange(c - ic).Interior.Color = RowsColor(c)
                            Else
                                LastRowRange(c - ic).Interior.Pattern = xlNone
                            End If
                        Next
                        
                        For r = StartRow To EndRow
                            If ColsBoolean(r) = True Then
                                LastColRange(r - ir).Interior.Color = ColsColor(r)
                            Else
                                LastColRange(r - ir).Interior.Pattern = xlNone
                            End If
                        Next
                        
                        Set CurrRowRange = Range(Cells(CurrRow, StartCol), Cells(CurrRow, EndCol))
                        
                        For c = StartCol To EndCol
                            If CurrRowRange(c - ic).Interior.Pattern = xlNone Then
                                RowsBoolean(c) = False
                            Else
                                RowsBoolean(c) = True
                                RowsColor(c) = CurrRowRange(c - ic).Interior.Color
                            End If
                        Next
                    
                        Set CurrColRange = Range(Cells(StartRow, CurrCol), Cells(EndRow, CurrCol))
                        
                        For r = StartRow To EndRow
                            If CurrColRange(r - ir).Interior.Pattern = xlNone Then
                                ColsBoolean(r) = False
                            Else
                                ColsBoolean(r) = True
                                ColsColor(r) = CurrColRange(r - ir).Interior.Color
                            End If
                        Next
                        
                        CurrRowRange.Interior.Color = RowColor
                        CurrColRange.Interior.Color = ColColor
                        CurrCell.Interior.Color = MidColor
                        
                        Set LastRowRange = CurrRowRange
                        Set LastColRange = CurrColRange
                        Set LastCell = CurrCell
                        
                    End If
                    
                End If
                
            Else
            
                If Not LastCell Is Nothing Then
                
                    For c = StartCol To EndCol
                        If RowsBoolean(c) = True Then
                            LastRowRange(c - ic).Interior.Color = RowsColor(c)
                        Else
                            LastRowRange(c - ic).Interior.Pattern = xlNone
                        End If
                    Next
                    
                    For r = StartRow To EndRow
                        If ColsBoolean(r) = True Then
                            LastColRange(r - ir).Interior.Color = ColsColor(r)
                        Else
                            LastColRange(r - ir).Interior.Pattern = xlNone
                        End If
                    Next
                    
                End If
                
            End If
            
        End If
            
        DoEvents
        
    Loop Until Cancel = True
    
End Sub
''******************************************************************************************


Sub CancelProcedure()
    Cancel = True
End Sub
''******************************************************************************************

Cảm ơn Anh nghĩa nhiều nhé!
Em thấy dường như Anh rất có năng khiếu về mấy cái món hiệu ứng, hay màu mè này, dạng dạng như đánh bóng trang điểm file đó... ^^!
Vì em Thấy anh gửi tặng toàn những cái trông rất đẹp mắt, như là: Lịch,UserName,MsgBox.v.v...
 
Upvote 0
Cảm ơn Anh nghĩa nhiều nhé!
Em thấy dường như Anh rất có năng khiếu về mấy cái món hiệu ứng, hay màu mè này, dạng dạng như đánh bóng trang điểm file đó... ^^!
Vì em Thấy anh gửi tặng toàn những cái trông rất đẹp mắt, như là: Lịch,UserName,MsgBox.v.v...

Lập trình giao diện không phải là thứ dễ nhai đâu nha các bạn! Ví dụ code chính trong Form chỉ dăm ba thủ tục cho việc nhập liệu, chỉnh sửa, lưu lại v.v... thì việc trình bày giao diện, hiệu ứng mất hết nhiều cái module hoặc class.

Tôi vẫn luôn nằm lòng câu nói của Thầy NDU: "Ăn chắc mặc bền", tôi luôn luôn tính cho đến khi nó hoàn toàn chính xác phần code chính của mình; song, tôi vẫn luôn có xu hướng "Ăn ngon mặc đẹp" và vì thế tôi có thói quen thích sưu tầm và nghiên cứu những cái gọi là "màu mè" như thế.

Nhưng để ý mà xem, điện thoại cũng như máy tính họ cải tiến phần mềm không đáng kể, nhưng họ cải tiến về mặt giao diện thì rất nhiều, họ ăn tiền nhờ giao diện (phần cứng lẫn phần mềm), ngoài thương hiệu ra thì giao diện làm cho sản phẩm bắt mắt hơn, thu hút hơn.
 
Upvote 0
Hi, Anh nghĩa!
Em định thử kết hợp2 kiểu Highlight lại với nhau đó là (SelectionChange + Mouse move).
Nhưng nó thế này anh ơi!(anh xem file kèm nhé).

Sở dĩ vì sao mà em lại muốn kết hợp như vậy là vì:
Trong quá trình nhập liệu ta luôn sử dụng phím qua trái qua phải lên xuông không sử dụng chuột. Nhưng mà trong quá trình rà soát dữ liệu ta lại sử dụng chuôyj không sử dụng phím!
Nếu mà kết hợp 2 cái này thì nhìn bảng tính cũng kinh và lòe loẹt quá!
Có thể nào làm sao để khi sử dụng một trong 2 chức năng này thì chức năng còn lại sẽ mất đi (hay nói cách khác là 2 chức năng hợp làm một luôn)...hix!
 

File đính kèm

Upvote 0
Một hạn chế lớn nhất của code này là nếu dữ liệu có đặt sẳn Conditional Formatting thì sẽ mất hết Thầy ơi. Nhưng thật sự mà nói thì nó chạy cũng rất mượt mà.

Mượt ở mức về thực tế có thể chấp nhận được. Nhưng về mặt lý thuyết thì vẫn chưa chuẩn.

Nếu có HL_TYPE = 1, tức tô mầu dòng, thì khi di chuyển chuột rất nhanh trong cùng dòng thì chuẩn phải là chỉ tô mầu một lần vì chỉ số dòng không đổi. Nhưng code vẫn tô mầu trong suốt quá trình di chuyển chuột do cell thay đổi. Dễ thấy nhất khi ta cho 1 dòng nào đó thật cao - để khi di chuột rất nhanh thì trỏ chuột không "lẹm" sang hàng khác - rồi di chuyển chuột nhanh. Thực ra di chuyển bình thường thì thỉnh thoảng vấn thấy nháy: tắt - xóa, tức hiển thị mầu nền (Area.FormatConditions.Delete) rồi bật - vẽ, tức hiển thị mầu mới (... rngTmp.FormatConditions(1).Interior.ColorIndex = ColorIndex)

Tương tự khi HL_TYPE = 2 và di chuyển trong cột.
----------
Code sau chắc chắn chỉ tô mầu 1 lần
Mã:
Dim rngCursor As Range, rngArea As Range
[B][COLOR=#ff0000]Dim lastRow As Long, lastColumn As Long[/COLOR][/B]

đỏ đỏ là mới thêm

code
Mã:
Private Sub Highlight(ByVal Area As Range, ByVal Target As Range, ByVal ColorIndex As Long, _
                     Optional ByVal Highlight_Type As Long = 1)
Dim rngTmp As Range
On Error Resume Next
    
    If Not Intersect(Area, Target) Is Nothing Then
        With Area
            Select Case Highlight_Type
                Case 1:
                    If Target.Row <> lastRow Then
                        lastRow = Target.Row
                        Set rngTmp = Intersect(.Cells, Target.EntireRow)
                    End If
                Case 2:
                    If Target.Column <> lastColumn Then
                        lastColumn = Target.Column
                        Set rngTmp = Intersect(.Cells, Target.EntireColumn)
                    End If
                Case 3, 4:
                    If Target.Row <> lastRow Or Target.Column <> lastColumn Then
                        lastRow = Target.Row
                        lastColumn = Target.Column
                        If Highlight_Type = 3 Then
                            Set rngTmp = Intersect(.Cells, Union(Target.EntireColumn, Target.EntireRow))
                        Else
                            Set rngTmp = Intersect(Range(.Cells(1, 1), Target), Union(Target.EntireColumn, Target.EntireRow))
                        End If
                    End If
            End Select
        End With
        If Application.CutCopyMode = False And Not rngTmp Is Nothing Then
            Area.FormatConditions.Delete
            rngTmp.FormatConditions.Add 2, , "TRUE"
            rngTmp.FormatConditions(1).Interior.ColorIndex = ColorIndex
        End If
    End If
End Sub

So sánh code cũ mới sẽ thấy những chỗ khác.

Nói lại: về mặt thực tế thì độ mượt chấp nhận được. Tôi chỉ bàn thêm về mặt lý thuyết cho chuẩn hơn mà thôi.
 
Upvote 0
Nó không chạy được có lẽ do thằng em này:

Mã:
[COLOR=#000000]Private Declare Function GetCursorPos Lib [/COLOR][COLOR=#ff0000][B]"user32"[/B][/COLOR][COLOR=#000000] (lpPoint As POINTAPI) As Long[/COLOR]


Có hàm API nào chạy được trên "User64" không vậy mọi người?

Do kiểu dữ liệu bạn ạ. Vd. Long (32 bit) - LongPtr (64 bit)

Có thể tìm đọc trên mạng, vd.

http://msdn.microsoft.com/en-us/library/office/ff700513(v=office.11).aspx

Tôi không có nhu cầu, cũng không có 64 bit, vậy tôi không tham gia. Gợi ý thôi.
 
Upvote 0
Do kiểu dữ liệu bạn ạ. Vd. Long (32 bit) - LongPtr (64 bit)

Có thể tìm đọc trên mạng, vd.

http://msdn.microsoft.com/en-us/library/office/ff700513(v=office.11).aspx

Tôi không có nhu cầu, cũng không có 64 bit, vậy tôi không tham gia. Gợi ý thôi.

Riêng cái file bài số 36, em nghĩ là vẫn còn cách làm cho nó mượt mà hơn, vì nếu con trỏ chạy trên một hàng thì cột thay đổi nhưng hàng không thay đổi và ngược lại nếu chạy trên một cột thì hàng thay đổi mà cột không thay đổi, chỉ thay đổi hoàn toàn khi khác hàng và khác cột mà thôi, nhưng em làm không thành công (bị dính vài cell không trả lại màu sắc ban đầu). Nghĩ được mà chả làm được -> Chán!
 
Upvote 0
1> Code trong Module (tên: modTimer)
Mã:
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Public Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long

Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Private Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Type POINTAPI
  X As Long
  Y As Long
End Type
Dim bChk As Boolean
Public curCell As Range
Public curColorIndex As Integer

Private Const GWL_HWNDPARENT As Long = (-8)
Public Const ActiveColor = 24
Public Sub TimerProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal oTimer As clsTimer, ByVal dwTime As Long)
  oTimer.RaiseTimer
End Sub
Public Function hWndMain() As Long
  Call EnumThreadWindows(GetCurrentThreadId(), AddressOf EnumThreadWndProc, VarPtr(hWndMain))
End Function
Private Function EnumThreadWndProc(ByVal hWnd As Long, ByVal lpResult As Long) As Long
  If bChk = False Then
    If GetWindowLong(hWnd, GWL_HWNDPARENT) Then
      EnumThreadWndProc = True
    Else
      Call CopyMemory(ByVal lpResult, hWnd, 4)
      EnumThreadWndProc = False
    End If
  ElseIf bChk = True Then
    Dim WindowText As String
    EnumThreadWndProc = True
    If GetWindowLong(hWnd, GWL_HWNDPARENT) = 0 Then
      WindowText = Space$(512)
      If GetWindowText(hWnd, WindowText, Len(WindowText)) Then
        If InStr(WindowText, Application.Name) Then
          Call CopyMemory(ByVal lpResult, hWnd, 4&)
          EnumThreadWndProc = False
        End If
      End If
    End If
  End If
End Function
2> Code trong Module (tên modMain)
Mã:
Dim m_Event As New clsControl
Sub Event_Start()
  m_Event.Timer_Start
End Sub
Sub Event_Stop()
  m_Event.Timer_Stop
End Sub
3> Code trong Class Module (tên clsTimer)
Mã:
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long

Private m_TmrID As Long
Private m_hWnd As Long
Private m_Enabled As Boolean
Private m_Interval As Long

Private Const defEnabled As Boolean = False
Private Const defInterval As Long = 0

Public Event Timer()
Private Sub Class_Initialize()
  m_Enabled = defEnabled
  m_Interval = defInterval
  m_hWnd = hWndMain()
End Sub
Private Sub Class_Terminate()
  Call KillTimer(m_hWnd, m_TmrID)
End Sub
Public Property Get Enabled() As Boolean
  Enabled = m_Enabled
End Property
Public Property Let Enabled(ByVal NewEnabled As Boolean)
  If m_Enabled Then
    Call KillTimer(m_hWnd, m_TmrID)
    m_TmrID = 0
  End If
  m_Enabled = NewEnabled
  If m_Interval > 0 Then
    If m_Enabled Then
      m_TmrID = SetTimer(m_hWnd, ObjPtr(Me), m_Interval, AddressOf TimerProc)
    End If
  End If
End Property
Public Property Get Interval() As Long
  Interval = m_Interval
End Property
Public Property Let Interval(ByVal NewInterval As Long)
  If NewInterval >= 0 Then
    m_Interval = NewInterval
    Me.Enabled = m_Enabled
  End If
End Property
Public Sub RaiseTimer()
  RaiseEvent Timer
End Sub
4> Code trong class Module (tên clsControl)
Mã:
Dim WithEvents tmr As clsTimer
Private CursorPos As POINTAPI
Private CursorCell As Range
Public Sub Timer_Start()
  Set tmr = New clsTimer
  tmr.Interval = 100
  tmr.Enabled = True
End Sub
Public Sub Timer_Stop()
  Set tmr = Nothing
End Sub
Private Sub tmr_Timer()
  Dim RetVal As Long
  Dim rng As Range
  RetVal = GetCursorPos(CursorPos)
  RetVal = WindowFromPoint(CursorPos.X, CursorPos.Y)
  On Error Resume Next
  Set CursorCell = Application.Windows(1).RangeFromPoint(CursorPos.X, CursorPos.Y)
  If Err.Number = 0 Then
    If CursorCell.Address <> curCell.Address Then
      curCell.Interior.ColorIndex = curColorIndex
      Set curCell = CursorCell
      curColorIndex = curCell.Interior.ColorIndex
      curCell.Interior.ColorIndex = ActiveColor
    End If
  End If
End Sub
Gọi Sub Event_Start để kịch hoạt và Event_Stop để tắt
(việc giới hạn vùng hoạt động, các bạn tự nghiên cứu nhé)

Cảm ơn bác vì code này rất hay. Em xin nhờ bác giúp thêm tý nữa bởi phát hiện 2 trường hợp:

1. Khi khóa sheet lại thì ô đang có trỏ chuột bị đổi mầu
2. Khi khóa sheet thì code không chạy nữa.

Mong bác giúp em để giải quyết 2 trường hợp trên. Trân trọng cảm ơn
 
Upvote 0
Cảm ơn bác vì code này rất hay. Em xin nhờ bác giúp thêm tý nữa bởi phát hiện 2 trường hợp:

1. Khi khóa sheet lại thì ô đang có trỏ chuột bị đổi mầu
2. Khi khóa sheet thì code không chạy nữa.

Mong bác giúp em để giải quyết 2 trường hợp trên. Trân trọng cảm ơn

Báo cáo các bác, phần 2 em đã giải quyết được bằng cách khi khóa ta loại bỏ phần khóa fỏrmat cell. Còn phần 1 vẫn chưa giải quyết được à
 
Upvote 0
về hiệu ứng rê chuột tô màu hàng và cột trong excel sao ko xài "Kutool for Excel" cho nhanh vậy các bạn, đơn giản mà hiệu quả nữa.
 
Upvote 0

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

Back
Top Bottom