Chia sẻ cách tạo giao diện cho Form

Liên hệ QC
Mình thấy giao diện Form excel tương đối đơn điệu, qua tìm hiểu về cách tạo form có hình dạng bất kỳ. Hôm nay mình có sưu tầm đoạn code cho file excel có sử dụng hình ảnh bất kỳ để tạo giao diện cho Form, mình chia sẻ để mọi người phát triển nhằm làm phong phú thêm giao diện Form của excel.

220943
 

File đính kèm

  • Form co hinh dang bat ky.xlsm
    794.6 KB · Đọc: 795
Chỉnh sửa lần cuối bởi điều hành viên:
Để giảm bị "lem nhem" mầu trắng thì bạn thử cách sau.

1. Thiết kế ảnh sao cho, nền của anh mà mình muốn Trasparent phải có màu đặc biệt, khác chủ màu của cần hiển thị của anh. Ví dụ object hiển thị không có màu vbBlue thì dùng nền vbBlue
2. Trong code mwor form sửa lại lệnh là
BackColor = vbBlue
MakeUserFormTransparent Me, vbBlue 'make certain color transparent

Ví dụ của mình là màu vbBlue là nền của bức ảnh.
 
Upvote 0
Hay nhỉ, nhanh đó chứ. SetLayeredWindowAttributes, mình quên béng hàm này.
Hồi xưa code mấy cái transparent, hoạt hình trên Win 3x, 9x cực bỏ bu.
Bác @giaiphap sao không dùng cái này làm skin mà dùng cách code skin theo kiểu cũ, GetPixel, SetPixel... trên C/C++ còn chạy chậm bỏ cha.
Hàm này và hàm TransparentBlt sau này mới có từ Win2000
 
Lần chỉnh sửa cuối:
Upvote 0
Để giảm bị "lem nhem" mầu trắng thì bạn thử cách sau.

1. Thiết kế ảnh sao cho, nền của anh mà mình muốn Trasparent phải có màu đặc biệt, khác chủ màu của cần hiển thị của anh. Ví dụ object hiển thị không có màu vbBlue thì dùng nền vbBlue
2. Trong code mwor form sửa lại lệnh là
BackColor = vbBlue
MakeUserFormTransparent Me, vbBlue 'make certain color transparent

Ví dụ của mình là màu vbBlue là nền của bức ảnh.
2 vấn đề này thì em biết và đã thử luôn rồi, màu nền em design bằng Photoshop luôn anh nên màu nền là chính xác luôn, nhưng dùng code không được ngoài trừ màu trắng. Em cũng chấp nhận design lại tất cả các màu trắng trên form trừ màu nền, nhưng không biết sao code lại chạy không chính xác bị "lem nhem" như anh nói.
Bài đã được tự động gộp:

Hay nhỉ, nhanh đó chứ. SetLayeredWindowAttributes, mình quên béng hàm này.
Hồi xưa code mấy cái transparent, hoạt hình trên Win 3x, 9x cực bỏ bu.
Bác @giaiphap sao không dùng cái này làm skin mà dùng cách code skin theo kiểu cũ, GetPixel, SetPixel... trên C/C++ còn chạy chậm bỏ cha.
Hàm này và hàm TransparentBlt sau này mới có từ Win2000
Tôi định xác định màu các pixel sau đó dùng hàm CombineRgn để kết hợp các pixel có màu đó và Transparent nó khỏi Form (Dí nhiên chí tốn công một lần sau đó lưu lại thành List trong file text trước khi gọi Form mình đọc các giá trị trong file Text và sử dụng thôi, lúc này tốc độ sẽ nhanh hơn rất nhiều so với đọc từ pixcel trên Form).
 
Upvote 0
Đẹp quá ạ. Đoạn code nào làm trong suốt userform vậy anh. Nhìn code tùm lum nên em không hiểu mấy ạ.
 
Upvote 0
GetPixel và SetPixel chậm là đúng rồi. Nếu trong Delphi thì ngay Delphi 5 có ScanLine rất nhanh.

Kiểu hoạt hình ABC thì cũng đơn giản. Vd. copy con cá lên màn hình thì cần 2 ảnh: ảnh con cá trên nền đen, ảnh trắng đen - chỗ con cá thì đen, nền trắng. Sau đó dùng 2 BitBlt copy liên tiếp 2 ảnh lên màn hình. Cách này khi animation sẽ hơi nhấp nháy nếu animation con cá "dịch chuyển" (bơi). Loại bỏ nhấp nháy bằng cách: dùng 2 BitBlt copy vào memory device context destDC, sau đó mới 1 BitBlt copy từ destDC vào device context màn hình.

