Chào mọi người!
Em hay tạo Userform để nhập liệu, khi tạo em chỉnh kích thước cho vừa với màn hình 14 Inch của Laptop nhà, nhưng khi mang File đó lên làm ở máy công ty thì mở Form lên lại không vừa với màn hình của máy công ty.
Vậy có code nào chỉnh cho Userform luôn vừa với mọi loại màn hình được không ah!
Em cám ơn mọi người.
Code Book1 là cố tình chỉnh riêng ListBox cho nó khớp màn hình hiện tại. Vậy đặt trường hợp có nhiều controls "bị bệnh" như thế thì bạn tính sao?
Controls nào "bị bệnh" làm sao bạn biết trước được? Bởi nó còn tùy thuộc vào kích thước từng màn hình (laptop khác, desktop khác...)
Tới Thầy Ndu:
Code của Thầy vẫn chưa cân đối (Lệch vế bên trái)
Tới Thầy Batman1:
Em đã chỉnh Height của ListBox1 bằng 220, nhưng Form vẫn chưa chuẩn (ListBox1 đụng tới TaskBar luôn, không thấy phấn dưới của Form). còn code kéo listBox là của Anh Hoang Trong Nghĩa đó.
Tới Thầy Tuân:
Cám ơn Thầy, nhưng File của Thầy không đúng ý của em.
Tới Thầy Ndu:
File của Thầy ở bài #25 em cũng phải kéo ListBox1 lên thì mới vừa khít.
******* Vậy là không có code nào làm cho Form và các control trên Form khi hiện ra là vừa khít với mọi loại màn hình (Tất nhiên là các Control trên Form cũng can đối theo Form)
Còn nếu dung code để kéo ListBox ra cho vừa thì lại mất dữ lieu dòng cuối trên ListBox.
Chỉ có cách là kéo bang tay(Thủ công) cho các control vừa khít thì thôi.
Tới Thầy Tuân:
Cám ơn Thầy, nhưng File của Thầy không đúng ý của em.
Tới Thầy Ndu:
File của Thầy ở bài #25 em cũng phải kéo ListBox1 lên thì mới vừa khít.
******* Vậy là không có code nào làm cho Form và các control trên Form khi hiện ra là vừa khít với mọi loại màn hình (Tất nhiên là các Control trên Form cũng can đối theo Form)
Còn nếu dung code để kéo ListBox ra cho vừa thì lại mất dữ lieu dòng cuối trên ListBox.
Chỉ có cách là kéo bang tay(Thủ công) cho các control vừa khít thì thôi.
Muốn giải quyết vấn đề của bạn phải có một phần mềm chuyên tạo hệ thống vận hành và màn hình ảo. Phần mềm này cho phép tự tạo tất cả các loại và kích cỡ màn hình. Từ chỗ này, ta có thể trích lọc ra những thông số của các tổ hợp hệ thống & cửa sổ & màn hình khác nhau và từ đó hiệu chỉnh cỡ Form cùng các controls của nó. Néu số tổ hợp lên tới vài ngàn thì bắt buọc phải lập mọt bảng tra. Trăm thứ rắc rối.
Đại khái, để đỡ mỏi tay, bạn có thể phải chấp nhận cái size của mỗi file phải tăng lên vài MB; mỗi lần mở file, VBA phải lục lọi thông số; mỗi lần có gì mới, bạn phải update bảng tra, vv...
Bạn nên nhớ rằng co những ngừoi dùng nhiều màn hình. Nếu code hoàn chỉnh thì phải khắc phục được trường hợp ngừoi ta kéo app từ màn hình này sang màn hình khác.
Để hiểu rõ hơn toi nói gì, bạn có thể vào các nơi dùng mã nguồn mở (như Ubuntu chẳng hạn) xem thử code họ viết 1 cái driver nào đó và lấy khái niệm về sự phức tạp của vấn đề.
Code Book1 là cố tình chỉnh riêng ListBox cho nó khớp màn hình hiện tại. Vậy đặt trường hợp có nhiều controls "bị bệnh" như thế thì bạn tính sao?
Controls nào "bị bệnh" làm sao bạn biết trước được? Bởi nó còn tùy thuộc vào kích thước từng màn hình (laptop khác, desktop khác...)
Chính vậy mà mình cố tình thiết kế UserForm với 3 nút: Max, Min, Close... để nếu sau khi phóng to mà thấy không vừa ý thì bấm nút giữa phục hồi
Hồi trước mình cũng từng nghien cứu vụ phóng to này nhưng sau đó.. nản, bởi có khi form chạy ngon trên mấy mình mà sang máy khác lại.. méo xẹo... Ghét bỏ luôn hổng thèm nghiên cứu nữa (dù sao cũng chỉ là làm màu, có cũng tốt mà không có cũng không chết Tây nào)
Chính vậy mà mình cố tình thiết kế UserForm với 3 nút: Max, Min, Close... để nếu sau khi phóng to mà thấy không vừa ý thì bấm nút giữa phục hồi
Hồi trước mình cũng từng nghien cứu vụ phóng to này nhưng sau đó.. nản, bởi có khi form chạy ngon trên mấy mình mà sang máy khác lại.. méo xẹo... Ghét bỏ luôn hổng thèm nghiên cứu nữa (dù sao cũng chỉ là làm màu, có cũng tốt mà không có cũng không chết Tây nào)
Nói chung giao nhiệm vụ theo dõi cho người nào thì sử dụng máy của người đó và chỉ tốn công sửa Form 1 lần (vậy là xong nhiệm vụ), còn muốn code thì phải dựa vào độ phân giải màn hình của từng loại máy tính sẽ phức tạp ra mà không có tác dụng gì nhiều.
Việc cân đối 100% là rất là khó. Ngay cả khi bạn chả zoom gì, chả phủ kín màn hình mà kích thước ListBox đã thay đổi. Bạn thử như sau:
1. Trong tập tin của Tuân bạn xóa code UserForm_Resize
2. Các sub còn lại thay bằng
Mã:
Private Sub UserForm_Activate()
Debug.Print ListBox1.Height
End Sub
Private Sub UserForm_Initialize()
Dim Arr(1 To 60, 1 To 1)
Debug.Print ListBox1.Height
For k = 1 To 60
Arr(k, 1) = "hic hic " & k
Next
ListBox1.List = Arr
End Sub
Bạn sẽ thấy trong UserForm_Initialize ListBox1.Height = 87,75 = kích thước thiết kế trong cửa sổ Properties. Nhưng ở Activate ListBox1.Height = 81. Tức cho dù bạn thiết kế trong cửa sổ Properties "khít" thì khi hiện Form (sau khi nhập các mục vào ListBox1) ListBox1 sẽ ngắn đi 6,75 [points], tức sẽ "lòi" ra khoảng trống ở dưới = 6,75 [points]
---------
Tôi thử một cách khác, có chuẩn không thì bạn tự kiểm tra, vì tôi ngại test lắm. Chỉ mới test cho các controls trong tập tin của Tuân. Được hay không thì tôi cũng không quan tâm nữa. Chuyện hoa hòe hoa sói tôi không ham.
1. Trong tập tin của Tuân bạn thêm khai báo (nếu biến đã có thì thôi)
Mã:
Dim hwnd As Long, wStyle As Long, OldWidth As Double, OldHeight As Double, OldInsideWidth As Double, OldInsideHeight As Double, lastScaleX As Double, lastScaleY As Double
2. Thay 2 sub UserForm_Initialize và UserForm_Resize bằng 2 sub mới
Mã:
Private Sub UserForm_Initialize()
Dim c As MSForms.Control, Arr()
OldWidth = Width
OldHeight = Height
OldInsideWidth = InsideWidth
OldInsideHeight = InsideHeight
lastScaleX = 1
lastScaleY = 1
For Each c In Controls
If TypeName(c) = "ListBox" Then c.Tag = c.Height
Next c
If Val(Application.Version) < 9 Then
hwnd = FindWindow("ThunderXFrame", Caption) 'XL97
Else
hwnd = FindWindow("ThunderDFrame", Caption) 'XL2000
End If
wStyle = GetWindowLong(hwnd, GWL_STYLE)
SetWindowLong hwnd, GWL_STYLE, wStyle Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX ' Or WS_THICKFRAME
ReDim arr(1 To 60, 1 To 1)
For k = 1 To 60
arr(k, 1) = "hic hic " & k
Next
ListBox1.List = arr
End Sub
Private Sub UserForm_Resize()
ScaleFormControls
End Sub
3. Thêm
Mã:
Private Sub ScaleFormControls()
Dim scaleX As Double, scaleY As Double, x As Double, y As Double, c As MSForms.Control
scaleX = InsideWidth / OldInsideWidth
scaleY = InsideHeight / OldInsideHeight
x = scaleX / lastScaleX
y = scaleY / lastScaleY
For Each c In Controls
c.Left = c.Left * x
c.Top = c.Top * y
c.Width = c.Width * x
If TypeName(c) = "ListBox" Then
c.Height = c.Tag * scaleY
Else
c.Height = c.Height * y
End If
On Error Resume Next
c.Font.Size = c.Font.Size * y
On Error GoTo 0
Next c
lastScaleX = scaleX
lastScaleY = scaleY
End Sub
4. Hiện tại chỉ có 2 trạng thái: max khít màn hình và kích thước thiết kế. Nếu bạn muốn test kéo ra kéo vào thì bỏ dấu nháy trước Or WS_THICKFRAME.
Tất nhiên thu nhỏ thì cũng chỉ nên tới lúc vẫn còn nhìn được chữ trên các Label, ListBox v...v Để khi thu nhỏ phóng to vẫn có thể về lại kích thước thiết kế thì thêm
Mã:
Private Sub UserForm_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Width = OldWidth
Height = OldHeight
End Sub
Khi muốn về lại kích thước thiết kế thì click đúp vào chỗ trống trên Form
Cám ơn Thầy Batman1, Chổ khai báo biến (1) thêm vào Module hay trong Form.
Vì em không biết thêm vào chổ nào nên em không Test được.
Mong Thầy chỉ cho.
Các biến của tôi thì liên quan gì tới WS_MINIMIZEBOX?
Thứ nhất là tôi không tin. Vì trong tập tin của Tuân (tôi ghi rất rõ: Trong tập tin của Tuân bạn thêm khai báo) trong UserForm1 ngay trên đầu có
Chào Thầy Batman1!
Code của Thầy đã chuẩn, nhưng khi Form bung toàn màn hình và các Control giãn ra cân đối theo Form, nhưng ColumWidth của các cột trong ListBox không giãn ra theo, nên khi nhập dữ liệu đập ListBox thì lại không cân đối.
Em xin đưa File Thầy xem giúp.
Trong File nhấn mặt cười sẽ hiện Form, gỏ đại các ký tự vào các TextBox: Tên hàng hóa, DVT, Số Lượng, Thành Tiền rồi Enter thì thấy dữ liệu nạp vào ListBox không cân đối.
Mong Thầy xem giúp.
nhưng khi Form bung toàn màn hình và các Control giãn ra cân đối theo Form, nhưng ColumWidth của các cột trong ListBox không giãn ra theo, nên khi nhập dữ liệu đập ListBox thì lại không cân đối.
2. Bạn hãy test lần nữa và cho kết quả test để mọi người biết. Lúc đó có thể có người khác giúp bạn - bằng cách khác hoặc làm chuẩn hơn. Riêng tôi không muốn làm nữa.
3. Trong UserForm_Initialize thay
Mã:
For Each c In Controls
If TypeName(c) = "ListBox" Then c.Tag = c.height
Next c
bằng
Mã:
For Each c In Controls
If TypeName(c) = "ListBox" Or TypeName(c) = "ComboBox" Then
If c.ColumnWidths = "" Then
c.Tag = String(c.ColumnCount, "a")
c.Tag = Replace(c.Tag, "a", (c.Width - 13) / c.ColumnCount & " pt;") & c.height
Else
c.Tag = c.ColumnWidths & ";" & c.height
End If
End If
Next c
4. Trong code của UserForm1 thêm code
Mã:
Private Sub CalcColWidths(ByVal c As MSForms.Control, ByVal zoomX As Double)
Dim k As Long, s As String, cSize
If c.ColumnCount = 1 Then Exit Sub
s = Replace(c.Tag, " pt", "")
cSize = Split(Left(s, InStrRev(s, ";") - 1), ";")
For k = LBound(cSize) To UBound(cSize)
cSize(k) = cSize(k) * zoomX
Next k
c.ColumnWidths = Join(cSize, " pt;") & " pt"
End Sub
5. Thay Sub ScaleFormControls bằng sub mới
Mã:
Private Sub ScaleFormControls()
Dim scaleX As Double, scaleY As Double, x As Double, y As Double, cSize, c As MSForms.Control
scaleX = InsideWidth / OldInsideWidth
scaleY = InsideHeight / OldInsideHeight
x = scaleX / lastScaleX
y = scaleY / lastScaleY
For Each c In Controls
c.Left = c.Left * x
c.Top = c.Top * y
c.Width = c.Width * x
If TypeName(c) = "ListBox" Then
cSize = Split(c.Tag, ";")
c.height = cSize(UBound(cSize)) * scaleY
Else
c.height = c.height * y
End If
' goi CalcColWidths sau khi xac dinh Height cua ListBox
If TypeName(c) = "ListBox" Or TypeName(c) = "ComboBox" Then
CalcColWidths c, scaleX
End If
On Error Resume Next
c.Font.Size = c.Font.Size * y
On Error GoTo 0
Next c
lastScaleX = scaleX
lastScaleY = scaleY
End Sub