Các câu hỏi về Form trong Excel VBA

Liên hệ QC

Tường_Vi

Thành viên tiêu biểu
Tham gia
19/4/10
Bài viết
482
Được thích
121
Nghề nghiệp
Luôn tìm kiếm một vị trí tốt hơn
Private Sub UserForm_Initialize()
.......................
.......................
.......................
End Sub


Em xin hỏi, sự kiện khí nào mình dùng sự kiện này Initialize

Cám ơn
 
Đối với trường hợp 1, 2, 3 Anh có thể tham khảo Advance Filter. Nhưng Anh đã hỏi trong này em sẽ trình bày bằng VBA, Anh tham khảo.
(Lưu ý, cần mở song song 2 file)
Bài đã được tự động gộp:
trong trường hợp 3 ở FileC mình coppy cả 1 sheet3 thành Sheet6 thì báo lỗi (nghĩa là có thêm 1 sheet có dữ liệu tương tự như sheet3 ở FileC thì hệ thống báo lỗi). Vậy nếu dữ liệu ở FileC là Sheet6 thì sao ??
 
Upvote 0
Cho em hỏi lỗi không hiển thị được hết chiều rộng phải sửa như nào, xuất ra thì vẫn đủ chữ "TCVN 4447:2012: Công tác đất. Thi công và nghiệm thu"
 

File đính kèm

  • Untitled.png
    Untitled.png
    34.4 KB · Đọc: 20
Upvote 0
Hic OT loay hoay mãi đã thử để thuộc tính ColumnHeads = True mà không thể hiển thị được tiêu đề cột cho listbox ở bài này:


Các bạn xem có cách nào không giúp đỡ OT với ạ.
 
Upvote 0
Hic OT loay hoay mãi đã thử để thuộc tính ColumnHeads = True mà không thể hiển thị được tiêu đề cột cho listbox ở bài này:


Các bạn xem có cách nào không giúp đỡ OT với ạ.
Em vào đề tài sau tham khảo nhé.
 
Upvote 0
Em vào đề tài sau tham khảo nhé.
Hic, OT không biết cách vận dụng code của bác Siwtom vào bài này, nên khi bấm nút mở form đã bị báo lỗi.
Phiền anh Hai Lúa xem giúp với ạ.
Nêu bác Siwtom (@batman1 ) có ghé qua dọc bài này. Bác xem giúp con "hiển thị được tiêu đề cột cho listbox " với ạ.
 

File đính kèm

  • FormLoc (Recordset).xlsm
    38.4 KB · Đọc: 13
Upvote 0
Hic, OT không biết cách vận dụng code của bác Siwtom vào bài này, nên khi bấm nút mở form đã bị báo lỗi.
Phiền anh Hai Lúa xem giúp với ạ.
Nêu bác Siwtom (@batman1 ) có ghé qua dọc bài này. Bác xem giúp con "hiển thị được tiêu đề cột cho listbox " với ạ.
Của bạn thiếu máy cái lb với cái sự kiện Frame

sdfsdfsdf.png
 
Lần chỉnh sửa cuối:
Upvote 0
Hic, OT không biết cách vận dụng code của bác Siwtom vào bài này, nên khi bấm nút mở form đã bị báo lỗi.
Phiền anh Hai Lúa xem giúp với ạ.
Nêu bác Siwtom (@batman1 ) có ghé qua dọc bài này. Bác xem giúp con "hiển thị được tiêu đề cột cho listbox " với ạ.
Tôi hướng dẫn để bạn tự làm chứ nếu tôi làm hộ bạn thì rồi với tập tin khác bạn lại hỏi thì ai đâu có thời gian trả lời.

Các lưu ý:
1. Với ListBox trong Properties hãy thiết lập ColumnCount (của bạn là 3), ColumnWidths (của bạn là 3 giá trị)

