由于您没有说明要从列表框中提取的内容,请尝试下一个Function
。它将提供名称中带有“ CFRA”字符串的列表框对象。当然,可以使用任何字符串:
Private Function getListObjX(strPartName As String,sh As Worksheet) As MSForms.ListBox
Dim oObj As OLEObject
For Each oObj In sh.OLEObjects
If oObj.Name Like "*" & strPartName & "*" Then
'Debug.Print oObj.Name,TypeName(oObj.Object): Stop
If TypeName(oObj.Object) = "ListBox" Then
Set getListObjX = oObj.Object: Exit Function
End If
End If
Next
End Function
可以通过以下方式调用:
Sub testGetListObj()
Dim sh As Worksheet,lstB As MSForms.ListBox,lstBF As ListBox
Dim i As Long,arrSel As Variant,k As Long
Set sh = ActiveSheet
Set lstB = getListObjX("CFRA",sh)
If lstB Is Nothing Then MsgBox "No such an ActiveX list box...": Exit Sub
ReDim arrSel(lstB.ListCount - 1)
For i = 0 To lstB.ListCount - 1
If lstB.Selected(i) Then
'Debug.Print lstB.List(i)
arrSel(k) = lstB.List(i): k = k + 1
End If
Next i
ReDim Preserve arrSel(k - 1)
MsgBox Join(arrSel,"|")
End Sub
但是,作为ActiveX列表框类型,您可以简单地使用其事件之一。当然,如果您不需要从更多物品中取出物品,则可以使用列表框...
我还准备了一个函数,用于返回“表单”列表框的对象(在澄清问题之前)。也许其他人会用它...
Dim oObj As ListBox
For Each oObj In sh.ListBoxes 'even not being shown by intellisense,this collection exists...
If oObj.Name Like "*" & strPartName & "*" Then
'Debug.Print oObj.Name
Set getListObjF = oObj: Exit Function
End If
Next
End Function
可以类似地调用它,但是lstB
应该声明为As ListBox
。
编辑,使该功能一步一步生效:
Private Function getListFilters(strPartName) As String
Dim sh As Worksheet,lstB As MSForms.ListBox
Dim oObj As OLEObject,i As Long,k As Long
Set sh = ActiveSheet ' use here your sheet
For Each oObj In sh.OLEObjects
If oObj.Name Like "*" & strPartName & "*" Then
If TypeName(oObj.Object) = "ListBox" Then
Set lstB = oObj.Object: Exit For
End If
End If
Next
If lstB Is Nothing Then MsgBox "No such an ActiveX list box...": Exit Function
ReDim arrSel(lstB.ListCount - 1)
For i = 0 To lstB.ListCount - 1
If lstB.Selected(i) Then
arrSel(k) = lstB.List(i): k = k + 1
End If
Next i
ReDim Preserve arrSel(k - 1)
getListFilters = Join(arrSel,"|")
End Function
该函数将简单地称为:
Debug.Print getListFilters("CFRA")
,
您可以通过工作表的ActiveX
-集合来访问OLEObjects
-对象。有趣的控制信息位于此类对象的属性Object
中:
-
使用VBA函数TypeName
来确定您拥有哪种OLE对象
-
可以通过Object.ListCount
属性获取项目数。
-
要访问列表框的项目,请在Object.list
属性上循环(索引从0开始,因此循环必须从0运行到ListCount-1)
-
要检查是否已选择一项,请使用匹配的.Object.Selected属性。
以下代码将循环打印工作表的所有列表框的所有选定项目:
Sub listBoxes()
Dim objx As OLEObject
For Each objx In ActiveSheet.OLEObjects
Debug.Print "Name = " & objx.Name & " Typ = " & TypeName(objx.Object)
If TypeName(objx.Object) = "ListBox" Then
Dim i As Long
For i = 0 To objx.Object.ListCount - 1
If objx.Object.Selected(i) Then
Debug.Print objx.Name,objx.Object.list(i)
End If
Next i
End If
Next
End Sub
更新:要在工作表上显示形状, OleObjects 和 ActiceX 控件之间的一致性:>
形状是一个容器,用于存储不属于单元格/范围的所有内容。可以是任何一种绘制的形状形式(矩形,箭头,星星...),可以是图像,图表,OLEObject,表单控件等。
OLEObject 是不是来自Excel的东西,而是通过称为OLE Object Linking and Embedding的技术放入Excel工作表的。
ActiveX 是控件(编辑框,列表框...)。这些控件由Microsoft开发,并且应在不同的环境(例如浏览器)中运行。它们可以通过dll访问,并且该dll已添加到Excel和其他Office程序中。
每个ActiveX-Control都作为OLEObject添加到工作表中,但是您还可以具有不是ActiceX对象的其他OLEObject(例如,嵌入式Word文档)。
当您想通过VBA访问这些内容时,可以使用列出了图纸的所有形状(包括所有OLEObject)的Shapes
-集合,也可以使用列出所有OLEObject(包括所有ActiveX控件)。但是,没有ActiveX集合,因此,如果要获取所有ActiceX-Control,则必须遍历上述两个集合。
如果要从shape集合访问OLEObject,首先需要检查形状的类型,它的类型必须为OLEObjects
(12)或msoOLEControlObject
(7)。可以找到所有形状类型的列表here。
如果形状是7或12,则可以使用msoEmbeddedOLEObject
访问OLEObject
。以下to循环的结果完全相同(Shape.OLEFormat.Object
只是一个工作表变量)
ws
请注意,sh.Name和sh.OLEFormat.Object.Name不一定相同。
现在,最后一步是找到特定类型的ActiveX控件,这已经在上面原始答案的代码中显示-可以通过Dim sh As Shape,oleObj As OLEObject
For Each sh In ws.Shapes
If sh.Type = msoOLEControlObject Or sh.Type = msoEmbeddedOLEObject Then
Set oleObj = sh.OLEFormat.Object
Debug.Print oleObj.Name,oleObj.OLEType
End If
Next
For Each oleObj In ws.OLEObjects
Debug.Print oleObj.Name,oleObj.OLEType
Next
访问ActiveX控件。检查对象类型是否通过VBA函数oleObj.object
进行过滤,例如过滤您的列表框。
本文链接:https://www.f2er.com/1851086.html