Thay vì con cá có thể là người, xe tăng, cây, viên đạn.

Đấy là ABC chỉ dùng BitBlt. Ngoài ra có DirectX ...

Theo tôi dùng mầu nào cũng được miễn là khác mầu ảnh. Nếu ảnh không có mầu trắng thì dùng mầu trắng làm nền và đường cắt cũng mầu trắng. Lúc này mầu trắng là crKey. Nếu lấy mầu nền, vd. trắng, làm crKey mà nhìn thấy đường viền thì chứng tỏ mầu viền không chính xác 100% bằng mầu nền.
Cái khó là cắt đường viền cho đẹp. Cắt không khéo thì nhì đường viền nhìn lởm chởm, răng cưa không được "mịn".
 
Lần chỉnh sửa cuối:
Upvote 0
GetPixel và SetPixel chậm là đúng rồi. Nếu trong Delphi thì ngay Delphi 5 có ScanLine rất nhanh.

Kiểu hoạt hình ABC thì cũng đơn giản. Vd. copy con cá lên màn hình thì cần 2 ảnh: ảnh con cá trên nền đen, ảnh trắng đen - chỗ con cá thì đen, nền trắng. Sau đó dùng 2 BitBlt copy liên tiếp 2 ảnh lên màn hình. Cách này khi animation sẽ hơi nhấp nháy nếu animation con cá "dịch chuyển" (bơi). Loại bỏ nhấp nháy bằng cách: dùng 2 BitBlt copy vào memory device context destDC, sau đó mới 1 BitBlt copy từ destDC vào device context màn hình.

Thay vì con cá có thể là người, xe tăng, cây, viên đạn.

Đấy là ABC chỉ dùng BitBlt. Ngoài ra có DirectX ...
Anh có thể viết em xem file mẫu được không? Cái phần API em còn gà quá.
Theo tôi dùng mầu nào cũng được miễn là khác mầu ảnh. Nếu ảnh không có mầu trắng thì dùng mầu trắng làm nền và đường cắt cũng mầu trắng. Lúc này mầu trắng là crKey. Nếu lấy mầu nền, vd. trắng, làm crKey mà nhìn thấy đường viền thì chứng tỏ mầu viền không chính xác 100% bằng mầu nền.
Cái khó là cắt đường viền cho đẹp. Cắt không khéo thì nhì đường viền nhìn lởm chởm, răng cưa không được "mịn".
Em thống nhất với anh cái chổ màu đỏ. Khôg biết thế nào, chứ rõ ràng là em chọn vùng và Fill cùng một màu không biết sao nó lại nham nhỡ thế kia.
 
Upvote 0
Anh có thể viết em xem file mẫu được không? Cái phần API em còn gà quá.
Nhưng bạn muốn biết cái gì? Cái con cá?

Nếu là hoạt hình ở mức ABC như tôi nói thì tôi không có đủ kiên nhẫn để soạn 2 tập tin với con cá nhưng nếu coi 1 hình tròn đỏ là con cá thì như tập tin đính kèm.

Nếu là dịch chuyển con cá - hình tròn đỏ thì các bước như sau:
Ảnh là hình tròn nhưng ảnh bao giờ cũng là hình vuông., giả sử có cạnh = a. Mỗi lần dịch là deltaX, deltaY (pixels)
1. Xác định xStart, yStart
2. Đọc device context của màn hình (GetDC). Tạo memory device context source srcDC (CreateCompatibleDC). Tạo bitmap srcBmp(CreateCompatibleBitmap) có dài và cao = a. Chọn srcBmp vào srcDC -> dùng BitBlt copy màn hình có tọa độ từ xStart, yStart và width = a, height = a vào srcDC. Mục đích để cất giữ ảnh nguồn.
3. Copy liên tiếp 2 ảnh con cá vào xStart, yStart như tôi làm trong tập tin đính kèm trong Sub animation (thay cho 200, 200 thì là xStart, yStart). Con cá đã được copy lên màn hình.
4. Sleep một tí.
5. dùng BitBlt copy từ srcDC vào device context của màn hình (GetDC) vào xStart, yStart để trả lại ảnh của màn hình trước khi copy con cá vào.
6. xStart = xStart + deltaX, yStart = yStart + deltaY
7. Trở lại điểm 2.

Tóm lại chẳng qua là copy liên tiếp con cá lên màn hình ở những điểm khác nhau nhưng giữa 2 lần copy phải trả lại vùng màn hình cũ mà con cá trước đã xóa mất. Để có thể trả lại vùng mà con cá sẽ xóa thì trước khi copy vào đâu thì sao chép nó ra srcDC -> copy con cá -> trả lại vùng đã sao chép -> tăng xStart, yStart -> sao chép vùng ở vị trí mới ra srcDC -> copy con cá vào vị trí mới -> trả lại vùng đã sao chép -> tăng xStart, yStart -> ...

