Tạo hiệu ứng cho UserForm

Liên hệ QC

anhtuan1066

Thành viên gạo cội
Tham gia
10/3/07
Bài viết
5,802
Được thích
6,905
Như có lần anh SA_DQ đã nói: "Chúng ta ăn chắc mặc bền trước rồi hãy tiến tới ăn ngon mặc đẹp"
Từ file Tra cứu chéo - hổ trợ nhập liệu tôi cải tiến nó thành 1 Form và sau khi hoàn tất, tôi bắt đầu trang trí, thêm 1 vài tính năng vào form cho thêm phần sống động
Hãy mở file lên, Double click vào 1 trong các cell trong vùng B20:C30 để mở form và khám phá
-------------------------
Những tính năng hiện có trong form:
- Cho phép Sort ListBox khi ta nhấp vào tiêu đề (hổ trợ tìm kiếm)
- Nếu ta gõ 1 vài ký tự vào TextBox thì Listbox sẽ hiển thị kết quả tìm dựa vào từ khóa vừa gõ (như chức năng Find của Excel)
- Một vài tính năng khác nữa
-------------------------
Các phần trang trí thêm vào:
- Form đã được làm mất nút Close form (dấu X)
- Vì lý do gì đó mà form che khuất cửa sổ bảng tính thì ta có thêm chức năng làm trong suốt form để có thể nhìn thấy những gì bên dưới
Để cho các bạn đở rối vì 1 mớ bòng bong, tôi làm thêm 2 file riêng: 1 cái đã được ẩn nút Close và 1 cái có chức năng làm trong suốt Form
Code cực đơn giản nhờ sự hổ trợ của các hàm API
1> Ẩn nút Close Form
PHP:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
PHP:
Private Sub UserForm_Initialize()
  Dim hWnd As Long
  hWnd = FindWindow("ThunderDFrame", Me.Caption)
  SetWindowLong hWnd, -16, &H84C00000
End Sub
Chú ý: Nếu các bạn thay &H84C00000 thành &HFF0000 thì sẽ làm xuất hiện cả 3 Button: Minimize, Maximize Close... và đương nhiên lúc này có thể Resize được Form ngay cả khi nó đang hoạt động
Các bạn có thể dùng dòng lệnh này:
PHP:
MsgBox Hex(GetWindowLong(hwnd, -16))
để đọc thông tin về Style chuẩn của UserForm. Từ đó có thể thí nghiệm và chỉnh sửa theo ý...
Lệnh này cần thêm hàm GetWindowLong:
PHP:
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long

2> Làm trong suốt Form
PHP:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hWnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
PHP:
Private Sub SpinButton1_Change()
  Dim hWnd As Long
  hWnd = FindWindow("ThunderDFrame", Me.Caption)
  SetWindowLong hWnd, -20, H80000
  SetLayeredWindowAttributes hWnd, 0, 255 - SpinButton1.Value, 2
  Label1.Caption = SpinButton1.Value / 10
End Sub
Với SpinButton đã được cài trước trong Properties:
- Max = 160
- Min = 0
- SmallChange = 10

-------------------------
Tôi đã gộp 2 code này vào code chính của file mc_request_03. Các bạn hãy tham khảo nhé
Dù sao thì tác dụng của Form vẫn là hổ trợ ta nhập liệu nhanh hơn, các phần trang trí thêm vào chỉ làm cho ứng dụng thêm hấp dẩn... Các bạn không nên vì thế mà "đua đòi" rồi quên đi mục đích chính
 

File đính kèm

  • UserForm.rar
    53.2 KB · Đọc: 2,302
Tiếp theo chủ đề Tạo hiệu ứng cho UserForm là phần hiển thị nội dung Help (khi bấm vào nút Help)
Tôi đã nghiên cứu qua nhiều cách và thấy rằng: Nếu không có yêu cầu cao về thiết kế thì DialogSheet là lựa chọn đơn giản nhất, dể Edit nhất
Các bạn tham khảo file mới này (Mở Form và bấm vào nút Help)
-------------
Nói thêm 1 chút về hiệu ứng trong suốt: Nếu các bạn có khiếu thẩm mỹ, có thể cải tiến sao cho khi mở Form thì nó hiện dần dần lên (Trong khoảng thời gian 3s, độ trong suốt sẽ tăng từ 0 đến 255)
 

