Để làm hiệu ứng Shadow cho các shape.
Khi mousemove đến 1 shape thì shape đó sáng lên.
Nếu không biết biết tên Label 1 cách tự động thì code viết rườm rà hơn.
Để làm hiệu ứng Shadow cho các shape.
Khi mousemove đến 1 shape thì shape đó sáng lên.
Nếu không biết biết tên Label 1 cách tự động thì code viết rườm rà hơn.
Thông thường muốn dùng hiệu ứng này thì SHEET phải có sự kiện MouseMove, rất tiếc SHEET lại không có nên khi ta rê chuột vào Label thì nó tạo highlight, nhưng khi rê ra ngoài thì không thể trả lại như ban đầu được!
Thông thường muốn dùng hiệu ứng này thì SHEET phải có sự kiện MouseMove, rất tiếc SHEET lại không có nên khi ta rê chuột vào Label thì nó tạo highlight, nhưng khi rê ra ngoài thì không thể trả lại như ban đầu được!
Để làm hiệu ứng Shadow cho các shape.
Khi mousemove đến 1 shape thì shape đó sáng lên.
Nếu không biết biết tên Label 1 cách tự động thì code viết rườm rà hơn.
Bạn xóa hết toàn bộ code trong file. Xong làm vầy:
1> Chèn 1 Module, với code:
Mã:
Dim lblObj() As New Class1
Public lblName As String
Sub AutoOpen()
Dim n As Long
Dim oleObj As OLEObject
For Each oleObj In Sheets("SBS").OLEObjects
If InStr(oleObj.progID, "Forms.Label") Then
n = n + 1
oleObj.Object.BorderStyle = fmBorderStyleNone
ReDim Preserve lblObj(n)
Set lblObj(n).lbl = oleObj.Object
End If
Next
End Sub
2> Chèn 1 Class (mặc định tên là Class1) với code
Mã:
Public WithEvents lbl As MSForms.Label
Private Sub lbl_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
On Error Resume Next
If UCase(lbl.Name) <> UCase(lblName) Then
lbl.BorderStyle = fmBorderStyleSingle
Sheets("SBS").OLEObjects(lblName).Object.BorderStyle = fmBorderStyleNone
lblName = lbl.Name
End If
End Sub
Xong, chạy Sub Autpen rồi rà chuột vào các Label xem sao!
-----------
Chưa hay lắm nhưng tạm dùng được
Ah! Xem kỹ lại code mới hiểu bạn hỏi gì
Giờ xóa hết code sự kiện MouseMove trong Sheet, sửa lại code trong Class1 thành vầy:
Mã:
Public WithEvents lbl As MSForms.Label
Private Sub lbl_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
On Error Resume Next
If UCase(lbl.Name) <> UCase(lblName) Then
lbl.BorderStyle = fmBorderStyleSingle
Sheets("SBS").OLEObjects(lblName).Object.BorderStyle = fmBorderStyleNone
lblName = lbl.Name
Range("O2") = lblName
Call ShowLabel_be4
Sheets("dieukiennho").Range("SBS_celllabel") = lblName
Sheets("dieukiennho").Range("SBS_cellshape") = Replace(lblName, "label", "SBS_shape", , , vbTextCompare)
Call Hidelabel
End If
End Sub
Để làm hiệu ứng Shadow cho các shape.
Khi mousemove đến 1 shape thì shape đó sáng lên.
Nếu không biết biết tên Label 1 cách tự động thì code viết rườm rà hơn.
Tôi đã tạo cho bạn hiệu ứng sáng label, đồng thời, Label nhận Text từ Shape tương ứng; kể cả khi bạn rê con chuột ra ngoài vùng sheet cũng tạo hiệu ứng tắt sáng. và xóa Caption của Label.
Bằng cách nào?
Tôi đã đặt trong sheet SBS một LABEL có tên là lblBackground. Label này đủ lớn để bao tất cả các Label khác trong sheet đó. Nó sẽ được ẩn đi, nhưng sẽ được hiện ra (nhưng ta cũng chả thấy nó vì nó trong suốt mà) khi ta rê chuột vào nút lệnh. Với Label này có nhiệm vụ tạo hiệu ứng ngược, tức trả về giá trị trong suốt và xóa caption của label như ban đầu.
Tôi cũng đặt tên các Shape lại cho tên chúng tương ứng với tên của các Label, nhằm mục đích gọi chúng khi cần thiết.
Code trong Class Module:
[GPECODE=vb]Option Explicit
Public WithEvents LabelMouseMove As MSForms.Label
Private Sub LabelMouseMove_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
On Error Resume Next
With LabelMouseMove
.Caption = ActiveSheet.Shapes(Replace(.Name, "Label", "Shape")).TextFrame.Characters.Text
.BackStyle = fmBackStyleOpaque
End With
Sheets("SBS").lblBackground.Visible = True
Set OldLabel = LabelMouseMove
End Sub[/GPECODE]
Code trong Sheet Module:
[GPECODE=vb]Option Explicit
Private lblMouseMove(0 To 11) As New LabelEvent
Private Sub Worksheet_Activate()
Call LabelSet
End Sub
Private Sub lblBackground_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
On Error Resume Next
OldLabel.Caption = ""
OldLabel.BackStyle = fmBackStyleTransparent
lblBackground.Visible = False
End Sub
Sub LabelSet()
Dim MyLabel(), c As Byte
MyLabel = Array(LabelDSC, LabelDSCNV, _
LabelHDLD, LabelkhautruHDLD, _
Labelbaohiem, Labelphucap, Labeldieuchinhluong, _
Labelngaycong, Labeltheodoino, Labelkhoanphatsinh, _
Labeltongluong, Labelchitiettinhluong)
For c = 0 To 11
Set lblMouseMove(c).LabelMouseMove = MyLabel(c)
Next
End Sub[/GPECODE]
Code trong Thisworkbook Module:
Mã:
Private Sub Workbook_Open()
Sheets("SBS").LabelSet
End Sub
Tôi đã tạo cho bạn hiệu ứng sáng label, đồng thời, Label nhận Text từ Shape tương ứng; kể cả khi bạn rê con chuột ra ngoài vùng sheet cũng tạo hiệu ứng tắt sáng. và xóa Caption của Label.
Bằng cách nào?
Tôi đã đặt trong sheet SBS một LABEL có tên là lblBackground. Label này đủ lớn để bao tất cả các Label khác trong sheet đó. Nó sẽ được ẩn đi, nhưng sẽ được hiện ra (nhưng ta cũng chả thấy nó vì nó trong suốt mà) khi ta rê chuột vào nút lệnh. Với Label này có nhiệm vụ tạo hiệu ứng ngược, tức trả về giá trị trong suốt và xóa caption của label như ban đầu.
Tôi cũng đặt tên các Shape lại cho tên chúng tương ứng với tên của các Label, nhằm mục đích gọi chúng khi cần thiết.
Về giải thuật thì cũng không có gì để bàn (hôm trước nhậu ta bàn rồi)
Về phần thẩm mỹ thì tôi thấy cách dùng Shadow cho shape có vẻ đẹp hơn, dù màu mè nhưng rất tinh tế.
Thử cái dùng Shadow này xem: 1> Code trong Module:
Mã:
Public lblObj() As New clsEffect, n As Long
Public szLabelName As String, szShapeName As String
Sub Auto_Open()
Dim oleObj As OLEObject
n = 0
Sheet1.lblBgrnd.Visible = False
For Each oleObj In Sheet1.OLEObjects
If InStr(oleObj.progID, "Forms.Label") Then
n = n + 1
oleObj.Object.BackStyle = 0
oleObj.Visible = True
ReDim Preserve lblObj(1 To n)
Set lblObj(n).lbl = oleObj.Object
End If
Next
End Sub
Sub ShadowSetup(ByVal Shape As Shape, ByVal ShadowType As Long, ByVal ShadowVisible As Boolean)
With Shape.Shadow
.Visible = ShadowVisible
.Parent.TextFrame.Characters.Font.Bold = ShadowVisible
If ShadowVisible Then
.OffsetX = 0
.OffsetY = 0
.Size = 105
.Type = ShadowType
End If
End With
End Sub
2> Code trong Class: (tên Class = clsEffect)
Mã:
Public WithEvents lbl As MSForms.Label
Private Sub lbl_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
On Error Resume Next
Sheet1.lblBgrnd.Visible = (lbl.Name <> "lblBgrnd")
If UCase(lbl.Name) <> UCase(szLabelName) Then
ShadowSetup Sheet1.Shapes(szShapeName), 25, False
szLabelName = lbl.Name
szShapeName = Replace(szLabelName, "label", "", , , vbTextCompare)
ShadowSetup Sheet1.Shapes(szShapeName), 25, True
End If
End Sub
3> Code trong Sheet:
Mã:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If n = 0 Then Auto_Open
End Sub
Code trong Sheet dùng để phòng ngừa trường hợp code bị lỗi dẫn đến "vỡ" toàn bộ hiệu ứng (khi ấy sẽ chạy lại Autpen để khôi phục)
1 cách xử lý thông minh cua Hoang Trong Nghia, và ndu96081631 rất hợp với ý mình.
Cả 2 code nhìn rất chuyên nghiệp. Ko cần dựa vào range (Define name).
Mục đích của mình vẫn giữ nguyên Shadow sau khi rê chuột ra ngoài vì sau khi Link đến sheet trùng với tên Shape và khi trở lại sheet chính vẫn thấy được sheet nào vừa kích hoạt.
Thanks 2 anh !
\
Mục đích của mình vẫn giữ nguyên Shadow sau khi rê chuột ra ngoài vì sau khi Link đến sheet trùng với tên Shape và khi trở lại sheet chính vẫn thấy được sheet nào vừa kích hoạt.
Thanks 2 anh !
Sửa lại một chút như vầy có vẻ mượt hơn nè anh. Ngoài ra mặc dù Label có nền trong suốt nhưng khi click vào lại hiện lên nền trắng che mất Shape bên dưới. Vì vậy khi dùng sự kiện cũng phải có một chút xảo thuật để xử lý.
Sửa lại một chút như vầy có vẻ mượt hơn nè anh. Ngoài ra mặc dù Label có nền trong suốt nhưng khi click vào lại hiện lên nền trắng che mất Shape bên dưới. Vì vậy khi dùng sự kiện cũng phải có một chút xảo thuật để xử lý.
Thắng thí nghiệm vầy nha:
- Đặt con trỏ chuột tại cell A1
- Alt + F8 chạy lại sub Autpen
- Xong, chọn chuột vào cell B2
Xem thử thấy gì?
Ẹc... Ẹc...
--------------
Còn cái vụ nền trắng xuất hiện che shape thì dễ mà. Mình chưa quan tâm vì đang nói đến MouseMove thôi
Các đối tượng được Wrap từ lúc mở file. Lúc đó name szLabelName chưa có giá trị (rỗng) nên sẽ không bao giờ chọn được Lable lblBgrnd như trường hợp anh nói. Nếu đang chạy file mà gọi lại sub Autpen thì mới có hiện tượng này do lúc này name szLabelName đã có giá trị, muốn khắc phục thì chỉ cần cho cái Lable lblBgrnd ẩn đi trong sub Autpen hoặc gán szLabelName bằng rỗng là được thôi mà.
Các đối tượng được Wrap từ lúc mở file. Lúc đó name szLabelName chưa có giá trị (rỗng) nên sẽ không bao giờ chọn được Lable lblBgrnd như trường hợp anh nói. Nếu đang chạy file mà gọi lại sub Autpen thì mới có hiện tượng này do lúc này name szLabelName đã có giá trị, muốn khắc phục thì chỉ cần cho cái Lable lblBgrnd ẩn đi trong sub Autpen hoặc gán szLabelName bằng rỗng là được thôi mà.
Do ta không lường trước những lỗi có thể xãy ra dẫn đến toàn bộ hiệu ứng bị phá vỡ (lúc ấy các biến Public sẽ bị reset) nên tôi phải dùng sự kiện SelectionChange gọi Autpen để phục hồi... Và đây chính là lúc vấn đề xảy ra (khi click chuột vào vùng chứa Lable background)
Sub ShadowSetup(ByVal Shape As Shape, ByVal ShadowType As Long, ByVal ShadowVisible As Boolean)
With Shape.Shadow
.Visible = ShadowVisible
'.Parent.TextFrame.Characters.Font.Bold = ShadowVisible
If ShadowVisible Then
[COLOR=#ff0000].Style = msoShadowStyleOuterShadow[/COLOR]
[COLOR=#ff0000] .Blur = 9[/COLOR]
.OffsetX = 0
.OffsetY = 0
[COLOR=#ff0000].Transparency = 0.3999999762[/COLOR]
.Size = 102
End If
End With
End Sub
Những chổ màu đỏ là chổ bạn thêm vào và bạn quyết định điều khiển thuộc tính Style (thay vì Type)... trong khi tại ClassModule bạn lại khai báo:
Con số 25 này chẳng ăn nhậu gì trong quá trình cả ---> Dù bạn có thay đổi con số 25 thành bao nhiêu cũng chẳng tác dụng ---> Có nghĩa là THỪA
Vậy: Những chổ bạn vừa thêm vào nên cho vào thành 1 đối số của Sub ShadowSetup sẽ hay hơn. Chẳng hạn:
Mã:
Sub ShadowSetup(ByVal Shape As Shape, [COLOR=#ff0000]ByVal ShadowStyle As Long, [/COLOR][COLOR=#0000cd]ByVal Blurriness As Long[/COLOR], _
[COLOR=#006400]ByVal ShadowTransparency As Double[/COLOR], ByVal ShadowVisible As Boolean)
With Shape.Shadow
.Visible = ShadowVisible
If ShadowVisible Then
[B] [COLOR=#ff0000].Style = ShadowStyle
[/COLOR][COLOR=#0000cd].Blur = Blurriness[/COLOR][/B]
[COLOR=#006400][B].Transparency = ShadowTransparency[/B][/COLOR]
.OffsetX = 0
.OffsetY = 0
.Size = 102
End If
End With
End Sub
Các con số sẽ được truyền vào 1 cách tùy biến hơn
-----------------------
Ở ClassModule bạn viết:
Mã:
With Application.ActiveSheet.Shapes(lbl.Name)
.Visible = False
End With
Có 2 vấn đề:
- Dùng With... End With là thừa (vì chỉ dùng duy nhất 1 lần)
- Bạn xem lbl là 1 Shape là chưa chuẩn (nó đúng là 1 Label ActiveX cơ mà) ---> Tức là gọi đối tượng theo kiểu chung chung chứ chưa hiểu "đích danh" nó là gì
Tôi sẽ sửa lại thế này:
Mã:
Private Sub lbl_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
On Error Resume Next
If UCase(lbl.Name) <> UCase(szLabelName) Then
[COLOR=#ff0000] lbl.Visible = False[/COLOR]
'show labelbe4
With ActiveSheet
[COLOR=#ff0000].OLEObjects(szLabelName)[/COLOR].Visible = True
[COLOR=#ff0000] ShadowSetup .Shapes(szShapeName), 2, 9, 0.3999999762, False [/COLOR]'shape_be4
szLabelName = lbl.Name
szShapeName = Replace(szLabelName, "label", "", , , vbTextCompare)
[COLOR=#ff0000]ShadowSetup .Shapes(szShapeName), 2, 9, 0.3999999762, True[/COLOR] 'shape_mousemove
End With
End If
End Sub
Ngoài ra, nên tập thói quen so sánh: If UCase(lbl.Name) <> UCase(szLabelName) Then
sẽ chắc ăn hơn là If lbl.Name <> szLabelName Then
Vì trong VBA, so sánh chuổi có phân biệt HOA thường
Cái "mẹo" ấy người ta dùng dùng đấy thôi
Các ActiveX đều có sự kiện MouseMove là chuyện rất bình thường
Vấn để ở đây là:
- Xét về mặt thẩm mỹ thì nó không đẹp bằng Shape. Chính vì vậy mà ta giả mới chơi chiêu "lát" 1 Lable lên trên Shape, dùng sự kiện MouseMove của Lable để thay đổi Shadow cho Shape ---> Thế nó mới "bảnh" chứ
Đó là chưa nói đến chuyện ActiveX Control trên sheet không gõ được caption tiếng Việt (trong khi với Shape thì vô tư)
- Trong sheet có nhiều controls nên buộc phải dùng đến Class để rút gọn code (chứ có 2 control thì đâu nói làm gì)
Sửa lại một chút như vầy có vẻ mượt hơn nè anh. Ngoài ra mặc dù Label có nền trong suốt nhưng khi click vào lại hiện lên nền trắng che mất Shape bên dưới. Vì vậy khi dùng sự kiện cũng phải có một chút xảo thuật để xử lý.
Tôi thấy bài này trở đi là đã rất mượt mà rồi, tuy nhiên tôi thấy rằng khi hiệu ứng được tạo ra, khi rê chuột ngang qua các Shape nó còn chuyển con trỏ thành cái nắm (mũi tên 4 chiều).
Ta cũng thấy rằng vì các LABEL chồng lên các SHAPE là trong suốt, vậy không lý do gì ta cho kích cỡ của chúng lại bằng Shape! Ta nên chỉnh lại chúng có độ dài và độ rộng phải lớn hơn các Shape chừng 1-2 li để đủ bao bọc khi shape tạo hiệu ứng shadow, có như thế khi ta rê vào sẽ không còn xuất hiện "cái nắm" nữa.
Khi thực hiện xong, nếu có protect sheet, chúng ta bỏ check tất cả, nhưng phải check vào mục Edit Object thì mới bảo toàn được hiệu ứng nhé!
E đã áp dụng hàm của a Hoang Trong Nghia va Private Sub lbl_MouseDown cua huuthang_bd. Còn Code của a ndu96081631 thấy khó hiểu quả -> chưa áp dụng.
E đã hoàn chỉnh nó ("dễ hiểu, rất chuẩn ").
+ Hiệu ứng SoftEdge (ở sheet SBS)
Click shape Window để Zoom in.
Click shape Start để Zoom out.