2. Có bao nhiêu cột trong ListBox thì đặt bấy nhiêu Label xuống Form. Của bạn là 3 Label. Do có những Label khác không là tiêu đề cột của ListBox, vd. như Label1 = "NHập điều kiện lọc cho cột code", nên để phân biệt thì phải đổi tên 3 Label vừa thêm sao cho chúng có tiền tố khác "Label", vd. cho tiền tố là "lb". 3 Label vừa thêm phải có số thứ tự từ 1 đến 3, tổng quát là từ 1 tới n, với n là số cột trong ListBox. Tóm lại trong trường hợp của bạn thì đổi tên thành lb1, lb2 và lb3. Lưu ý là bạn chỉ thêm Label thôi còn không phải thiết lập Top, Left, Width, Height, vì code trong sub CalculateControls sẽ làm việc này.

3. 3 Label vừa thêm ở điểm 2 phải nằm trọn trong Frame. Nếu cần thì kéo 3 Label vào trong Frame, của bạn là vào trong Frame2.

4. Trong module UserForm1 phải có code của Sub CalculateControls và Sub Frame2_Scroll. Lưu ý là ListBox nằm trong Frame2 nên phải là Sub Frame2_Scroll chứ không phải là Sub Frame1_Scroll. Và do ListBox có tên là ListBox1 nên trong Sub Frame2_Scroll phải là ListBox1.Width.

5. Hãy đọc chú thích trong sub CalculateControls để biết cách truyền tham số. Cách gọi thì bạn làm đúng rồi, tức CalculateControls Frame2, ListBox1, "lb", "ID;Code;Price"

Mã:
Private Sub CalculateControls(ByVal FrameList As Object, ByVal listbox As Object, ByVal lbName As String, ByVal colNames As String)
'    FrameList: nhập tên của Frame, vd. Frame2
'    listbox: nhập tên của ListBox.
'    Các Label có số thứ tự từ 1 tới n, với n là số các cột trong ListBox. Nếu các Label có tiền tố là "lb" (lb1, lb2, ..., lbn) thì lbName = "lb"
'    colNames: tất cả tên các cột ngăn cách bởi dấu chấm phẩy
Dim index As Long, s As String, cWidths As String, lblLeft As Double, Arr, lb As msforms.Label, colWidths As Double
Dim captionArr
    captionArr = Split(colNames, ";")
    If listbox.ColumnCount <> UBound(captionArr) + 1 Then
        Err.Raise vbObjectError + 513, , "So tieu de cot khac so cot trong ListBox"
    End If
    cWidths = listbox.ColumnWidths
    s = Replace(cWidths, "pt", "")
    s = Replace(s, ";", "+")
    With FrameList
        colWidths = Evaluate(s)
        If colWidths > listbox.Width Then
            .ScrollBars = fmScrollBarsHorizontal
            .ScrollLeft = 0
            .ScrollWidth = colWidths
        Else
            listbox.Width = colWidths
        End If
        .Width = listbox.Width + 3
        .Height = listbox.Top + listbox.Height
    End With
    Arr = Split(s, "+")
    For index = LBound(Arr) To UBound(Arr)
        Set lb = Me(lbName & index + 1)
        If Not lb Is Nothing Then
            With lb
                .Left = lblLeft
                .Top = 0
                .Width = Arr(index)
                .Height = listbox.Top - 1
                .Caption = captionArr(index)
            End With
        End If
        lblLeft = lblLeft + Arr(index)
    Next
    On Error Resume Next
    For index = index To Me.Controls.Count
        Set lb = Me.Controls(lbName & index + 1)
        If Err Then Exit For
        lb.Top = FrameList.Height
    Next

    If listbox.ListStyle = fmListStyleOption Then
        listbox.ColumnWidths = Replace(cWidths, Arr(0), Arr(0) - 12, , 1)
    End If
End Sub

Private Sub Frame2_Scroll(ByVal ActionX As msforms.fmScrollAction, ByVal ActionY As msforms.fmScrollAction, ByVal RequestDx As Single, ByVal RequestDy As Single, ByVal ActualDx As msforms.ReturnSingle, ByVal ActualDy As msforms.ReturnSingle)
    If ActualDx <> 0 Then ListBox1.Width = ListBox1.Width + ActualDx