Nôm na là thế. Tất nhiên sau mỗi lần thao tác cần giải phóng resource. Nếu trước đó là GetDC (Get - đọc ra, lấy ra, mượn syatem) thì sau đó ReleaseDC (release - giải phóng, trả lại). Nếu là CreateCompatibleDC, CreateCompatibleBitmap (Create - tạo ra) thì sau đó là DeleteDC, DeleteObject (Delete - hủy) v...v

Get - đọc ra, mượn những cái CÓ trong system -> Release - TRẢ LẠI

Create - tự TẠO RA cái mới -> Delete - HỦY cái đã tạo.

Có mượn có trả, có "thêm rác" (chỉ dùng cho mình) vào system thì có "dọn rác" để system trở về trạng thái như cũ.

Cũng có thể thử tạo srcDC và srcBmp một lần thôi.
-------------
Cách vẽ thứ 2 là chỉ copy 1 hình con cá trên nền bất kỳ lên màn hình nhưng giới hạn vùng copy bằng Region. Trong tập tin tôi tạo region bằng CreateEllipticRgn vì con cá hình tròn. Trong thực tế thì từ đường viền con cá phải tạo region bằng CreatePolygonRgn. Nếu hình phức tạp thì tạo các region rồi dùng CombineRgn để tạo region tổng.
Trong ví dụ nhìn thấy chút viền mầu đen do tôi tạo ảnh trong Paint nhưng đường tròn và hình vuông không 100% đồng tâm.
 

File đính kèm

  • animation.rar
    24.9 KB · Đọc: 233
Lần chỉnh sửa cuối:
Upvote 0
Mình thấy thật ra cái này làm cho vui thì đc, chứ thật ra Excel có chức năng đặt mật khẩu nên nếu set pass thì có lẽ là nhanh gọn lẹ hơn. Chỉ là ý kiến cá nhân mong ko bị ăn gạch đá.
 
Upvote 0
Mình thấy thật ra cái này làm cho vui thì đc, chứ thật ra Excel có chức năng đặt mật khẩu nên nếu set pass thì có lẽ là nhanh gọn lẹ hơn. Chỉ là ý kiến cá nhân mong ko bị ăn gạch đá.

Mục đích của việc tạo riêng form đăng nhập là để kiểm soát được user nào đã nhập để từ đó phân quyền ai được xem gì, làm gì. Set password open như bạn nói là excel quản lý cứng.
 
Upvote 0
Mục đích của việc tạo riêng form đăng nhập là để kiểm soát được user nào đã nhập để từ đó phân quyền ai được xem gì, làm gì. Set password open như bạn nói là excel quản lý cứng.
À :D đúng nhỉ, phân quyền này khá hay đó bác. Nhưng thực sự mình cũng chưa nghĩ đến việc Excel có thể phân quyền dc như Software vậy. Nếu đã nhỡ gợi ý rùi bác code thử với
 
Upvote 0
Mục đích của việc tạo riêng form đăng nhập là để kiểm soát được user nào đã nhập để từ đó phân quyền ai được xem gì, làm gì. Set password open như bạn nói là excel quản lý cứng.
Nếu lý do là như vậy thì chưa thỏa đáng lắm anh ạ. Bởi vì nó thật sự phiền hà. Bây giờ nhân viên đăng nhập máy tính bằng mã nhân viên, thì UserName trên máy tính chính là mã nhân viên luôn. Vì vậy, VBA hoàn toàn biết được là ai đang sử dụng macro thông qua username computer, và do đó ô đăng nhập như anh nói là thừa. Anh có nghĩ vậy không, hay là thực tế còn trường hợp nào khác mà em chưa nghĩ tới?
 
Upvote 0
À :D đúng nhỉ, phân quyền này khá hay đó bác. Nhưng thực sự mình cũng chưa nghĩ đến việc Excel có thể phân quyền dc như Software vậy. Nếu đã nhỡ gợi ý rùi bác code thử với

Nếu lý do là như vậy thì chưa thỏa đáng lắm anh ạ. Bởi vì nó thật sự phiền hà. Bây giờ nhân viên đăng nhập máy tính bằng mã nhân viên, thì UserName trên máy tính chính là mã nhân viên luôn. Vì vậy, VBA hoàn toàn biết được là ai đang sử dụng macro thông qua username computer, và do đó ô đăng nhập như anh nói là thừa. Anh có nghĩ vậy không, hay là thực tế còn trường hợp nào khác mà em chưa nghĩ tới?

