có thể tạo Userform vừa khít với các loại màn hình (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

NguyenthiH

Thành viên mới đăng ký
Tham gia
11/12/16
Bài viết
965
Được thích
175
Giới tính
Nữ
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.
 
Bạn xem thử khổng biết có phải ý của bạn vầy không?
 

File đính kèm

Upvote 0
cám ơn Anh Giaiphap, nhưng khi Form hiện che luôn Taskbar Anh ơi.
 
Upvote 0
Được rồi Anh giaiphap ơi, nhưng các TextBox và ListBox trên Form nó không can đối theo Form, nó lệch về bên trái, có code nào làm nó can đối theo Form luôn không Anh?
 
Upvote 0
Được rồi Anh giaiphap ơi, nhưng các TextBox và ListBox trên Form nó không can đối theo Form, nó lệch về bên trái, có code nào làm nó can đối theo Form luôn không Anh?
Bạn muốn thế nào thì đưa file lên đây, chứ giúp bạn xong bạn lại không biết áp dụng vào file của bạn nửa thì mất công quá. Do code dài và nhiều.
 
Upvote 0
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.
Thử vầy xem:
Mã:
Private Sub UserForm_Initialize()
  Application.WindowState = xlMaximized
  Me.Top = 0
  Me.Left = 0
  Me.Height = Application.Height
  Me.Width = Application.Width
End Sub
Hên xui
 
Upvote 0
Được rồi Anh giaiphap ơi, nhưng các TextBox và ListBox trên Form nó không can đối theo Form, nó lệch về bên trái, có code nào làm nó can đối theo Form luôn không Anh?

Thì thử code này:

Mã:
Private Sub UserForm_Initialize()
With Application
  .WindowState = xlMaximized
  Zoom = Int(.Width / Me.Width * 100)
  Width = .Width
  Height = .Height
   End With
End Sub

Tùy theo loại màn hình mà độ phân giải có khác nhau, vì vậy có thể thay đổi số 100 thành 90 hoặc 85, nó tự thay đổi các Control trên Form cho phù hợp.
 
Upvote 0
Được rồi Anh giaiphap ơi, nhưng các TextBox và ListBox trên Form nó không can đối theo Form, nó lệch về bên trái, có code nào làm nó can đối theo Form luôn không Anh?
Cái vụ "cân đối" này hơi khó nha! Thử kiểu này xem:
Mã:
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
    (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
    (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Const GWL_STYLE = (-16)
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_SIZEBOX = &H40000

Dim hWnd As Long, uStyle As Long, OldWidth As Double
Private Sub UserForm_Initialize()
  OldWidth = Me.Width
  hWnd = FindWindow("ThunderDFrame", Me.Caption)
  uStyle = GetWindowLong(hWnd, GWL_STYLE)
  SetWindowLong hWnd, GWL_STYLE, uStyle + WS_SIZEBOX + WS_MINIMIZEBOX + WS_MAXIMIZEBOX
  With Application
    .WindowState = xlMaximized
    Me.Left = .Left: Me.Top = .Top
    Me.Width = .Width: Me.Height = .Height
  End With
End Sub
Private Sub UserForm_Terminate()
  SetWindowLong hWnd, GWL_STYLE, uStyle
End Sub
Private Sub UserForm_Resize()
  Dim lW As Long
  lW = Round(Width / OldWidth * 100, 0)
  If lW > 400 Then lW = 400
  Zoom = lW
End Sub
 
Upvote 0
Em cám ơn Anh Giaiphap, Thầy Ndu, Anh Be09.
Em lấy code của anh Be09 thì ListBox1 bị mất phần dưới, mong các Anh và Thầy Ndu xem giúp.
Em xin gửi file đính kèm.
 

File đính kèm

Upvote 0
Em đưa File lên thì mới thấy code mới của Thầy Ndu, để em thử code của Thầy.
 
Upvote 0
Code mới của Thầy Ndu cũng bị mất phần dưới của ListBox, nhưng có cái hay là có nút Minimize, Maximize.
Mong Thầy Ndu xem giúp.
 
Upvote 0
Code mới của Thầy Ndu cũng bị mất phần dưới của ListBox
Đó là do bạn thiết kế không cân đối chứ không phải tại code
Đã gọi là "cân đối" thì phải làm đều hết tất cả các đối tượng bạn à
Tóm lại: Bạn tự mình thiết kế lại, đến khi nào thấy "vừa khít" thì thôi
nhưng có cái hay là có nút Minimize, Maximize.
.
Vì Zoom lên Maximun, hổng có 2 nút đó thì lấy gì phục hồi nguyên trạng, đúng không?
 
Upvote 0
Tức phải giảm chiều cao của ListBox hả Thầy Ndu???
 
Upvote 0
Tức phải giảm chiều cao của ListBox hả Thầy Ndu???
Thì cứ làm "tùm lum" đi, hồi tự dưng nó.. trúng thôi
Nói đơn giản thì: Bạn cứ tưởng tượng đang thiết kế 1 cái form to bằng màn hình, vậy bạn cứ làm cho mọi controls trở nên cân đối theo kích thước to to ấy đi (giảm chỗ này, tăng chỗ kia... đến khi vừa ý thì thôi)
 
Upvote 0
nãy giờ em cứ giảm chiều cao của ListBox rồi giảm chiều cao của Form rồi cũng được rồi Thầy Ndu ơi, nhưng cứ làm "tùm lum" như vậy "Mỏi tay lắm" và "Không Chuyên".
Vậy Thầy có cách nào cho nhanh giúp em với.
Em xin đưa File Thầy xem giúp.
 

File đính kèm

Upvote 0
nãy giờ em cứ giảm chiều cao của ListBox rồi giảm chiều cao của Form rồi cũng được rồi Thầy Ndu ơi, nhưng cứ làm "tùm lum" như vậy "Mỏi tay lắm" và "Không Chuyên".
Vậy Thầy có cách nào cho nhanh giúp em với.
Em xin đưa File Thầy xem giúp.
Thế em làm mỏi tay chắc thầy Ndu làm không mỏi tay à.
 
Upvote 0
Ý em là phải có cách nào để lập trình cho nó "Cân Đối", chứ đâu phải làm bằng tay (thủ công) kéo vào kéo ra cho vừa.
 
Upvote 0
Ý em là phải có cách nào để lập trình cho nó "Cân Đối", chứ đâu phải làm bằng tay (thủ công) kéo vào kéo ra cho vừa.
Hiệu chỉnh lần cuối:
Mã:
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
    (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
    (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare PtrSafe Function ShowWindow Lib "user32" _
    (ByVal hWnd As LongPtr, ByVal nCmdShow As Long) As Long


Private Const GWL_STYLE = (-16)
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_MINIMIZEBOX = &H20000
Private Const SW_MAXIMIZE = 3
Private Const WS_SIZEBOX = &H40000

Dim hWnd As LongPtr, uStyle As Long, OldWidth As Double, OldHeight As Double
Private Sub UserForm_Initialize()
  OldWidth = Me.Width: OldHeight = Me.Height
  hWnd = FindWindow("ThunderDFrame", Me.Caption)
  uStyle = GetWindowLong(hWnd, GWL_STYLE)
  SetWindowLong hWnd, GWL_STYLE, uStyle + WS_SIZEBOX + WS_MINIMIZEBOX + WS_MAXIMIZEBOX
End Sub
Private Sub UserForm_Activate()
  ShowWindow hWnd, SW_MAXIMIZE
End Sub
Private Sub UserForm_Terminate()
  SetWindowLong hWnd, GWL_STYLE, uStyle
End Sub
Private Sub UserForm_Resize()
  Dim lW As Long, lH As Long, lngZoom As Long
  lW = Round(Me.Width / OldWidth * 100, 0)
  lH = Round(Me.Height / OldHeight * 100, 0)
  lngZoom = IIf(lW > lH, lH, lW)
  If lngZoom > 400 Then lngZoom = 400
  If lngZoom < 10 Then lngZoom = 10
  Zoom = lngZoom
End Sub
Nếu không được nữa thì tôi.. thua
Được cái này sẽ mất cái kia. Mình thiết kế không cân xứng mà cứ bắt code nó phải chỉnh lại cho "cân" thì đúng là chuyện không thể nào. Mọi thứ chỉ có thể ở mức tương đối mà thôi
----------------------------------------------
Ah... mình mới phát hiện có sai sót. Hồi nảy có chỗ minh ghi Application.WidthApplication.Height là sai hoàn toàn. Vừa mới sửa lại thành Me.WidthMe.Height
Các bạn lưu ý chỗ này nhé! Với code cũ sau khi zoom toàn màn hình xong rồi phục hồi trở lại thì các controls sẽ không tự resize tương ứng
 
Lần chỉnh sửa cuối:
Upvote 0
Em đưa File lên thì mới thấy code mới của Thầy Ndu, để em thử code của Thầy.
Ý em là phải có cách nào để lập trình cho nó "Cân Đối", chứ đâu phải làm bằng tay (thủ công) kéo vào kéo ra cho vừa.
Code cũng có thể làm được cái bạn nêu, nhưng học hành bài bản thì mới nên nghĩ đến chuyện này (thuộc dạng chuyên nghiệp).
Còn tay ngang học mò trong Help và trên diễn đàn này, làm được cái Form để sử dụng tạm được thì đã là điều đáng mừng rồi, chứ đừng nghĩ đến những cái cao siêu quá như vậy (chỉ làm đẹp thôi không có hiệu quả gì hết).
 
Upvote 0
Code hiệu chỉnh lần cuối của Thầy Ndu vẫn chưa can đối (Book2)
và Code của Thầy Tuân và của Thầy Ndu em sưu tầm trên DD (Book1) được can đối.
 

File đính kèm

Upvote 0
Code hiệu chỉnh lần cuối của Thầy Ndu vẫn chưa can đối (Book2)
và Code của Thầy Tuân và của Thầy Ndu em sưu tầm trên DD (Book1) được can đố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...)
 
Upvote 0
Code của Thầy Tuân và của Thầy Ndu em sưu tầm trên DD (Book1) được can đối.
Cũng không chuẩn.
1. Trong UserForm_Initialize sau dòng SetWindowLong thêm
Mã:
ReDim arr(1 To 60, 1 To 1)
    For k = 1 To 60
        arr(k, 1) = "hic hic " & k
    Next
    ListBox1.List = arr
Mở Form và cuộn ListBox1 xuống cuối. Bạn không nhìn thấy mục cuối cùng - mục "hic hic 60" bị che.

2. Không phải lúc nào ListBox cũng "với" tới tận cạnh dưới của Form. Có những th ở dưới ListBox còn nhiều thứ.
Kiểu cố tình kéo ListBox tới tận cạnh dưới của Form là vô lý.
Mã:
 ''Thuat toan nam tai day!
    With ListBox1
        .Height = Me.InsideHeight - .Top - 6
    End With
Thuật toán gì? Nếu dưới ListBox người ta có những thứ khác thì vẫn cứ kéo ListBox xuống dưới cùng?

Bạn hãy sửa Height của ListBox1 thành 220 rồi mở Form xem có chuẩn không nhé
 
Upvote 0
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 đó.
 
Upvote 0
Bạn có thể xem ví dụ cùng mã nguồn tôi làm về zoom userform tại đây:
zoomform.gif

File nguồn:
http://bluesofts.net/phong-to-va-thu-nho-userform-va-controls-trong-excel-vba.html
 
Upvote 0
Bạn có thể xem ví dụ cùng mã nguồn tôi làm về zoom userform tại đây:
Tôi e rằng cái này không đúng theo ước muốn của chủ đề tài.
Ta thêm 1 ListBox2 nữa "vươn" tới cạnh dưới của Form.
1. Khi mở Form thì nó ở dạng max và TextBox2, ToggleButton1 và cmdClose bị cụt bên phải.
2. Nếu click max button để về kích thước thiết kế rồi "nắm" góc dưới bên phải di chuyển thì a. Nếu kéo sang bên phải mở rộng Form thì đến lúc ListBox2 và cmdClose bị cụt ở dưới.
b. Nếu kéo xuống để tăng chiều cao của Form thì ListBox2, Label3 và Label4 càng ngày càng xa cạnh dưới của Form, xuất hiện khoảng trống càng ngày càng lớn dưới 3 control này.
c. Nếu kéo lên để giảm chiều cao của Form thì ListBox2, Label3, cmdClose và Label4 càng ngày càng cụt đi

v...v

Ước muốn của chủ đề tài là giãn ra co vào luôn cân đối.
 
Upvote 0
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.
 
Upvote 0
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 đề.
 
Upvote 0
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...)

Kinh nghiệm:
Code nên tạo cho người dùng 1 cửa hậu. Bấm mọt tổ hợp phím nào đó thì form sẽ trở về vị trí/kích cỡ mặc định.
 
Upvote 0
Kinh nghiệm:
Code nên tạo cho người dùng 1 cửa hậu. Bấm mọt tổ hợp phím nào đó thì form sẽ trở về vị trí/kích cỡ mặc định.
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)
 
Upvote 0
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.
 
Lần chỉnh sửa cuối:
Upvote 0
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
 
Upvote 0
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.
 
Upvote 0
Bạn phải có kiến thức abc tối thiểu và biết suy nghĩ chứ không chỉ tập copy/paste.
Bạn muốn khai báo ở Module cũng được nhưng với DIM kia thì chắc chắn code trong Form không thể truy cập tới các biến kia. Vậy tùy bạn.
 
Upvote 0
Em đã thử khai báo biến (1) vào Userform_Initialize nhưng code chạy lỗi ngay chổ
"WS_MINIMIZEBOX" nên em mới hỏi khai báo vào đâu?
Mong Thầy chỉ rỏ.
 
Upvote 0
Em đã thử khai báo biến (1) vào Userform_Initialize nhưng code chạy lỗi ngay chổ
"WS_MINIMIZEBOX" nên em mới hỏi khai báo vào đâu?
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ó
Option Explicit

Private Const GWL_STYLE = (-16)
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_THICKFRAME = &H40000
Thứ nữa là bạn hãy nhìn xem trong những biến mà tôi đề nghị khai báo có biến nào tên là WS_MINIMIZEBOX không. Rõ ràng là không.

WS_MINIMIZEBOX là hằng số của Tuân (của Windows), nhưng tôi có đả động gì tới WS_MINIMIZEBOX đâu?

Trong bài tôi ghi rất rõ, thêm cái gì, thay cái gì của Tuân bằng cái mới.

Tôi cố tình không nói để bạn tự đọc kỹ và động não. Không thì suốt đời bạn chỉ đi hỏi mà không học thêm được cái gì.
 
Upvote 0
Xin lỗi Thầy!
Em lấy File của em, nên bị lỗi.
 
Lần chỉnh sửa cuối:
Upvote 0
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.
 

File đính kèm

Upvote 0
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.
Đúng là quên. Chính vì làm chuẩn mất thời gian vì nếu không nghĩ kỹ thì dễ quên nhiều vấn đề.

Tôi thường bỏ công để viết rõ ràng nhưng nếu bạn lại không chịu đọc kỹ như lần trước thì bạn tự tìm hiểu. Lần này tôi sẽ không trả lời. Không thể "thời gian của người khác thì không tiếc".

Bạn hãy đọc kỹ những điểm sau:

0. Tôi vẫn cứ lấy tập tin của Tuân làm căn cứ. Bạn tự chuyển code sang tập tin của mình.

1. Để làm thật khít, thật chuẩn 100% là chuyện khó, mất công. Mà tôi không muốn mất thời gian về chuyện này. Và chắc chả ai rỗi hơi cả. Vậy nếu bạn rất cần thì đặt hàng để ai đó làm cho. Lúc này thì khác, vì khách hàng là thượng đế mà. Anh muốn rực rỡ, vô bổ cũng có người làm. Càng nhiều rực rỡ thì việc càng nhiều, tiền công càng cao, ai mà chả thích làm ra càng nhiều tiền, đúng không?

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
 
Upvote 0
Mong Thầy Batman1 làm giúp cho em trên File của em, vì em lấy code của Thầy chuyển sang file của em thì khi nạp dữ lieu vào ListBox vẫn chưa can đối.
Sao bây giờ em gửi File đính kèm không được.
 
Lần chỉnh sửa cuối:
Upvote 0
vì em lấy code của Thầy chuyển sang file của em thì khi nạp dữ lieu vào ListBox vẫn chưa can đối.
Tôi đề nghì sửa vài chỗ:
1. Trong Sub ghilistbox1 bạn mới có
Mã:
With ListBox1
    .ColumnCount = 5
    .ColumnWidths = "20;240;110;120;70"
...
End With
a. Như thế trong Sub UserForm_Initialize trong code sau
Mã:
For Each c In Controls
        If TypeName(c) = "ListBox" Or TypeName(c) = "ComboBox" Then
            If c.ColumnWidths = "" Then
....
thì ListBox1.ColumnWidths = ""

b. Chả lí gì lại làm nhiều lần mỗi khi gọi Sub ghilistbox1 một việc chỉ cần làm 1 lần. Vì vậy xóa 2 dòng trong Sub ghilistbox1
Mã:
 .ColumnCount = 5
.ColumnWidths = "20;240;110;120;70"
Và hoặc là nhập trong cửa sổ thiết kế Properties hoặc trong Sub UserForm_Initialize trước dòng For Each c In Controls phải thêm code
Mã:
With ListBox1
        .ColumnCount = 5
        .ColumnWidths = "20;240;110;120;70"
End With
Bạn chịu khó suy nghĩ chút nhé. Suy nghĩ không đau đâu. Nếu trong code có kiểm tra ColumnWidths (If c.ColumnWidths = "" Then) thì ColumnWidths phải nhập trước khi kiểm tra. Phải kiểm tra ColumnWidths vì mặc định thì ListBox, ComboBox chỉ có 1 cột và ColumnWidths = ""

Nhưng trong trường hợp này thì còn một chuyện khác thú vị hơn. Giả sử Form đang max, tức code đã vào cuộc và phóng to ColumnWidths. Bây giờ bạn nhập dữ liệu và khi bạn nhấn Enter ở TextBox cuối cùng thì Sub ghilistbox1 được thực hiện. Mà nó lại chuyển ColumnWidths về mặc định thì rõ ràng là công code phóng to ColumnWidths đổ xuống sông xuống biển rồi còn gì. Các cột co lại là do chính bạn chuyển về mặc định thì sao bạn lại phàn nàn??? Bạn chưa thạo viết code nhưng bạn không thể viện lý do là không biết suy nghĩ.

2. Nhân tiện sửa Sub CalcColWidths thành
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), ";")
    s = ""
    For k = LBound(cSize) To UBound(cSize)
        s = s & Int(cSize(k) * zoomX) & " pt;"
    Next k
    c.ColumnWidths = Left(s, Len(s) - 1)