End Sub
 
Upvote 0
Tôi hướng dẫn để bạn tự làm chứ nếu tôi làm hộ bạn thì rồi với tập tin khác bạn lại hỏi thì ai đâu có thời gian trả lời.

Các lưu ý:
1. Với ListBox trong Properties hãy thiết lập ColumnCount (của bạn là 3), ColumnWidths (của bạn là 3 giá trị)

2. Có bao nhiêu cột trong ListBox thì đặt bấy nhiêu Label xuống Form. Của bạn là 3 Label. Do có những Label khác không là tiêu đề cột của ListBox, vd. như Label1 = "NHập điều kiện lọc cho cột code", nên để phân biệt thì phải đổi tên 3 Label vừa thêm sao cho chúng có tiền tố khác "Label", vd. cho tiền tố là "lb". 3 Label vừa thêm phải có số thứ tự từ 1 đến 3, tổng quát là từ 1 tới n, với n là số cột trong ListBox. Tóm lại trong trường hợp của bạn thì đổi tên thành lb1, lb2 và lb3. Lưu ý là bạn chỉ thêm Label thôi còn không phải thiết lập Top, Left, Width, Height, vì code trong sub CalculateControls sẽ làm việc này.

3. 3 Label vừa thêm ở điểm 2 phải nằm trọn trong Frame. Nếu cần thì kéo 3 Label vào trong Frame, của bạn là vào trong Frame2.

4. Trong module UserForm1 phải có code của Sub CalculateControls và Sub Frame2_Scroll. Lưu ý là ListBox nằm trong Frame2 nên phải là Sub Frame2_Scroll chứ không phải là Sub Frame1_Scroll. Và do ListBox có tên là ListBox1 nên trong Sub Frame2_Scroll phải là ListBox1.Width.

5. Hãy đọc chú thích trong sub CalculateControls để biết cách truyền tham số. Cách gọi thì bạn làm đúng rồi, tức CalculateControls Frame2, ListBox1, "lb", "ID;Code;Price"

Mã:
Private Sub CalculateControls(ByVal FrameList As Object, ByVal listbox As Object, ByVal lbName As String, ByVal colNames As String)
'    FrameList: nhập tên của Frame, vd. Frame2
'    listbox: nhập tên của ListBox.
'    Các Label có số thứ tự từ 1 tới n, với n là số các cột trong ListBox. Nếu các Label có tiền tố là "lb" (lb1, lb2, ..., lbn) thì lbName = "lb"
'    colNames: tất cả tên các cột ngăn cách bởi dấu chấm phẩy
Dim index As Long, s As String, cWidths As String, lblLeft As Double, Arr, lb As msforms.Label, colWidths As Double
Dim captionArr
    captionArr = Split(colNames, ";")
    If listbox.ColumnCount <> UBound(captionArr) + 1 Then
        Err.Raise vbObjectError + 513, , "So tieu de cot khac so cot trong ListBox"
    End If
    cWidths = listbox.ColumnWidths
    s = Replace(cWidths, "pt", "")
    s = Replace(s, ";", "+")
    With FrameList
        colWidths = Evaluate(s)
        If colWidths > listbox.Width Then
            .ScrollBars = fmScrollBarsHorizontal
            .ScrollLeft = 0
            .ScrollWidth = colWidths
        Else
            listbox.Width = colWidths
        End If
        .Width = listbox.Width + 3
        .Height = listbox.Top + listbox.Height
    End With
    Arr = Split(s, "+")
    For index = LBound(Arr) To UBound(Arr)
        Set lb = Me(lbName & index + 1)
        If Not lb Is Nothing Then
            With lb
                .Left = lblLeft
                .Top = 0
                .Width = Arr(index)
                .Height = listbox.Top - 1
                .Caption = captionArr(index)
            End With
        End If
        lblLeft = lblLeft + Arr(index)
    Next
    On Error Resume Next
    For index = index To Me.Controls.Count
        Set lb = Me.Controls(lbName & index + 1)
        If Err Then Exit For
        lb.Top = FrameList.Height
    Next

    If listbox.ListStyle = fmListStyleOption Then
        listbox.ColumnWidths = Replace(cWidths, Arr(0), Arr(0) - 12, , 1)
    End If