Các phần mềm mà các bạn thấy như QLNS, Bán hàng, Kế toán, QTSX,.... làm như thế nào thì trên Excel hoàn toàn làm gần giống được như vậy. Mỗi cái có đặc trưng riêng và thế mạnh riêng để từ đó người thiết kế phát huy điểm mạnh từ môi trường phát triển hợp với mục tiêu ứng dụng.
Các chức năng thường được nhiều người lựa chọn để thiết là:
1. Userform đê đăng nhập: lý giải như mình đã đề cập sự cần thiết ở trên. Còn ta dựa vào Account Name khi đăng nhập Windows cũng là một cách giống SQL Server họ làm và có hai cơ chế để người dùng lựa chọn: "Windows Authentication" - dựa vào tài khoản login của Windows và "SQL Server Authentication" - quản trị theo danh mục user riêng. Ví dụ đơn giản nhất là hạn chế ai được xem sheet nào, được sửa, xóa khi nào? Viết code cho ví dụ này không khó và trên GPE cũng đã có rồi.

Windows_Auth.jpg SQL_Server_Auth.jpg

Nếu dựa theo Windows Auth thì khá là cứng ta có quản trị danh mục theo các ý tưởng khác nhau (theo quan điểm và kinh nghiệm cá nhân), còn theo SQL Server Auth hay Userform có hai mục nhập User & Password người thiết kế sẽ quản trị danh mục user và thực hiện các nguyên tắc phân quyền rất chủ động. Đôi khi tài khoản Windows không đổi nhưng tài khoản đăng nhập lại thay đổi hoặc có nhiều hơn cho cùng một máy tính, password có thể thay đổi tức thời khi máy tính văn phòng đôi khi có một vài người dùng ké....

2. Userform phục vụ cho những chức năng tìm kiếm: Ở môi trường Excel tôi thường khuyên các bạn khai thác tối đa Worksheet làm môi trường nhập liệu, nó rất mềm dẻo để vừa nhập liệu cứng tưng ô vừa copy paste và áp dụng công thức, chart,.... Nhưng những trường hợp nhập mã vật tư, khách hàng cần tìm kiếm theo tên, mã số thuế, thì nên cần một Userform nổi lê để tìm và chọn - thay thế Validation List (chỉ có một cột thông tin). Nếu ai từng xem các clip tôi làm sẽ thấy các ví dụ này.

3. Các tình huống giao tiếp người dùng: bình thường người ta có thể dùng MsgBox để giao tiếp nhanh, hỏi đáp, nhưng những trường hợp cần đa dạng hơn, màu sắc, kiểu chữ, kích hoạt vài chức năng gì đó thì Userform cũng là cần thiết.

Các tình huống dùng Userform để làm giao diện nhập liệu kiểu Master-Details (kiểu như phiếu nhập, xuất hàng) thì mình khuyên không nên vì rất vất vả khi phải làm list item kiểu như grid khó mà linh hoạt như Worksheet mà lại quá vất vả và khó khăn trong bảo trì sau này.

Một số bạn chưa biết hết sức mạnh mà Excel có thể làm nên thường mới dùng lại ở khai thác các chức năng và công thức sẵn có. Môi trường lập trình VBA cho phép kết nối với các thư viện của hệ điều hành (API), nhúng DLL ActiveX, ActiveX Control nên làm được rất rất nhiều thứ. Ta hoàn toàn thiết kế các phần mềm trên Excel rất tuyệt với nếu biết ứng dụng linh hoạt những gì nó có. Điểm yếu của Excel là khả năng lưu trữ dữ liệu và không chạy đa luồng (bản thân trong VBA), bị hạn chế bộ nhớ RAM do bị Excel quản lý, làm báo cáo khá vất vả nếu không ứng dụng các add-in mạnh, những điểm yếu này thì phần mềm viết độc lập như Delphi, .NET làm mạnh hơn nhiều nhưng để linh hoạt nếu ai trình không cao cũng không hay đâu. Tóm lại là, ở góc độ viết ứng dụng nhứng trong Excel, quan trọng chúng ta nên xây dựng mô hình vừa nhỏ phù hợp, thiết kế đúng cách ,tận dụng những thế mạnh Excel có, có thể khai thác cùng các add-in hỗ trợ thì ta vẫn có những phần mềm trên Excel tuyệt vời.

