thuộc tính nào dùng để lấy ra giá trị của dòng đang được chọn trong listbox ?
Ngày đăng:
05/12/2021
Trả lời:
0
Lượt xem:
174
Lập trình thì tới bước cuối cùng mới sử dụng tới tip & trick. Cái gì cũng có cách giải quyết theo phương pháp chuẩn của nó. Như tôi nói ở trên, bài toán của bạn chắc chắn là bài toán chuẩn rồi (vì kiểu gì đám Microsoft coders trước kia cũng phải đụng tới). Và nó được giải quyết thế này:
99% các câu hỏi liên quan tới lập trình (xử lý kỹ thuật) đều có thể giải quyết theo bước: - Dịch câu hỏi sang tiếng anh - Sử dụng Google Ngoài "câu chuyện" của bạn là: gather/get/remove multi-selected VB listbox items như đã nói ở trên, bạn còn phải quan tâm tới limits của standard listbox (vì thế ít khi PM xịn sử dụng listbox cho dữ liệu nhiều). Nếu ko bạn sẽ phải xử lý chuyện > 64k dữ liệu được load lên standard listbox thế nào? Làm thế nào để trong nháy mắt có thể load bụp 1 cái 1tr bản ghi lên listbox , v.v... Ngoài ra, bạn còn phải nghĩ tới việc duplicate copy from a listbox to another, remove selected listbox items, etc... (all w/ fastest way). Tất cả những việc như vậy đang đợi bạn và tôi chỉ có thể gợi ý đến đây mà thôi.
Vấn đề là con người khi chọn đường đi thì cần phải biết đường đó có đi được hay ko. Khi đã chứng minh là có tảng đá to lù lù trước mặt rồi thì nếu mà còn cố đi tiếp người ta gọi là.... Chúng ta phải biết cách học giải quyết vấn đề (nếu tôi làm VBA thật thì chắc chỉ khoảng 10 phút là tôi biết cái đó có làm được trên VBA hay ko. VBA hay Excel là đồ của M$ làm ra, chỉ cần vào msdn seach 1 lúc ko thấy đáp ứng thì về mặt chính thức là ko có cách nào xử lý. Mà khi M$ tạo ra nó nói đó là limited thì tốt nhất đừng tiếp tục làm tiếp vấn đề đó vì cái đó gọi là "biết là ko được mà cứ làm"). Trong quá trình giải quyết vấn đề, khi làm ko được thì tìm, tìm không được thì làm cách khác chứ ko đi tiếp vào ngõ cụt (google & microsoft mà "solution not found" thì tớ cam đoan là chả có ai trên GPE làm được). Bạn khi làm việc với Excel, với VBA thì phải hiểu là cái đó rất hạn chế. Properties và Methods của controls hạn chế như vậy thì tìm tiếp làm gì. Thế nên người ta mới gọi là VBA. Excel chỉ mạnh ở cái bảng tính với dữ liệu nhỏ thôi (mở files 500,000 dòng thì biết ngay) và VBA chỉ là 1 phần nhỏ script language bổ sung vào mà thôi.
Để lấy được SelCount của ListBox thì bạn làm như sau: Đoạn này để ở module nào đó Mã:Sao chép. Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const LB_GETSELCOUNT = &H190 Mã:Sao chép. Public Function fnListBox_SelCount(objListBox as ListBox) as Long
' get the number of selected items in the listbox
fnListBox_SelCount = SendMessage(objListBox.hWnd, LB_GETSELCOUNT, 0&, ByVal 0&)
End Function Sử dụng: ... '// iNumItems = Listbox1.SelCount iNumItems = fnListBox_SelCount(Listbox1) .... Tớ vừa tra trên API Declaration và thấy hằng số LB_GETSELCOUNT nên đoán là nó sẽ chạy vì nếu viết như thế này thì nó sẽ lấy được tương tự như thuộc tính .ListCount Mã:Sao chép. ' get the number of items in the source list
numItems = SendMessage(objListBox.hWnd, LB_GETCOUNT, 0&, ByVal 0&) Nếu đoạn code trên mà thực hiện được thì coi như bài toán đã được giải quyết. (Trước đó phải lấy được handle của objListBox đã vì trong VBA thì Listbox là Windowless control. Sử dụng hàm FindWindowEx) Về mặt lý thuyết mà nói thì mọi ActiveX Controls trong HĐH Windows đều là các Window và đều có thể mở rộng nó thành những Window chuẩn. VBA chẳng qua cũng dùng tương tự như VB6 nhưng nó làm hẹp phạm vi đi mà thôi. Còn những gì trước kia phải làm bằng APIs với VS6 thì nay ông M$ biến nó thành bộ .NET Framework với hàng trăm nghìn tính năng được tích hợp theo từng object và trở thành thư viện để cho chúng ta dùng 1 cách dễ dàng. Cảm ơn bạn hai2hai đã dành nhiều thời gian cho vấn đề của tôi.
Sau 1 hồi mày mò, tôi cũng đã làm được cái tôi cần, không dùng API, chỉ thông qua các thao tác khi sử dụng để lưu lại những Item được chọn. Có vẻ hơi dài dòng nhưng tôi thấy hiệu quả. Các bạn tham khảo và cho ý kiến nhé, có thể vẫn còn sót tình huống. PHP:Sao chép. Dim Str As String 'Chuỗi lấy danh sách các Item được chọn
Dim Mdn As Boolean 'MouseDown
Dim Mm As Boolean ' MouseMove
Dim ShiftK As Integer
Dim StID As Long 'Vị trí ban đầu
Dim BotID As Long, TopID As Long 'Vị trí đầu, cuối danh sách
Private Sub L1_Change()
If ShiftK = 0 Then 'Không có phím điều khiển nào được nhấn
If Not Mm Then 'Không kéo rê chuột
StID = L1.ListIndex
Str = "(" & L1.ListIndex & ")"
Else 'Kéo rê chuột
LienTuc
End If
ElseIf ShiftK = 1 Or ShiftK = 3 Then 'Bâìm Shift hoãòc Ctrl+Shift
LienTuc
ElseIf ShiftK = 2 Then 'Bấm Ctrl
If Not Mm Then 'Không kéo rê chuột
If L1.Selected(L1.ListIndex) Then StID = L1.ListIndex
If InStr(Str, "(" & L1.ListIndex & ")") <> 0 Then
Str = Replace(Str, "(" & L1.ListIndex & ")", "")
Else
If Mdn Then 'Chọn bằng chuột
Str = Str & "(" & L1.ListIndex & ")"
Else 'Chọn bằng phím
Str = "(" & L1.ListIndex & ")"
End If
End If
Else 'Kéo rê chuột
LienTuc
End If
End If
Me.Caption = Str
End Sub
Private Sub LienTuc()
Str = ""
If StID > L1.ListIndex Then
BotID = StID: TopID = L1.ListIndex
Else
BotID = L1.ListIndex: TopID = StID
End If
For I = TopID To BotID
Str = Str & "(" & I & ")"
Next
End Sub
Private Sub L1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
ShiftK = Shift
End Sub
Private Sub L1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
ShiftK = Shift
End Sub
Private Sub L1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
ShiftK = Shift
Mdn = True
End Sub
Private Sub L1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
ShiftK = Shift
If Mdn Then Mm = True
End Sub
Private Sub L1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
ShiftK = Shift
Mm = False: Mdn = False
End Sub
Private Sub UserForm_Activate()
Dim Lst() As Long
For I = 1 To 1000
L1.AddItem I
Next
End Sub |