I'm building a spreadsheet for staffing purposes. The workbook that contains it is made up of 2 sheets. The one in question and a separate one for validation lists for various different situtations. Currently none are dependant on each other. The two lists in question are for Team Members and Roles. They are both in separate structured tables and both are contained in dual named ranges. The first references the table column directly and the second references the first to make it an indirect reference to the table.
My goal is to make the combobox searchable without the use of helper columns. I had that and it worked somewhat, but because the formulas were volatile it broke easily. The first part of my code I found and adapted to suit my needs. But basically, it makes the combobox appear in any cell that has data validation set for dropdowns and sets some parameters for it. I turned off the validation dropdown to accomodate the combobox and it works nicely. The part I can't seem to get is the "searchable part". In the TempCombo_Keydown sub I try to put the named ranges in arrays and loop through them to make the combobox return only names containing the string of characters typed no matter where in the name they are. To make a long story short I've run into a myriad of errors such as Type Mismatch, Permission Denied, and a few others and every time I think I've fix one another pops up... *Note - All tables are structured tables
I'm by no means a vba guru and I could really use a hand. I've uploaded marked up screenshots because I guess I can't upload the file. If someone would be willing to take a look and help me understand where I'm going wrong and how to get it to work I'd very much appreciate it. Learned a lot doing this so far, but I've hit a wall. Below is the code pertaining to the combobox and I've marked the line where the most recent error is (Permission Denied). I'm happy to answer any questions, thank you!
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, _
Cancel As Boolean)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
With cboTemp
'clear and hide the combo box
.ListFillRange = vbNull
.LinkedCell = vbNull
.Visible = False
End With
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
'if the cell contains
'a data validation list
Cancel = True
Application.EnableEvents = False
With cboTemp
'show the combobox with the list
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = ""
.LinkedCell = Target.Address
End With
cboTemp.Activate
'open the drop down list automatically
Me.TempCombo.DropDown
End If
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
ByVal Shift As Integer)
Dim arrIn() As Variant
Dim arrOut() As Variant
Dim i As Long
Dim j As Long
If Not Application.Intersect(ActiveCell, Range("Name")) Is Nothing Then
arrIn = Sheets("Validation Lists").Range("Tm_11").Value
Else
If Not Intersect(ActiveCell, Range("Position")) Is Nothing Then
arrIn = Sheets("Validation Lists").Range("Role_11").Value
End If
End If
ReDim arrOut(1 To UBound(arrIn), 1 To 1)
For i = 1 To UBound(arrIn)
If arrIn(i, 1) Like "*" & TempCombo.Text & "*" Then
j = j + 1
arrOut(j, 1) = arrIn(i, 1)
End If
Next
TempCombo.List = arrOut 'Location of current "Permission Denied" error
Select Case KeyCode
Case 9 'Tab
ActiveCell.Offset(0, 1).Activate
Case 13 'Enter
ActiveCell.Offset(1, 0).Activate
Case Else
'do nothing
End Select
End Sub
Private Sub TempCombo_LostFocus()
Application.ScreenUpdating = False
With Me.TempCombo
.Top = 10
.Left = 10
.Width = 0
.ListFillRange = vbNull
.LinkedCell = vbNull
.Visible = False
.Value = vbNull
End With
Application.ScreenUpdating = True
End Sub
For anyone interested in knowing... Below is my final code. I was able to achieve what I was looking to do and some. If anyone has any comments or ideas for a better way to achieve the same thing I'd certainly be interested in hearing about it. That being said what I have is working nicely so far!
I did end up with something a little different than what #FaneDuru and I were discussing above. In researching how to improve on what I already had I came across another similar thread on a different site so I modified that code to my situation, and it works just a little more smoothly.
Link mentioned above:
https://www.mrexcel.com/board/threads/how-to-use-a-combobox-with-autocomplete-and-search-as-you-type.1098277/
Option Explicit
Private IsArrow As Boolean
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, _
Cancel As Boolean)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
With cboTemp
'clear and hide the combo box
.ListFillRange = vbNull
.LinkedCell = vbNull
.Visible = False
End With
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
'if the cell contains
'a data validation list
Cancel = True
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With cboTemp
'show the combobox with the list
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = ""
.LinkedCell = Target.Address
End With
cboTemp.Activate
'open the drop down list automatically
Me.TempCombo.DropDown
End If
errHandler:
Application.EnableEvents = True
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Exit Sub
End Sub
Private Sub TempCombo_Change()
Dim i As Long
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
If Not IsArrow Then
With Me.TempCombo
If Not Application.Intersect(ActiveCell, Range("Name")) Is Nothing Then
Me.TempCombo.List = Worksheets("Validation Lists").Range("TM_11").Value
Else
If Not Intersect(ActiveCell, Range("Position")) Is Nothing Then
Me.TempCombo.List = Worksheets("Validation Lists").Range("Role_11").Value
End If
End If
.ListRows = Application.WorksheetFunction.Min(6, .ListCount)
If Len(.Text) Then
For i = .ListCount - 1 To 0 Step -1
If InStr(1, .List(i), .Text, vbTextCompare) = 0 Then .RemoveItem i
Next
End If
End With
End If
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
ByVal Shift As Integer)
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
IsArrow = (KeyCode = vbKeyUp) Or (KeyCode = vbKeyDown)
If KeyCode = vbKeyReturn Then
If Not Application.Intersect(ActiveCell, Range("Name")) Is Nothing Then
Me.TempCombo.List = Worksheets("Validation Lists").Range("TM_11").Value
Else
If Not Intersect(ActiveCell, Range("Position")) Is Nothing Then
Me.TempCombo.List = Worksheets("Validation Lists").Range("Role_11").Value
End If
End If
End If
Select Case KeyCode
Case 13 'Enter
ActiveCell.Offset(1, 0).Activate
Case Else
'do nothing
End Select
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Private Sub TempCombo_LostFocus()
Application.ScreenUpdating = False
With Me.TempCombo
.Top = 10
.Left = 10
.Width = 0
.ListFillRange = vbNull
.LinkedCell = vbNull
.Visible = False
.Value = vbNull
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Related
I have a code written in Excel VBA by making use of an Active-X element. But somehow Excel keeps crashing, leaving me frustrated. The element should have the following tasks:
- Looking into a predefined source in this case called "Opleidingen".
- You should be able to type inside the box so you can look in to the 200 variables and receive suggestions.
- Once selected it should transpose to the Cell behind so other cells can pick up the data and use it to come back with their own data.
But somehow it keeps crashing
I re-written the code 4 times, removed cells but with no success ( I am not a VBA guru and my knowledge is limited)
Private Sub ComboBox1_Change()
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim xArr
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xCombox = xWs.OLEObjects("ComboBox1")
With xCombox
.ListFillRange = "Opleiding"
.LinkedCell = "$C$4:$J$4"
.Visible = True
End With
If Target.Validation.Type = 3 Then
Target.Validation.InCellDropdown = False
Cancel = True
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xCombox
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = xStr
If .ListFillRange = "Opleiding" Then
xArr = Split(xStr, ",")
Me.ComboBox1.List = xArr
End If
.LinkedCell = Target.Address
End With
xCombox.Activate
Me.ComboBox1.DropDown
End If
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 9
Application.ActiveCell.Offset(0, 1).Activate
Case 13
Application.ActiveCell.Offset(1, 0).Activate
End Select
End Sub
Excel crashes once I start typing.
How to make suggestions in Excel data validation list while typing. There are constraints in my request:
The list of items should be in another sheet, and must not be above in hidden rows.
Typing a phrase should narrow the list to all the items which contain the phrase.
Search should be case insensitive.
So after typing am we should hypothetically have a suggestion to pick up from Amelia, Camila, Samantha, provided that those girls' names are on the item list.
I have found a good solution here, however it does not filter the items with contains clause but begins with. I sum up the proposed solution here shortly.
We insert a Combo Box (ActiveX Control) to a sheet.
We right click on a sheet name > View code > and paste the VBA code in the sheet VBA editor:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Update by Extendoffice: 2018/9/21
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim xArr
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xCombox = xWs.OLEObjects("TempCombo")
With xCombox
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
If Target.Validation.Type = 3 Then
Target.Validation.InCellDropdown = False
Cancel = True
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xCombox
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = xStr
If .ListFillRange = "" Then
xArr = Split(xStr, ",")
Me.TempCombo.List = xArr
End If
.LinkedCell = Target.Address
End With
xCombox.Activate
Me.TempCombo.DropDown
End If
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 9
Application.ActiveCell.Offset(0, 1).Activate
Case 13
Application.ActiveCell.Offset(1, 0).Activate
End Select
End Sub
I could not find a way to modify to change the search option from 'begins with' to contains.
The questions about autocomplete or autosuggest in validation list have been asked so far.
Excel data validation with suggestions/autocomplete
Excel 2010: how to use autocomplete in validation list
But neither of them contained answers which would satisfied the constraints I imposed.
Test file for download is here.
Try to add the following event (additionally the the other 2). Every time you enter something the code refreshes the ComboBox list.
Private Sub TempCombo_Change()
With Me.TempCombo
If Not .Visible Then Exit Sub
.Clear 'needs property MatchEntry set to 2 - fmMatchEntryNone
.Visible = False 'to refresh the drop down
.Visible = True
.Activate
Dim xStr As String, xArr As Variant
xStr = TempCombo.TopLeftCell.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
xArr = Split(xStr, Application.International(xlListSeparator))
Dim itm As Variant
For Each itm In xArr
If InStr(1, itm, .Value, vbTextCompare) > 0 Or .Value = "" Then
.AddItem itm
End If
Next itm
.DropDown
End With
End Sub
To overcome your first constraint, maybe you can assign a range to your combo box:
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim xArr
Dim i As Range
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xCombox = xWs.OLEObjects("Combotest")
With Sheets("Test_list2")
Set i = .Range("A2:A" & .Range("A" & .Rows.Count).End(xlUp).Row)
End With
Combotest.ListFillRange = i.Address
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xCombox = xWs.OLEObjects("Combotest")
With xCombox
.LinkedCell = "F2"
.Visible = True
End With
.
.
.
.
End Sub
is it possible to generate a combobox/dropdownlist inside a cell that is currently active? I tried this but nothing happened:
Programmatically add a drop down list to a specific cell
my client wants any cell that has been clicked from column A (except A1 because it serves as the Column header) to have dropdowns with list of items.
I also tried copying this and see if it runs but it always go to the On Error Resume Next
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
On Error GoTo errHandler
If Target.Count > 1 Then GoTo exitHandler
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
If cboTemp.Visible = True Then
With cboTemp
.Top = 10
.Left = 10
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
.Value = ""
End With
End If
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
'if the cell contains a data validation list
Application.EnableEvents = False
'get the data validation formula
str = Target.Validation.Formula1
str = Right(str, Len(str) - 1)
With cboTemp
'show the combobox with the list
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 15
.Height = Target.Height + 5
.ListFillRange = ws.Range(str).Address
.LinkedCell = Target.Address
End With
cboTemp.Activate
End If
exitHandler:
Application.ScreenUpdating = True
Application.EnableEvents = True
Exit Sub
errHandler:
Resume exitHandler
End Sub
I'm trying to use autofill drop-down list in Excel
The code which i used.I got it from here
http://www.contextures.com/DataValComboboxClick.zip
All the sudden it stopped working (worked for 2 months before)
Now i am getting 438 error
"Object does not support this property or method" in this line: .Value
= ""
The weird thing is that when i try to type the following in the immediate window: ?cbotemp.value, the promt shows me that cbotemp object does not have a Value property at all
Any help will be highly appreciated. I'm trying to work it out all night long and now it becomes desperate.
Here is the source code:
Option Explicit
' Developed by Contextures Inc.
' www.contextures.com
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
'Hide combo box and move to next cell on Enter and Tab
Select Case KeyCode
Case 9
ActiveCell.Offset(0, 1).Activate
Case 13
ActiveCell.Offset(1, 0).Activate
Case Else
'do nothing
End Select
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
Cancel = True
End If
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
With cboTemp
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
Application.EnableEvents = False
str = Target.Validation.Formula1
str = Right(str, Len(str) - 1)
With cboTemp
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 15
.Height = Target.Height + 5
.ListFillRange = ws.Range(str).Address
.LinkedCell = Target.Address
End With
cboTemp.Activate
'open the drop down list automatically
Me.TempCombo.DropDown
End If
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
If cboTemp.Visible = True Then
With cboTemp
.Top = 10
.Left = 10
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
.Value = "" 'here i get 438 error
End With
End If
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
The error is in this part of code:
...
Dim cboTemp As OLEObject
...
Set cboTemp = ws.OLEObjects("TempCombo")
On Error Resume Next
If cboTemp.Visible = True Then
With cboTemp
.Top = 10
.Left = 10
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
.Value = ""
End With
End If
Since cboTemp is of type OLEObject it really has not a property Value. But the On Error Resume Next should prevent this error from breaking the program.
If this is not (or not more) the case, then the setting in:
VBA Editor - Tools > Options > General > Error Trapping
is set to Break on all errors.
Default is Break on unhandled errors.
Set it back to default or simply do not set .Value="" at all. It is not necessary.
I have an invoice set up with validation list on a separate worksheet listing all our parts we sell. I put combo boxes on the invoice and linked them to the validation list and included code so that when box is double clicked, it will start auto completing the box using the validation list when typed. I also included code so that when this invoice is closed at end of the day, and then reopened the next day, or when shortcut key is pressed, it will clear the contents and change the invoice number.
Sometimes I need to save a, invoice to add on or change later. So I copy that worksheet and rename it with customer name. This has worked fine for over a year. But last week, when I click on any cell on the copied worksheets, it has a runtime error 1004 Method "OLEObjects" of object"_Worksheet" failed. Then the combo boxes don't work. But it only does it on the copied worksheets. The original worksheet works fine. Any suggestions? Here is the code used:
'==========================
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, _
Cancel As Boolean)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Dim wsList As Worksheet
Set ws = ActiveSheet
Set wsList = Sheets("ValidationLists")
Cancel = True
Set cboTemp = ws.OLEObjects("Parts")
On Error Resume Nex
With cboTemp
'clear and hide the combo box
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
'if the cell contains a data validation list
Application.EnableEvents = False
'get the data validation formula
str = Target.Validation.Formula1
str = Right(str, Len(str) - 1)
With cboTemp
'show the combobox with the list
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = str
.LinkedCell = Target.Address
End With
cboTemp.Activate
End If
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
End Sub
'=========================================
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
Application.EnableEvents = False
Application.ScreenUpdating = True
If Application.CutCopyMode Then
'allow copying and pasting on the worksheet
GoTo errHandler
End If
Set cboTemp = ws.OLEObjects("Parts")
On Error Resume Next
With cboTemp
.Top = 10
.Left = 10
.Width = 0
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
.Value = ""
End With
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
'====================================
'Optional code to move to next cell if Tab or Enter are pressed
'from code by Ted Lanham
Private Sub Parts_KeyDown(ByVal _
KeyCode As MSForms.ReturnInteger, _
ByVal Shift As Integer)
Select Case KeyCode
Case 9 'Tab
ActiveCell.Offset(0, 1).Activate
Case 13 'Enter
ActiveCell.Offset(1, 0).Activate
Case Else
'do nothing
End Select
End Sub
Set cboTemp = ws.OLEObjects("Parts") is where the problem is. It appears twice and gets flagged on both of them.