当用户在Excel工作表中select单元格时,如何通过VBA提供文本build议

我的公司有一个相当大的导入模板,我创build了一个加载项,其中有一些我们经常使用的有用的快捷工具和过程。

我想做什么:我想添加一个类似于Intellisense的function,只有当用户在工作表(而不是vbe)中工作时,用户select四个特定列(BF,BG,CS和CT)中的单元格时才起作用。

我想模仿这样的事情:
智能感知

更具体地说:当在四列中的任何一列中select一个单元格时,我希望根据在其他列中的工作表中input的数据,在下拉列表中提供build议。

当用户点击空白单元格时:

  1. 他们给出了一个可供select的值列表
  2. 一旦他们select了这个值,它就会被添加到单元格中,并且冒号被添加到单元格的末尾
  3. 仍然在同一个单元格中,我希望根据用户首先select的内容重新填充下拉列表,并显示新的值(从第一个值缩小选项开始,列表将小于第一个列表)
  4. 一旦用户select了第二个值,它将与另一个冒号一起粘贴到单元格中的值的末尾。
  5. 最后,下拉列表将根据用户select的内容再次重新填充,并向他们展示最后一组值(列表将小于第一个和第二个列表,因为这些值缩小了select),然后他们select完成填充单元格

示例:在列中,V,W和X是值
印记选项|单选项1 |高级自定义颜色可在额外的成本。 请求报价。 分别。

  1. 当用户点击BF栏中的单元格时,首先显示包含“Imprint Option”的下拉列表,以及列V中的其他选项。
  2. 如果他们select“印记选项”,则“印记选项”被input到当前单元格中,并且该列表在“印记选项”右侧的列W中find值(意味着在这种情况下仅“单一选项1”将是上市)
  3. 当用户select“单选项1”时,单元格值现在是“印记选项:单选项1:”,并且列performance在仅显示值“额外成本可用的高级自定义颜色。请求报价”。
  4. 当用户select此值时,单元格值已完成,显示“Imprint Option:Single Option 1:Premium Custom Colors Available at Additional Cost。Call for Quote。”,没有显示列表

这只是一个非常简单的例子,因为显然在两次重新填充之后,列表中会有多个值。

我的想法/想法:
我的想法是,也许这是可能的通过使用combobox没有下拉箭头显示重新创build下拉列表,但我不知道如何或如果此方法可以与此工作,因为值需要重新填充,将有一个值在第一轮价值之后的细胞中,我认为这将被覆盖。 我唯一的限制是我必须在飞行中创build。 我将无法事先将控件拖放到工作表上,为了避免任何进一步的阻碍,我一次只select一个单元格。

所以,最后我的问题是:

  1. 这有可能重新创build吗?
    • 如果是的话,我该怎么办呢? (即使方法很复杂,我很乐意听到)
  2. 如果这是不可能的,你能提出一个办法,我可以做类似的事情吗?

实际上有很多方法可以实现这一点,也许有些自动化接近你想要的。 如果你想走自己的路,那么我会使用一个只包含ListBoxUserForm

有API显示所选单元格旁边的UserForm ,并从您的UserForm删除边界,使其看起来更像智能感知。 你可能也想要处理一些ListBox自动resize。 我会把所有这些都留给你,但是一个基本的版本会是这样的:

在这里输入图像说明

基本的想法是,你创build一个项目的数据库在适当的级别,然后重新填充ListBox与适当的数组,每当一个级别的索引已更改。 我会尽我的数据库在XML中,但你可以做到这一点,但你希望。

下面的代码是让你开始的东西,但是你想扩展它来处理所有可能的用户活动,比如想要退出,改变主意,删除等等。

第1步 :创build一个只有一个ListBoxUserForm ,并确保MultiSelect属性设置为单一。 在下面的例子中,我调用了UserForm IntelliSenseListBox lboxOptions

第2步 :这是用户表单背后的框架代码

 Option Explicit Private mItems() As String Private mSubItems1() As String Private mSubItems2() As String Private mSubItems3() As String Private mSubItems4() As String Private mIndex As Integer Private mCell As Range Private Property Let Index(val As Integer) mIndex = val Select Case val Case 0: lboxOptions.List = mItems Case 1: lboxOptions.List = mSubItems1 Case 2: lboxOptions.List = mSubItems2 Case 3: lboxOptions.List = mSubItems3 Case 4: lboxOptions.List = mSubItems4 End Select End Property Private Sub HandleItemSelected() Dim i As Integer 'Identify the selected item For i = 0 To lboxOptions.ListCount - 1 If lboxOptions.Selected(i) Then If mIndex = 0 Then 'Write to the cell and add a full stop mCell.Value = lboxOptions.List(i) & "." 'Trigger the next level of dropdown Index = i + 1 Else 'Write to the cell and close the window mCell.Value = mCell.Value & lboxOptions.List(i) Me.Hide End If End If Next End Sub Private Sub lboxOptions_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) 'Trap the return key event as if 'selected' If KeyAscii = vbKeyReturn Then HandleItemSelected End If End Sub Private Sub lboxOptions_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) 'Trap the click event as if 'selected' HandleItemSelected End Sub Private Sub UserForm_Activate() 'Reset the list and store the target cell Set mCell = Selection Index = 0 End Sub Private Sub UserForm_Initialize() 'Define the arrays of selections. 'I'd probably create an XML for this and read it into some arrays here. Const items As String = "Cake|IceCream|Pasta|Chips" Const subs1 As String = "Eggs|Flour|Butter|Sugar|Bake" Const subs2 As String = "Milk|Eggs|Sugar|Freeze" Const subs3 As String = "Eggs|Flour|Boil" Const subs4 As String = "Potatoes|Oil|Fry" mItems = Split(items, "|") mSubItems1 = Split(subs1, "|") mSubItems2 = Split(subs2, "|") mSubItems3 = Split(subs3, "|") mSubItems4 = Split(subs4, "|") End Sub 

第3步 :在您的Worksheet_SelectionChange事件中input此代码

 Private Sub Worksheet_SelectionChange(ByVal Target As Range) Const DESIRED_ADDRESS As String = "A:A, C:C, E:E" Dim desired As Range IntelliSense.Hide 'Check if just one cell has been selected If Target.Cells.Count = 1 Then 'Check if target cell is one that we want Set desired = Me.Range(DESIRED_ADDRESS) If Not Intersect(Target, desired) Is Nothing Then 'Check that target cell is blank If Len(Target.Value) = 0 Then 'All criteria met so show 'IntelliSense' IntelliSense.Show False End If End If End If End Sub 

Excel有一些内置的function,您可能会适应:

  1. 插入一个Comment – 只需鼠标hover触发
  2. 插入Data Validation消息 – 通过单击单元格触发
  3. 插入Data Validation下拉菜单 – 从已知列表中直接select
  4. 使用工作表事件macros来显示一个用户窗体

从您的详细的需求描述,我会select选项4

你可以用数据validation来描述你的描述。 这里是一个概述过程的文章: https : //support.microsoft.com/en-us/kb/211485 。 这可能不是你所期待的,因为你最终会得到多个用户select不同可用选项的单元。 然后可以使用连接公式将所有select放在一个单元格中。 其他人可能有更好的方式来做到这一点在VBA,但这是我第一次想到,当我读你的post。 我希望这是一些帮助。