File đính kèm

  • mc_request_03.xls
    97.5 KB · Đọc: 789
Lần chỉnh sửa cuối:
Upvote 0
file của anh tôi xem qua, nhưng bị lỗi trong trường hợp không nhập Text nào hết mà chỉ click mũi tên lên (Up) thì sẽ bị Error
 
Upvote 0
file của anh tôi xem qua, nhưng bị lỗi trong trường hợp không nhập Text nào hết mà chỉ click mũi tên lên (Up) thì sẽ bị Error
Không biêt bạn đã Test kỹ chưa? Chứ cái mũi tên ấy chỉ dùng để di chuyển ActiveCell, làm sao mà lổi được nhỉ? Nó không liên quan gì đến phần nhập liệu cả, bạn xem lại thử
Có phát hiện ra điều gì bất thường, bạn vui lòng thông báo để tôi hoàn thiện
Cảm ơn trước
(thật ra tôi cũng là tay mơ, nên lổi chắc không thể tránh được)
 
Upvote 0
Error chỉ xảy ra khi di chuyển đến cell đầu tiên mà vẫn tiếp tục click.
Hay là do excel của tôi bị lỗi ?
 
Upvote 0
Tôi làm lại và báo lỗi ở thủ tục này:

Private Sub SpinButton1_Change()
ActiveCell.Offset(Sgn(ActiveCell.Row - SpinButton1.Value)).Activate
End Sub


Nếu có gì phiền thì anh bỏ qua cho nhé
 
Upvote 0
Ồ, lỗi đó là đúng rồi, cần phải thêm điều kiện ràng buộc nữa vì 1 <= Row <=65536 mà
 
Upvote 0
Tiêu đề này là gì "Tạo hiệu ứng cho UserForm" mà, làm sao nó đa đoan hết được, các bác muốn ứng dụng vào thực tế công việc thì cần thêm thắt, bẫy lỗi thêm chứ --=0

Thú thật, mấy cái hiệu ứng này rất hay nhưng mình không mặn mà lắm. Mình thì khoái cái Filter trong Listbox thôi, hi hi

TDN
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi làm lại và báo lỗi ở thủ tục này:

Private Sub SpinButton1_Change()
ActiveCell.Offset(Sgn(ActiveCell.Row - SpinButton1.Value)).Activate
End Sub


Nếu có gì phiền thì anh bỏ qua cho nhé
Tôi cảm ơn bạn chứ sao lại phiền
Mà nghĩ cũng lạ thật... Dù cho ActiveCell.Row có = bao nhiêu và SpinButton1.Value có = bao nhiêu thì hàm Sgn cũng chỉ có giá trị hoặc = -1, hoặc =0, hoặc = 1 thôi... Làm sao có lổi được nhỉ? (cùng lắm nó dịch chuyển sai)
Ác cái là tôi chạy hết lần này đến lần khác mà nó chẳng báo lổi gì nên cũng khó... Tuy nhiên tôi đoán và sửa đại, bạn xem lại file mới dưới đây có còn lổi không nha!
Thú thật, mấy cái hiệu ứng này rất hay nhưng mình không mặn mà lắm. Mình thì khoái cái Filter trong Listbox thôi, hi hi
Thầy Phước nói rất hợp ý tôi... Tôi cũng chẳng mấy thích cái vụ màu mè.. chẳng qua là đang nghiên cứu các hàm API, thấy hay quá nên mượn tạm UserForm là thí nghiệm thôi
Hi.. hi..
Xin các bạn góp ý thêm
 

File đính kèm

  • mc_request_03.rar
    30.2 KB · Đọc: 696
