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,906
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,303
Các thủ thuật tác động vào Userform hay bất cứ cái gì trên Windows phần lớn đều dùng kỹ thuật lập trình Windows API. Các hàm sử dụng cùng các hằng số do Microsoft đã cung cấp.

Sau đây là ví dụ về tạo nút MINIMIZE , MAXIMIZE và cho phép Resize của Userform
Mã:
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
'--------------------------------------------------------------------------------------------------------
Private Sub UserForm_Initialize()
    Dim oldStyle&, hWnd&
    hWnd = FindWindow("ThunderDFrame", Me.Caption)
    SetWindowLong hWnd, -16, &H84CF0080
End Sub

Con số -16 và &H84CF0080 là gì vậy? Với người lập trình ra nó thì chắc chắn biết nó là phép hợp của một loạt các hằng số, nhưng khi gửi cho người khác, vì lý do nào đó như là để ngắn gọn ta để &H84CF0080. Xét về mặt học thuật thì viết như vậy rất khó để học cho chính mình và ho những người khác.
Trong lập trình, ta nên sử dụng khai báo hằng số, đặc biệt trong API, Microsoft đã cung cấp thành bộ thử viện rồi. Nếu các bạn cài VS sẽ có chương trình "API Text Viewer" để lấy các khai báo này.

Như vậy, để thuận tiện cho người học và phát triển cao hơn, người ta thường viết như sau:
(Các code dưới đây bạn paste vào Userform)
Mã:
Option Explicit
[COLOR="DarkGreen"]'Các khai báo dưới đây được lấy từ "[B]API Text Viewer[/B]" trong bộ [B]Visual Studio 6.0[/B][/COLOR]
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Const GWL_STYLE As Long = -16
Private Const WS_MAXIMIZEBOX As Long = &H10000
Private Const WS_MINIMIZEBOX As Long = &H20000
'--------------------------------------------------------------------------------------------------------
Private Sub UserForm_Initialize()
    Dim hWnd&, oldStyle&
    hWnd = FindWindow("ThunderDFrame", Me.Caption) [COLOR="DarkGreen"]'Lấy điều khiển Windows đang quản lý Userform[/COLOR]
    oldStyle = GetWindowLong(hWnd, GWL_STYLE) [COLOR="DarkGreen"]'Nhận các kiểu thiết lập (Style) đang có của Userform[/COLOR]
[COLOR="DarkGreen"]    'Thiết lập kiểu Userform = [B]giá trị cũ[/B]  cộng thêm (Or) giá trị mới - phép hợp[/COLOR]
    SetWindowLong hWnd, GWL_STYLE, [B]oldStyle[/B] Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX Or WS_SIZEBOX
End Sub

WindowLong : các thiết lập Window mang giá trị kiểu Long (32 bit)
WS_ : là tiếp đầu ngữ cho Window Style (kiểu Window)
 
Lần chỉnh sửa cuối:
Upvote 0
Em muốn dữ liệu ở list view trên bài tập ví dụ chỉ thể hiện các dữ liệu đã Filter được không ạ. EM thấy nếu em filter ở sheet source rồi thì ở List view vẫn thể hiện đầy đủ
 

File đính kèm

  • mc_request_03.rar
    28.1 KB · Đọc: 149
Upvote 0
Em muốn dữ liệu ở list view trên bài tập ví dụ chỉ thể hiện các dữ liệu đã Filter được không ạ. EM thấy nếu em filter ở sheet source rồi thì ở List view vẫn thể hiện đầy đủ
Thay vì sheet bên kia bạn AutoFilter để lọc thì sheet bên này, bạn mở form lên, gõ điều kiện lọc vào TextBox sẽ có kết quả như ý

attachment.php
 

File đính kèm

  • untitled.JPG
    untitled.JPG
    37.7 KB · Đọc: 1,251
Upvote 0
em muốn hỏi thể để biết áp dụng vào bài toán khác thôi
mong các a/c giúp em
 
Upvote 0

Chào Thầy AnhTuan1066, cái Form này của Thầy hay quá, nhưng có 1 điều làm em thắc mắc là khi Họ và Tên dừng chạy, nó hiển thị khoảng 1 giây tên này, nhưng Msgbox lại hiển thị tên khác??? (Nếu tên đó là em, em bị quê liền!!!)
 
Upvote 0
Chào Thầy AnhTuan1066, cái Form này của Thầy hay quá, nhưng có 1 điều làm em thắc mắc là khi Họ và Tên dừng chạy, nó hiển thị khoảng 1 giây tên này, nhưng Msgbox lại hiển thị tên khác??? (Nếu tên đó là em, em bị quê liền!!!)

Sẳn đây cho em hỏi Thầy AnhTuan1066 làm sao sau khi Expand thì Listbox xuất hiện, chia ra làm 2 cột, Thầy có vui lòng chỉnh lại code thành 3 cột được không? Với cột này là cột đầu tiên ghi số thứ tự của người trúng giải thứ 1 đến số n?

Cảm ơn Thầy rất nhiều!
 
Upvote 0
Chào Thầy AnhTuan1066, cái Form này của Thầy hay quá, nhưng có 1 điều làm em thắc mắc là khi Họ và Tên dừng chạy, nó hiển thị khoảng 1 giây tên này, nhưng Msgbox lại hiển thị tên khác??? (Nếu tên đó là em, em bị quê liền!!!)
Trong file có đoạn code:
PHP:
Alert = "ALERT(""" & Evaluate("MsgText1") & Label1.Caption & Chr(10) & Evaluate("MsgText2") & Label2.Caption & Chr(10) & Evaluate("MsgText3") & """,2)"
Với Label1.Caption là HỌ VÀ TÊN và Label2.Caption là số thẻ
Sau khi kết thúc vòng lập, giá trị mà MsgBox hiển thị chính là Label1 và Lable2, tức Label thế nào thì MsgBox sẽ y chang thế, vậy ko lý gì lại có chuyện "nó hiển thị khoảng 1 giây tên này, nhưng Msgbox lại hiển thị tên khác" ... bạn vui lòng kiểm tra lại nhé
----------------------------------
Sẳn đây cho em hỏi Thầy AnhTuan1066 làm sao sau khi Expand thì Listbox xuất hiện, chia ra làm 2 cột, Thầy có vui lòng chỉnh lại code thành 3 cột được không? Với cột này là cột đầu tiên ghi số thứ tự của người trúng giải thứ 1 đến số n?
Cảm ơn Thầy rất nhiều!
Bạn chịu khó nghiên cứu và tự làm lấy nhé! Mình nghĩ nó không đến nổi quá khó đâu
 
Upvote 0
Chào Thầy AnhTuan1066, thỉng thoảng từ cái Form rút thăm trúng thưởng, nó vẫn ra số ngẫu nhiên là Tiêu đề của cột "HỌ VÀ TÊN" và "SỐ THẺ". Trong khi đó, nó không có chứa công thức ngẫu nhiên tại cột "STT"? Làm ơn cho biết lý do và cách khắc phục!
 
Upvote 0
Chào Thầy AnhTuan1066, thỉng thoảng từ cái Form rút thăm trúng thưởng, nó vẫn ra số ngẫu nhiên là Tiêu đề của cột "HỌ VÀ TÊN" và "SỐ THẺ". Trong khi đó, nó không có chứa công thức ngẫu nhiên tại cột "STT"? Làm ơn cho biết lý do và cách khắc phục!
Bạn nói có lẻ đúng
Trong form có đoạn code:
PHP:
Private Sub CommandButton1_Click()
  Dim i As Long, iRnd As Long, Alert As String
  With Range("A1").CurrentRegion
    .Sort .Cells(2, 1), 1, Header:=xlGuess
    For i = 1 To 100
      iRnd = Int(.Rows.Count * Rnd()) + 1
      .................
    Next
  ...............
 
End Sub
Để ý chổ này:
iRnd = Int(.Rows.Count * Rnd()) + 1
Chúng ta cùng phân tích nhé:
- Hàm Rnd() có kết quả từ 0 đến < 1
- .Rows.Count là tổng số dòng dử liệu, trong file nó = 328 dòng
- Vậy .Rows.Count * Rnd() sẽ cho kết quả từ 0 đến < 328
- Khi lồng INT vào thì kết quả thu được sẽ trong khoảng từ 0 đến 327
- Cộng thêm 1, ta được kết quả trong khoảng từ 1 đến 328
===> Tức cận dưới là 1 và cận trên là 328. Dẩn đến trường hợp có đôi lúc nó hiện ra tiêu đề (vì tiêu đề thuộc dòng số 1)
Từ phân tích trên, ta sửa lại đoạn này thành:
iRnd = Int((.Rows.Count - 1) * Rnd()) + 2
Vẫn theo phân tích như trên, kết quả của biểu thức này sẽ cho kết quả dao động trong khoảng từ 2 đến 328 (dòng 2 đến dòng 328)
Hợp lý chứ
Ngoài ra còn 1 cách sửa khác, đó là sửa lại vùng hoạt động của dử liêu:
Thay
With Range("A1").CurrentRegion
thành:
With Range([A2], [C65536].End(xlUp))
Nếu sửa vùng dử liệu thì khỏi phải sửa iRnd, tùy ý bạn!
 

File đính kèm

  • Ruttham_Trungthuong.rar
    62.4 KB · Đọc: 422
Lần chỉnh sửa cuối:
Upvote 0
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á
2> Làm trong suốt Form

.........

Các Thầy ơi, nếu làm Form trong suốt, nhưng chữ trong Form (ghi trong Label) không bị trong suốt có được không ạ?

Cám ơn rất nhiều!
 
Upvote 0
----------------------------------

Bạn chịu khó nghiên cứu và tự làm lấy nhé! Mình nghĩ nó không đến nổi quá khó đâu

Thầy AnhTuan1066 ơi, thầy hướng dẫn em cách làm sao cho Listbox hiện ra 3 cột, trong đó cột 1 là tên giải thưởng (vd: giải Nhất, giải Nhì....). Em xem code của Thầy rồi, nhưng do ko hiểu nên em thêm thắt hay chỉnh sửa thế nào cũng ko được. Thầy giúp em với nha.
 
Upvote 0
Bạn có thể đưa bảng tính này sang autocad mà khi in bản vẽ autocad thì nền của bảng excel và autocad đồng nhất với nhau không?
 
Upvote 0
Bạn click chuột vào ListBox rồi sửa ColumnCount từ số 2 thành số 3 hoặc n là được.
Bạn cũng có thể thay đổi từ code trong UserForm_Initialize()


Mã:
Private Sub UserForm_Initialize()
 
      ListBox1.ColumnCount = [COLOR=#ff0000]6[/COLOR]



End Sub
Màu đỏ là số cột bạn nhé.
 
Upvote 0
Vậy chúng ta có thể setup xổ số theo chỉ định được ko nhỉ?
 
Upvote 0
sao mình dow mấy file các bác gửi, mở lên file nào cũng báo lỗi "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."
Báo vị trí chỗ mã code bị lỗi, mà mình rành.
Có bác nào biết chĩ giúp mình với.
Mình muốn đưa 1 file audio vào excel 2010 - 64bit. có tạo nút play mà tìm trên mạng hoài chưa ra.
Các bác chỉ giúp mình cái.

Cảm ơn các bác
 
Upvote 0
sao mình dow mấy file các bác gửi, mở lên file nào cũng báo lỗi "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."
Báo vị trí chỗ mã code bị lỗi, mà mình rành.
Có bác nào biết chĩ giúp mình với.
Mình muốn đưa 1 file audio vào excel 2010 - 64bit. có tạo nút play mà tìm trên mạng hoài chưa ra.
Các bác chỉ giúp mình cái.

Cảm ơn các bác

Máy bạn dùng Windows 64-bit, còn hàm API trên dùng cho 32-bit nên bị lỗi là phải rồi, muốn sửa hàm API từ 32-bit sang 64-bit không phải là dễ.
 
Upvote 0
bài bạn mangat06008 hỏi cách nay đã nữa năm(ngày 8 tháng 4 năm 2016), chắc đã có giải pháp hay đã biết cách rồi, anh be09 hãy trả lời của bạn cankiller mới hôm 18/11/2016 kìa.
 
Upvote 0
Web KT
Back
Top Bottom