End Sub

Private Sub Frame2_Scroll(ByVal ActionX As msforms.fmScrollAction, ByVal ActionY As msforms.fmScrollAction, ByVal RequestDx As Single, ByVal RequestDy As Single, ByVal ActualDx As msforms.ReturnSingle, ByVal ActualDy As msforms.ReturnSingle)
    If ActualDx <> 0 Then ListBox1.Width = ListBox1.Width + ActualDx
End Sub
Con chào Bác Siwtom,
Cảm ơn Bác đã dành thời gian hướng dẫn và giải thích cho con ạ.
Theo hướng dẫn của Bác con đã làm được rồi ạ, và con cũng đã copy các lưu ý vào trong code để sau này gặp phải nếu có quên cách làm con đọc lại ạ.
Con chúc Bác nhiều sức khỏe ạ.
 
Upvote 0
Con chào Bác Siwtom,
Cảm ơn Bác đã dành thời gian hướng dẫn và giải thích cho con ạ.
Theo hướng dẫn của Bác con đã làm được rồi ạ, và con cũng đã copy các lưu ý vào trong code để sau này gặp phải nếu có quên cách làm con đọc lại ạ.
Con chúc Bác nhiều sức khỏe ạ.
Bạn sửa xong rồi có thể cho mình xin file nghiên cứu được không? Mình thử mà chưa được
 
Upvote 0
Bạn sửa xong rồi có thể cho mình xin file nghiên cứu được không? Mình thử mà chưa được
Cảm ơn bạn đã quan tâm.
Bạn muốn thử mình hay sao ấy chứ, hihi. Bài #368 Bác Siwtom hướng dẫn rất chi tiết mà.
Có một vấn đề như Bác Siwtom ( @batman1 ) có nêu ở trên:
"ColumnWidths (của bạn là 3 giá trị) " chỗ này hình như phải nhập tay và căn ke hơi thủ công thì from mới đẹp được ạ.
Còn mấy cái Lable thì tự nó co giãn theo các ColumnWidths rồi thì phải vì OT vẽ nó xong không cần phải co kéo đặt đúng vị trí tiêu đề (chỉ đặt áng chừng).
Bạn tham khảo nhé.
 

File đính kèm

  • FormLoc (Recordset).xlsm
    43 KB · Đọc: 12
Upvote 0
Tối hôm qua định đưa lên rồi mà thấy anh @batman1 hướng dẫn kỹ quá nên mình không đưa lên. với lại thường máy cái File mình ít lưu lắm

các bạn có thể dùng Code thiết lập
Mã:
    ListBox1.ColumnCount = 3
    ListBox1.ColumnWidths = "70pt;70pt;70pt"
hay là tự động tạo Lable hay Button làm tiêu đề cũng được, kể cả kéo thay đổi độ của Lisbox cũng được
 

File đính kèm

  • FormLoc (Recordset).xlsm
    35.1 KB · Đọc: 8
Upvote 0
các bạn có thể dùng Code thiết lập
Mã:
    ListBox1.ColumnCount = 3
    ListBox1.ColumnWidths = "70pt;70pt;70pt"
hay là tự động tạo Lable hay Button làm tiêu đề cũng được, kể cả kéo thay đổi độ của Lisbox cũng được
Xin chào thuyyeu99,
Giả sử tiêu đề là các ô A1,B1,C1,...,N1 => Vùng tiêu đề là A1:N1
Như vậy cái đoạn: "lb", "ID;Code;Price" trong câu lệnh:
Mã:
CalculateControls Frame2, ListBox1, "lb", "ID;Code;Price"
Có thể tự động thêm số Lable & đặt tên "lb1,lb2,...." & lấy tên tiêu đề ứng với các ô trong vùng A1:N1 được phải không bạn?
Nếu được mong bạn & các bạn chỉ dẫn & giúp đỡ ạ.
 
