Đố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)
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 ??
Tôi vận dụng và khai thác cái hàm lọc vào cái form lọc dữ liệu, các bạn có thể tham khảo và tùy biến sử dụng nhé. Dim rst As Object Private Sub TextBox1_Change() Dim arr As Variant If TextBox1.Text = "" Then rst.Filter = 0 Else rst.Filter = "Code like '*" &...
Tôi vận dụng và khai thác cái hàm lọc vào cái form lọc dữ liệu, các bạn có thể tham khảo và tùy biến sử dụng nhé. Dim rst As Object Private Sub TextBox1_Change() Dim arr As Variant If TextBox1.Text = "" Then rst.Filter = 0 Else rst.Filter = "Code like '*" &...
Chào Các Anh/Chị Em đang trong giai đoạn học VBA. Em đang loay hoay không biết gán tiêu đề cột trong Listbox làm thế nào, do Listbox hiển thị các kết quả cho giá trị tìm kiếm (không phải RowSource). Em cũng tìm hiểu dùng Label cho tiêu đề Listbox nhưng do em gán dữ liệu nhiều cột dữ liệu vào...
Chào Các Anh/Chị Em đang trong giai đoạn học VBA. Em đang loay hoay không biết gán tiêu đề cột trong Listbox làm thế nào, do Listbox hiển thị các kết quả cho giá trị tìm kiếm (không phải RowSource). Em cũng tìm hiểu dùng Label cho tiêu đề Listbox nhưng do em gán dữ liệu nhiều cột dữ liệu vào...
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 ạ.
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 ạ.
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 ạ.
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
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 ạ.
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 ạ.
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é.
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 đỡ ạ.
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
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
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
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