Nhân chủ đề này mình góp ý thêm với chủ topic. Userform là cần thiết như mình nói ở trên nhưng thiết kế skin với hình dạng form theo ảnh hay hình bất kỳ sau này gặp nhiều trở ngại lắm. Ở môi trường bình thường thì form nguyên vẹn, nhưng nếu máy tính có màn hình với độ phân giải cao, WIndows 10 trở lên cho phép tùy biến Scale and Layout với các tỷ lệ % khác nhau thì khả năng Form bị vỡ là rất cao. Ngày trước với các Windows cũ hoặc các card đồ họa phân giải thấp thì vấn đề này ít xảy ra. Nên nếu theo mục tiêu tạo form với kiểu skin này sẽ còn gian nan lắm đấy.
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu lý do là như vậy thì chưa thỏa đáng lắm anh ạ. Bởi vì nó thật sự phiền hà. Bây giờ nhân viên đăng nhập máy tính bằng mã nhân viên, thì UserName trên máy tính chính là mã nhân viên luôn. Vì vậy, VBA hoàn toàn biết được là ai đang sử dụng macro thông qua username computer, và do đó ô đăng nhập như anh nói là thừa. Anh có nghĩ vậy không, hay là thực tế còn trường hợp nào khác mà em chưa nghĩ tới?

Bổ sung thêm ý về vụ form Đăng nhập.
Chắc bạn chưa phân phối một ứng dụng nên chưa thấy được các vấn đề liên quan.
Thuờng các ứng dụng sẽ không dùng tài khoản đăng nhập Windows để làm tài khoản đăng nhập ứng dụng.
Lý do:
User đăng nhập Windows do nhân viên IT quản lý máy tính và mạng nội bộ quản lý. Khi đó người quản trị ứng dụng lại phải kết hợp với IT để lấy danh sách tên máy, user từng máy tính trong Cty để đưa vào dữ liệu phần mềm.
Đối với Cty không dùng Domain thì IT phải khoá quyền Administrator để tránh người dùng sửa tên PC, tên User đăng nhập.
Đối với Cty có dùng Domain thì danh sách User có sẳn rồi có thể dùng để đưa vào ứng dụng. Nhưng khi đó thông tin User/pass để vào ứng dụng lại có thêm nhiều người nắm (bộ phận IT) chứ không phải chỉ có người quản trị ứng dụng nắm. Bảo mật ứng dụng sẽ như thế nào.
Còn một trường hợp cũng nguy hiểm không kém là nếu máy PC có cài ứng dụng ERP hay quản lý kế toán. Nhân viên ngồi máy đó đã đăng nhập Domain windows rồi nhưng có việc đi đâu đó, người khác nhảy vô mở ứng dụng kế toán lên, sửa vài con số... Khi đó ứng dụng sẽ lưu vào Log file là User của máy PC đó đã sửa nhưng thực ra có phải người ngồi máy đó sửa đâu, truy cứu trách nhiệm ra sao?
Một trường hợp khác mà tôi đã nói là ứng dụng cũng không nên dùng User/Pass của Domain vì khi IT thực hiện đổi pass của một user nào đó lại phải thông báo cho quản trị ứng dụng cập nhật lại danh sách User/pass trong hệ thống ứng dụng -> lại phát sinh chi phí cho bên ứng dụng chỉ vì một thay đổi bảo mật bên IT nội bộ.
Một trường hợp khác là ứng dụng dùng qua internet thì lấy đâu ra User windows mà quản lý? (Trường hợp Cty không dùng VPN)

Do đó tốt nhất là ứng dụng sẽ có danh sách User/Pass riêng của ứng dụng.
- Khi cài trên bất cứ máy PC nào, và bất kỳ User nào cũng có thể ngồi trên một máy PC để thao tác nhập liệu với tài khoản do ứng dụng cung cấp. Khi đó ứng dụng chỉ quản lý trên tên User đăng nhập ứng dụng chứ không cần biết từ máy PC. Tất nhiên về bảo mật thì ứng dụng sẽ lưu vào file Log các thông tin như: User đăng nhập, ngày/giờ vào/ thoát, tên PC đang thao tác v.v...
- Người quản trị ứng dụng không cần phải liên hệ, chia sẻ thông tin với IT trong các vấn đề User/pass.
 
Lần chỉnh sửa cuối:
Upvote 0
Có một chi tiết này bạn làm hy vọng sẽ tốt hơn. ẢNh lưu về dạng Bitmap 24-bit. Dùng phần mềm Paint của Windows, dùng lệnh Fill Color với màu nền làm transparent, nếu phủ hết thì đạt yêu cầu, nếu còn vài vết loang thì chỉnh thủ công.
 
Upvote 0
Web KT
Back
Top Bottom