Upvote 0
Xin chào thuyyeu99,
Giả sử tiêu đề là các ô A1,B1,C1,...,N1 => Vùng tiêu đề là A1:N1
Như vậy cái đoạn: "lb", "ID;Code;Price" trong câu lệnh:
Mã:
CalculateControls Frame2, ListBox1, "lb", "ID;Code;Price"
Có thể tự động thêm số Lable & đặt tên "lb1,lb2,...." & lấy tên tiêu đề ứng với các ô trong vùng A1:N1 được phải không bạn?
Nếu được mong bạn & các bạn chỉ dẫn & giúp đỡ ạ.
gọi sub Addlabel này, tuy nhiên mình đang loay hoay để khi thêm label thì nó nằm trong frame2
Mã:
Sub addLabel()

Dim theLabel As Object
Dim labelCounter As Long

For labelCounter = 1 To 3
    Set theLabel = UserForm1.Controls.Add("Forms.Label.1", "lb" & labelCounter, True)
    With theLabel
        .Caption = "lb" & labelCounter
        .Left = 10
        .Width = 50
        .Top = 10 * labelCounter
    End With
Next
End Sub
 
Upvote 0
Xin chào thuyyeu99,
Giả sử tiêu đề là các ô A1,B1,C1,...,N1 => Vùng tiêu đề là A1:N1
Như vậy cái đoạn: "lb", "ID;Code;Price" trong câu lệnh:
Mã:
CalculateControls Frame2, ListBox1, "lb", "ID;Code;Price"
Có thể tự động thêm số Lable & đặt tên "lb1,lb2,...." & lấy tên tiêu đề ứng với các ô trong vùng A1:N1 được phải không bạn?
Nếu được mong bạn & các bạn chỉ dẫn & giúp đỡ ạ.
gọi sub Addlabel này, tuy nhiên mình đang loay hoay để khi thêm label thì nó nằm trong frame2
Mã:
Sub addLabel()

Dim theLabel As Object
Dim labelCounter As Long

For labelCounter = 1 To 3
    Set theLabel = UserForm1.Controls.Add("Forms.Label.1", "lb" & labelCounter, True)
    With theLabel
        .Caption = "lb" & labelCounter
        .Left = 10
        .Width = 50
        .Top = 10 * labelCounter
    End With
Next
End Sub
Đây chỉ cẩn thêm cái Frame2
Mã:
Private Sub AddLabel()
    Dim i, numberLabel As Long
    Dim lbl As Object ' or Dim lbl As Control
    numberLabel = 3
        For i = 1 To numberLabel
            Set lbl = Frame2.Controls.Add("forms.label.1") 'Controls.Add("Forms.Label.1")
            With lbl
                .Caption = "Label" & i
                .Name = "lb" & i
                .Height = 20
                .Width = 50
                .Left = 20 * i * 1
                .Top = 0
            End With
        Next i
End Sub
 
Upvote 0
Đây chỉ cẩn thêm cái Frame2
Mã:
Private Sub AddLabel()
    Dim i, numberLabel As Long
    Dim lbl As Object ' or Dim lbl As Control
    numberLabel = 3
        For i = 1 To numberLabel
            Set lbl = Frame2.Controls.Add("forms.label.1") 'Controls.Add("Forms.Label.1")
            With lbl
                .Caption = "Label" & i
                .Name = "lb" & i
                .Height = 20
                .Width = 50
                .Left = 20 * i * 1
                .Top = 0
            End With
        Next i
End Sub
Híc, OT không hiểu code của hai bạn ạ: không thấy trong code đề câpj gì đến nội dung vùng tiêu đề là A1:N1 ạ?
 
Upvote 0

File đính kèm

  • FormLoc (Recordset) -Ver1.1.xlsm
    42.2 KB · Đọc: 21
Upvote 0
Web KT
Back
Top Bottom