End Sub
 
Upvote 0
Cám ơn Thầy Batman1!
Quá chuẩn rồi Thầy Ơi!
Chúc Thầy Ngày Vui!
 
Upvote 0
Đúng là quên. Chính vì làm chuẩn mất thời gian vì nếu không nghĩ kỹ thì dễ quên nhiều vấn đề.

Tôi thường bỏ công để viết rõ ràng nhưng nếu bạn lại không chịu đọc kỹ như lần trước thì bạn tự tìm hiểu. Lần này tôi sẽ không trả lời. Không thể "thời gian của người khác thì không tiếc".

Bạn hãy đọc kỹ những điểm sau:

0. Tôi vẫn cứ lấy tập tin của Tuân làm căn cứ. Bạn tự chuyển code sang tập tin của mình.

1. Để làm thật khít, thật chuẩn 100% là chuyện khó, mất công. Mà tôi không muốn mất thời gian về chuyện này. Và chắc chả ai rỗi hơi cả. Vậy nếu bạn rất cần thì đặt hàng để ai đó làm cho. Lúc này thì khác, vì khách hàng là thượng đế mà. Anh muốn rực rỡ, vô bổ cũng có người làm. Càng nhiều rực rỡ thì việc càng nhiều, tiền công càng cao, ai mà chả thích làm ra càng nhiều tiền, đúng không?

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
Bạn ơi liệu VBA có phóng to một trang web được không bạn nhỉ?
Có cách nào để dùng VBA điều chỉnh kích thước cửa số của một ứng dụng khác ( Chorme chẳng hạn ) ?
 
Upvote 0
Bạn ơi liệu VBA có phóng to một trang web được không bạn nhỉ?
Có cách nào để dùng VBA điều chỉnh kích thước cửa số của một ứng dụng khác ( Chorme chẳng hạn ) ?
Bạn hỏi tôi làm gì? Vấn đề của bạn khác thì lập chủ đề mới mà hỏi, sao lại vào chủ đề khác? Lúc ấy ai thích thì trả lời.
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom