如何在Excel自定义功能区控件的下拉控件中设置默认值

时间:2013-09-19 23:33:19

标签: xml excel excel-vba vba

我为Excel 2010创建了一个自定义Fluent功能区界面,其中包含一个下拉列表。相关的XML代码(简化):

<dropDown id="chooseFilter" showLabel="true" label="Filter" onAction="filterSelected" > 
    <item id="Filter1" label="Filter 1" /> 
    <item id="Filter2" label="Filter 2" /> 
</dropDown>

加载功能区时,未选择任何值 - 下拉列表显示为空。

enter image description here

我希望默认情况下选择第一个项目 - 但找不到任何描述如何操作的文档。我查看了控件的MSDN documentation,但它没有涵盖这种情况。我尝试了各种“HTML-like”语句的排列,但它们都被自定义UI编辑器拒绝为无效。我试过的事情的例子:

<item id="Filter1" label="Filter 1" selected="selected" /> 

错误讯息:The 'selected' attribute is not declared

我在selectedItem声明中尝试了valueselected<dropDown .../>等其他属性,但似乎没有任何效果。

如果我只有正确的文档,这将是微不足道的,但即使是功能区自定义的完整Microsoft“文档”(找到here对此主题保持沉默。

我甚至试图查看位于http://schemas.microsoft.com/office/2006/01/customui的架构是否“人类可读”,但当我尝试在浏览器中打开它时,我被告知它不可用。也许有一招......

所以我转向这个论坛的综合智慧。你可以从我的Q / A比率中看出我不经常这样做......

如何修改我的XML以便功能区打开,并在下拉控件中选择任意项?我会满足于它是第一项 - 但“我选择在我的XML中声明的任何项目”将是更可取的。

我正在为此寻找XML解决方案 - 不希望添加onLoad VBA代码或其他VBA技巧。这有多难,对吧?...

3 个答案:

答案 0 :(得分:8)

您似乎需要使用VBA才能选择默认项目。

引自documentation for the dropDown element(我的重点):

  

getSelectedItemID(getSelectedItemID callback)

     

指定要调用的回调函数的名称,以确定要在此控件中选择的项的标识符。 getSelectedItemID和getSelectedItemIndex属性是互斥的。 如果未指定任何属性,则控件不应显示所选项目。例如,请考虑以下XML片段:

<gallery id="gallery" getItemCount="GetGalleryItemCount"  
   getItemID="GetItemID"
   getSelectedItemID="GetGallerySelectedItemID" />
  

在此示例中,当应用程序需要确定库中的选定项时,将调用GetGallerySelectedItemID回调函数。在此示例中,回调函数返回GetItemID回调函数返回的标识符之一。此属性的可能值由ST_Delegate简单类型定义,如2.3.2节中所述。

根据我对文档的阅读,您需要自己维护过滤器的当前所选项目。 GetSelectedItemID处理程序将返回当前选定的项,OnAction处理程序将更新它。

在XML中:

<dropDown id="chooseFilter" showLabel="true" label="Filter"
   getSelectedItemID="GetSelectedItemID" onAction="OnAction"> 
   <item id="Filter1" label="Filter 1" /> 
   <item id="Filter2" label="Filter 2" />
</dropDown>

在工作簿的代码模块中:

Private mCurrentItemID As Variant

Sub GetSelectedItemID(control As IRibbonControl, ByRef itemID As Variant)
    If IsEmpty(mCurrentItemID) Then
        mCurrentItemID = "Filter1"
    End If
    itemID = mCurrentItemID
End Sub

Sub OnAction(control As IRibbonControl, selectedID As String, _
             selectedIndex As Integer)
    mCurrentItemID = selectedID
End Sub

答案 1 :(得分:3)

我在启动时出现了类似的问题,因为还没有设置任何内容。但是,当控件失效但dropDown已经填充时,它将再次返回空白选择(我使控件无效,因为我在列表中添加了一些新项目,所以我希望它重建)。

这里提到的解决方案是使用
如上所述<dropDown id="ddc0" label="Label Dropdown 0" getSelectedItemIndex="GetSelectedItemIndexDropDown ...

然后VBA回电话:

Sub GetSelectedItemIndexDropDown(control As IRibbonControl, ByRef index) ' Callbackname in XML File "GetSelectedItemIndexDropDown ...

按预期工作。注意:onAction= "onActionCallback"用于设置状态并将其广播给VBA中的任何人; getSelectedItemIndex= "onGetSelectedItemIndexCallback"用于功能区查询它应显示的状态。

答案 2 :(得分:2)

我无耻地欺骗了这个XML - 我使用了RibbonCreator 2010

DefaultValue似乎设置在所有荒谬地方的dropDown tag内......

<dropDown id="ddc0" label="Label Dropdown 0" getSelectedItemIndex="GetSelectedItemIndexDropDown" onAction="OnActionDropDown" getVisible="GetVisible" getEnabled="GetEnabled" tag="RibbonName:=;inMenu:=;CustomTagValue1:=;CustomTagValue2:=;CustomTagValue3:=;DefaultValue:=1;CustomPicture:=;CustomPicturePath:=">
    <item id="ddc0Item0" label="a" screentip="a" supertip="a"/>
    <item id="ddc0Item1" label="b" screentip="b" supertip="b"/>
</dropDown>

编辑:

除非您将以下功能添加到VBA代码中,否则此不会工作:

Sub GetSelectedItemIndexDropDown(control As IRibbonControl, ByRef index)
    ' Callbackname in XML File "GetSelectedItemIndexDropDown"
    ' Callback getSelectedItemIndex
    Dim varIndex As Variant
    varIndex = getTheValue(control.Tag, "DefaultValue")
    If IsNumeric(varIndex) Then
        Select Case control.ID
            ''GetSelectedItemIndexDropDown''
            Case Else
                index = getTheValue(control.Tag, "DefaultValue")
        End Select
    End If
End Sub

Public Function getTheValue(strTag As String, strValue As String) As String
   Dim workTb()     As String
   Dim Ele()        As String
   Dim myVariabs()  As String
   Dim i            As Integer
   On Error Resume Next
      workTb = Split(strTag, ";")
      ReDim myVariabs(LBound(workTb) To UBound(workTb), 0 To 1)
      For i = LBound(workTb) To UBound(workTb)
         Ele = Split(workTb(i), ":=")
         myVariabs(i, 0) = Ele(0)
         If UBound(Ele) = 1 Then
            myVariabs(i, 1) = Ele(1)
         End If
      Next
      For i = LBound(myVariabs) To UBound(myVariabs)
         If strValue = myVariabs(i, 0) Then
            getTheValue = myVariabs(i, 1)
         End If
      Next
End Function

但是,它可以做得足够通用,一旦它到位,就可以用XML重复引用。