vba循环通过形状列表框(更改类型)

所以我有一个带有多个列表框的电子表格。在这些列表框中,我有一些实际上是过滤器的值/项目。我想获取每个列表框的每个项目/过滤器,以修改代码中的SQL查询。 因此,我被要求遍历列表框,并设法通过循环电子表格的形状来做到这一点,但最终...这些列表框现在在VBA中被视为Shapes,而不再是列表框。我正在寻找一种在列表框中旋转形状的方法,或者从Shapes类型中找到一种方法来循环每个列表框的项目。这是我的代码的一部分,到目前为止,我循环浏览了每个形状/列表框,如果在我的形状名称中有单词“ CFRA”,那么我想在列表框中选择的每个项目中循环,以便我的函数返回它们。

Private Function getListFilters() As String

    My_Sheet.activate
    Dim Shp
    For Each Shp In My_Sheet.Shapes
        pos = InStrRev(Shp.Name,"CFRA",vbTextCompare)
        MsgBox (pos)
        If pos <> 0 Then
        MsgBox (TypeName(Shp))

        End If
    Next
End Function

在此先感谢那些愿意帮助我并度过美好时光的人:)

iCMS 回答:vba循环通过形状列表框(更改类型)

由于您没有说明要从列表框中提取的内容,请尝试下一个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

大家都在问