如何通过 VBA (Excel) 在编辑框功能区上设置文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18660875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set a text on a Editbox Ribbon via VBA (Excel)
提问by Braulio
How can I set a text in a Ribbon Editbox? I can't find it on internet :/
如何在功能区编辑框中设置文本?我在互联网上找不到它:/
I just can find examples of click event but nothing about set a text from a Sub.
我只能找到点击事件的例子,但没有关于从 Sub 设置文本的信息。
So for example, I want something like this:
例如,我想要这样的东西:
Sub settingText()
editboxname = "my text"
end sub
采纳答案by greenbutterfly
It's a little while since this answer was posted, and there looks to be a recent-ish change to the behaviour of the ribbon, which means the original answer posted may not be a solution any more. For the record, I'm using Excel 2013 with some updates that are dated after Braulio's answer.
这个答案发布已经有一段时间了,功能区的行为似乎最近发生了变化,这意味着发布的原始答案可能不再是解决方案。作为记录,我使用的是 Excel 2013,其中有一些更新日期在 Braulio 的回答之后。
The heart of the difference is that Invalidate and InvalidateControl on the ribbon don't behave the same way as previously. This means that InvalidateControl does not call the getText callback on the editBox. I replaced the InvalidateControl calls with Invalidate (so forces a re-draw on the entire ribbon), and that does trigger the callback as expected.
不同之处的核心是功能区上的 Invalidate 和 InvalidateControl 的行为方式与以前不同。这意味着 InvalidateControl 不会在 editBox 上调用 getText 回调。我用 Invalidate 替换了 InvalidateControl 调用(因此强制在整个功能区上重新绘制),并且确实按预期触发了回调。
So here's the code of my solution for a filename/browse button (note I've included extra code for caching the ribbon UI reference on a very hidden sheet so that resets during development don't make the ribbon inaccessible).
所以这是我的文件名/浏览按钮解决方案的代码(请注意,我已经包含了额外的代码,用于在非常隐藏的工作表上缓存功能区 UI 引用,以便在开发过程中重置不会使功能区无法访问)。
Private sobjRibbon As IRibbonUI
Private strFilename As String
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (destination As Any, source As Any, ByVal length As Long)
Private Function GetRibbon() As IRibbonUI
If sobjRibbon Is Nothing Then
Dim objRibbon As Object
CopyMemory objRibbon, ThisWorkbook.Worksheets("Ribbon_HACK").Range("A1").Value, 4
Set sobjRibbon = objRibbon
End If
Set GetRibbon = sobjRibbon
End Function
'Callback for customUI.onLoad
Sub Ribbon_Load(ribbon As IRibbonUI)
Set sobjRibbon = ribbon
Dim lngRibPtr As Long
lngRibPtr = ObjPtr(ribbon)
' Write pointer to worksheet for safe keeping
ThisWorkbook.Worksheets("Ribbon_HACK").Range("A1").Value = lngRibPtr
strFilename = ""
End Sub
'Callback for FileName onChange
Sub OnChangeFilename(control As IRibbonControl, text As String)
strFilename = text
End Sub
'Callback for FileName getText
Sub GetFileNameText(control As IRibbonControl, ByRef returnedVal)
returnedVal = strFilename
End Sub
'Callback for FilenameBrowse onAction (I'm looking for XML files here)
Sub OnClickFilenameBrowse(control As IRibbonControl)
Dim objFileDialog As Office.FileDialog
Set objFileDialog = Application.FileDialog(msoFileDialogFilePicker)
With objFileDialog
.AllowMultiSelect = False
.Title = "Please select the file."
.Filters.Clear
.Filters.Add "XML", "*.xml"
If .Show = True Then
strFilename = .SelectedItems(1)
GetRibbon().Invalidate ' Note the change here, invalidating the entire ribbon not just the individual control
End If
End With
End Sub
For the record, here's the XML for the two objects I'm dealing with here:
作为记录,这是我在这里处理的两个对象的 XML:
<editBox id="FileName" onChange="OnChangeFilename" screentip="Filename of the XML file to upload" label="XML file name" showImage="false" getText="GetFileNameText" />
<button id="FilenameBrowse" imageMso="ImportExcel" onAction="OnClickFilenameBrowse" screentip="Find the file to upload" label="Browse" />
回答by Braulio
The solution I found on this link: http://www.shulerent.com/2011/08/16/changing-the-value-of-an-editbox-office-ribbon-control-at-runtime/
我在这个链接上找到的解决方案:http: //www.shulerent.com/2011/08/16/changed-the-value-of-an-editbox-office-ribbon-control-at-runtime/
Here is an example that I tested and it worked well:
这是我测试过的一个例子,它运行良好:
'Global Variables:
Public MyRibbonUI As IRibbonUI
Public GBLtxtCurrentDate As String
Private Sub OnRibbonLoad(ribbonUI As IRibbonUI)
Set MyRibbonUI = ribbonUI
GBLtxtCurrentDate = ""
End Sub
Private Sub ocCurrentDate(control As IRibbonControl, ByRef text)
GBLtxtCurrentDate = text
MyRibbonUI.InvalidateControl (control.id)
End Sub
Private Sub onGetEbCurrentDate(control As IRibbonControl, ByRef text)
text = GBLtxtCurrentDate
End Sub
Public Sub MyTest()
'Here is an example which you are setting a text to the editbox
'When you call InvalidateControl it is going to refresh the editbox, when it happen the onGetEbCurrentDate (which is the Gettext) will be called and the text will be atributed.
GBLtxtCurrentDate = "09/09/2013"
MyRibbonUI.InvalidateControl ("ebCurrentDate")
End Sub
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="OnRibbonLoad">
<ribbon>
<tabs>
<tab id="Objects" label="Objects">
<group id="grp" label="My Group">
<editBox id="ebCurrentDate" label="Date" onChange="ocCurrentDate" getText="onGetEbCurrentDate"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>