Lần chỉnh sửa cuối:
Upvote 0
Mà nghĩ cũng lạ thật... Dù cho ActiveCell.Row có = bao nhiêu và SpinButton1.Value có = bao nhiêu thì hàm Sgn cũng chỉ có giá trị hoặc = -1, hoặc =0, hoặc = 1 thôi... Làm sao có lổi được nhỉ? (cùng lắm nó dịch chuyển sai)
Ác cái là tôi chạy hết lần này đến lần khác mà nó chẳng báo lổi gì nên cũng khó... Tuy nhiên tôi đoán và sửa đại, bạn xem lại file mới dưới đây có còn lổi không nha!
Vấn đề là khi hàm Sgn trả về -1 mà ActiveCell.Row đang = 1 thì toàn bộ câu lệnh trên sẽ trở thành ActiveCell.Offset(-1).Activate và 1 -1 = 0, không có dòng 0, tương tự sẽ không có dòng >65536 và vì thế mới xảy ra lỗi mà.
 
Upvote 0
Vấn đề là khi hàm Sgn trả về -1 mà ActiveCell.Row đang = 1 thì toàn bộ câu lệnh trên sẽ trở thành ActiveCell.Offset(-1).Activate và 1 -1 = 0, không có dòng 0, tương tự sẽ không có dòng >65536 và vì thế mới xảy ra lỗi mà.
Nếu đúng là lổi này thì còn dể sửa (tôi cũng đã sửa lại như bạn nói trong file đính kèm ở bài #10)... nhưng tôi sợ không phải thế
Bạn cavoi nói rằng ngay khi mở Form (lúc đó ActiveCell.Row =20) rồi bấm SpinButton thì lổi ngay, thế mới lạ chứ
 
Lần chỉnh sửa cuối:
Upvote 0
Lấy ý tưởng từ topic Xin phần mềm quay số tôi nghĩ ra 1 hiệu ứng khác cho UserForm: Mở rộng và thu nhỏ ListBox 1 cách từ từ (Expand/Collapse)
Các bạn hãy mở file đính kèm dưới đây (nhớ Enable macro) sẽ nhìn thấy giao diện như hình:

attachment.php

-------------------------------
Bấm nút Start để khởi động quay số ngẩu nhiên.. Và bắt đầu từ sau lần quay thứ nhất đến những lần sau đó, giao diện UserForm sẽ có chút thay đổi: Xuất hiện thêm thanh Expand

attachment.php

------------------------------------
Nếu các bạn bấm vào thanh Expand này, UserForm sẽ từ từ kéo dài về phía dưới cho đến khi 1 ListBox xuất hiện hoàn toàn

attachment.php

---------------------------------
Lúc này thanh Expand biến thành Collapse.. và đương nhiên nếu ta bấm vào nó, UserForm sẽ thu lại như ban đầu
Hãy mở file và khám phá nhé
ANH TUẤN
 

File đính kèm

  • untitled1.JPG
    untitled1.JPG
    23.9 KB · Đọc: 1,268
  • untitled2.JPG
    untitled2.JPG
    27.1 KB · Đọc: 1,253
  • untitled3.JPG
    untitled3.JPG
    35.9 KB · Đọc: 1,261
  • Ruttham_Trungthuong.rar
    22.8 KB · Đọc: 652
Upvote 0
Ý tưởng và thiết kế của bác rất hay và sáng tạo. Cất để dành cái này, mai mốt có việc dùng đến đây!

Cảm ơn bác nhé!
 
Upvote 0
Tiếp theo chủ đề này, tôi gữi tiếp 1 file nữa bao gồm các hiệu ứng như sau:
- Tiếng Việt trên thanh tiêu đề
- Chơi 1 file âm thanh (midi) khi Form load
- Ảnh động trên UserForm
Với tiêu chí hướng tới sự đơn giản trong thuật toán, tin chắc rằng các bạn sẽ thấy rằng file này tuy hoành tráng nhưng làm nó chỉ là chuyện nhỏ!
Nguyên tắc:
1> Tiếng Việt trên Title bar
Đừng nói gõ tiếng Việt, chỉ mỗi chuyện canh cho dòng chử nằm giữa tiêu đề cũng đã mệt rồi...
Ở đây ta dùng 1 chút kỹ xảo, bằng cách "cắt bỏ" tiêu đề rồi vẽ ra bên dưới nó 1 Label... Khi Form load, do thanh tiêu đề đã biến mất nên ta có cảm giác cái Label bên dưới chính là tiêu đề... Với Lable, việc gõ tiếng Việt hay canh dòng chử nằm giữa là chuyện cỏn con (Font, Size, Color cứ vô tư mà chỉnh trong Label Properties)
Chắc các bạn từng nhớ bài viết trước có giới thiệu cách ẩn nút Close:
PHP:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Sub UserForm_Initialize()
  Dim hWnd As Long
  hWnd = FindWindow("ThunderDFrame", Me.Caption)
  SetWindowLong hWnd, -16, &H84C00000
End Sub
Với code này, các bạn chỉ cần thay &H84C00000 thành &H84080080 và thêm 1 đoạn vào phía dưới cùng:
PHP:
Me.Height = Me.Height + 1: Me.Height = Me.Height - 1
Là lập tức thanh tiêu đề sẽ biến mất
Code cuối cùng như sau:
PHP:
Private Sub UserForm_Initialize()
  Dim hWnd As Long, dw As Long
  dw = &H84080080
  hWnd = FindWindow("ThunderDFrame", Me.Caption)
  SetWindowLong hWnd, -16, dw
  Me.Height = Me.Height + 1: Me.Height = Me.Height - 1
End Sub
(Đương nhiên vẫn có 2 hàm API ở trên)
-------------------
2> Chơi âm thanh Midi khi Form load
Trò này lại đơn giản hơn nữa... Chỉ với 1 hàm API
PHP:
Private Declare Function mciExecute Lib "winmm.dll" (ByVal lpstrCommand As String) As Long
1 câu lệnh duy nhất để Play file
PHP:
mciExecute ("play C:\WINDOWS\Media\flourish.mid")
và 1 câu lệnh duy nhất để Stop file
PHP:
mciExecute ("stop C:\WINDOWS\Media\flourish.mid")
Việc còn lại do các bạn quyết định Play và Stop file vào thời điểm nào thì cứ đặt code cho đúng chổ
------------------
2> Tạo ảnh động trên UserForm
Có nhiều cách tạo ảnh động, thông thường người ta dùng vòng lập để load các file GIF vào UserForm (đã có trên diển đàn). Tuy nhiên cách này quá oải (quan trọng là không phải ai cũng biết cách làm, dù nó chẳng khó gì)
Theo tôi cách cực kỳ đơn giản là chèn 1 file Flash vào UserForm... Thậm chí các bạn không cần viết bất cứ code nào mà file Flash vẫn cứ chạy vi vu
Chỉ cần lưu ý 2 điểm quan trọng khi chỉnh thuộc tính cho ShockwaveFlash
- Movie: Là đường dẩn đến file SWF
- EmbedMovie: Chọn giá trị TRUE để "nhúng" luôn file Flash vào UserForm.. để sau này dù có xóa file SWF gốc thì nó vẫn tồn tại trên Form
Nói thêm: Nếu các bạn đang có trong tay 1 file GIF thì hãy dùng phần mềm GIF2SWF để chuyển chúng thành Flash trước (phần mềm loại này có đầy trên mạng)
------------------
File đính kèm dưới đây tích hợp cả 1 đóng hiệu ứng nhưng chỉ toàn là những code cực đơn giản lắp ghép với nhau
Các bạn tham khảo nhé (mượn file RÚT THĂM TRÚNG THƯỞNG để làm các hiệu ứng này)
 

File đính kèm

  • Ruttham_Trungthuong.rar
    37.6 KB · Đọc: 823
Upvote 0
Xin lưu ý với các bạn rằng:
- Thông thường ta di chuyển UserForm bằng cách bấm vào thanh tiêu đề, giữ chuột rồi kéo nó sang nơi khác
- Vậy khi tiêu đề đã được loại bỏ như file trên thì gặp lúc ta muốn di chuyển nó, ta làm cách nào đây?
Các bạn hãy tải file về chạy thử rồi suy nghĩ về tình huống tôi vừa nêu ở trên nhé! Đại khái phải bằng cách nào đó, bấm chuột vào bất cứ điểm nào trên UserForm cũng có thể kéo nó đi được tuốt
Chúng ta sẽ tiếp tục trong bài viết tới đây! Và hy vọng rằng mấy trò chơi này sẽ gây cảm hứng cho mọi người
 
Upvote 0
Không biết các bạn đã tìm ra giải pháp cho vấn đề dùng chuột "kéo" UserForm khi thanh tiêu đề bị cắt bỏ chưa? Thật ra rất đớn giản, dùng 2 sự kiện MouseDown MouseMove là có thể giải quyết gọn
Nguyên tắc:
- Dùng sự kiện MouseDown để lấy tọa độ X, Y của con trỏ chuột:
PHP:
Private PosX As Double, PosY As Double
Private Sub UserForm_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  PosX = X: PosY = Y
End Sub
- Dùng sự kiện MouseMove để thay đổi .Left và .Top cho UserForm, bằng cách cộng PosX, PosY (mà ta đã lấy được từ sự kiện MouseDown) thêm vào .Left và .Top của UserForm
PHP:
Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  Me.Left = Me.Left - (Button > 0) * (X - PosX)
  Me.Top = Me.Top - (Button > 0) * (Y - PosY)
End Sub
Điều kiện Button > 0 ở đây mang ý nghĩa: Chỉ khi chuột "bấm" thì "kéo" mới có tác dụng
Với 2 code này, khi Form load các bạn có thể dùng chuột "nắm" vào bất kỳ nơi đâu trên UserForm và kéo đi, UserForm sẽ di chuyển sang vị trị mới
-----------
Tuy nhiên khi đưa vào code thật sự thì có thay đổi chút ít, ta cũng dùng 2 sự kiện trên, nhưng không phải với UserForm mà là với Label đang được giả lập làm thanh tiêu đề... Như vậy UserForm mới giống thật hơn... Tức chỉ khi "nắm" vào tiêu đề (giả lập) và kéo thì UserForm mới dịch chuyển
Đại khái thế này:
PHP:
Private PosX As Double, PosY As Double
PHP:
Private Sub Label1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  PosX = X: PosY = Y
End Sub
PHP:
Private Sub Label1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  Me.Left = Me.Left - (Button > 0) * (X - PosX)
  Me.Top = Me.Top - (Button > 0) * (Y - PosY)
End Sub
-----------
Bây giờ các bạn hãy tham khảo file Ruttham_Trungthuong.xls sau khi đã được cho hiệu ứng "kéo thả" vào
(Code trong UserForm cũng đã được cải tiến ngắn gọn hơn)
Giao diện chương trình thế này đây:

attachment.php


------------------------------
Các bạn ai tìm ra được hiệu ứng nào hay hãy gữi lên nhé... đương nhiên vẫn trên tiêu chí đơn giản về code (để ai cũng làm được)...
Chẳng hạn các bạn có thể nghiên cứu đề tài này: Làm sao để khi MsgBox xuất hiện, nó không đè lên UserForm
 

File đính kèm

  • Ruttham_Trungthuong.rar
    36.1 KB · Đọc: 879
  • Ruttham_Trungthuong.JPG
    Ruttham_Trungthuong.JPG
    29.1 KB · Đọc: 1,564
Upvote 0
Các bác cho mình hỏi ở cái form trong suốt mình muốn khi khởi động thì giá trị trong suốt mặc định là 6/16 thì làm sao a, mình thay đổi SPIN value =6 thì sau khi click chuột vào mũi tên lên của nút spin 1 lần thì nó mới đổi
 

File đính kèm

  • UserForm_Transparency.xls
    36 KB · Đọc: 137
Upvote 0
Các bác cho mình hỏi ở cái form trong suốt mình muốn khi khởi động thì giá trị trong suốt mặc định là 6/16 thì làm sao a, mình thay đổi SPIN value =6 thì sau khi click chuột vào mũi tên lên của nút spin 1 lần thì nó mới đổi
Thì thêm 1 đoạn code nữa:
PHP:
Private Sub UserForm_Initialize()
  Dim hWnd As Long
  hWnd = FindWindow("ThunderDFrame", Me.Caption)
  SetWindowLong hWnd, -20, &H80000
  SetLayeredWindowAttributes hWnd, 0, 195, 2
End Sub
Đoạn này: SetLayeredWindowAttributes hWnd, 0, 195, 2 ---> Số 195 bạn muốn sửa bao nhiêu tùy ý (trong khoảng 0 đến 255)
 

File đính kèm

  • UserForm_Transparency.xls
    36.5 KB · Đọc: 299
Upvote 0
Web KT
Back
Top Bottom