VBA Excel comboBox dropdown is empty after obj.addItem - vba

I have an Excel2010 VBA userform that has one comboBox, from which the user should be able to select a currently-open Excel Workbook. The USERFORM_Initialize subroutine contains (among other things) :
cbWorkbook.Clear
cbWorkbook.Visible = True
For Each wb In Workbooks
cbWorkbook.AddItem wb.name
Next wb
I have set a breakpoint at this code, and am able to step through it; in the present situation there are four open workbooks, and the "for each" is iterated four times, as appropriate. And I can see that wb.name contains the values that I want.
However, when the form displays and the dropbox arrow is clicked, the "list" is empty. It looks like there is room for one item, and that item is blank. (I believe this is typical of an empty dropdown box.)
Select attributes for the combobox are:
Autosize=False; AutoTab=false; Enabled=True; DropButtonStyle=1-fmDropButtonStyleArrow;
Height=18; ListRows=8; ListStyle=0; Locked=False; ShowOptionWhen=2; SpecialEffect=2; Style=0; Visible=True. At the time of execution, cbWorkbook.listCount = 4
This is in development, and it did appear to work as expected yesterday, but now seems to never work. Any ideas where I might be going wrong?
EDIT: I found the solution to this: I had inadvertantly duplicated another combo box over the top of cbWorksheet, effectively hiding it. The control I was seeing was empty, while the control I wanted was overlaid. Deletion of the rogue control box solved the issues.
My apologies; this should have been the first thing I sought.

I found the solution to this: I had inadvertantly duplicated another combo box over the top of cbWorksheet, effectively hiding it. The control I was seeing was empty, while the control I wanted was overlaid. Deletion of the rogue control box solved the issues.
My apologies; this should have been the first thing I sought.

With ComboBox1
.AddItem "This"
.AddItem "Is"
.AddItem "A"
.AddItem "Test"
End With
or if you want to fill it with Range data:
ActiveSheet.Shapes("ComboBox1").Select
Selection.ListFillRange = "k1:k10"
PS - submit your file for review; it should be easier to look at!

Related

Excel-VBA UserForm ListBox - How can I Highlight option without Selecting

Nutshell:
What is the equivalent to Me.ListBox1.Selected(2) = True but for highlighting instead of Selecting?? (Highlight might be the wrong word but I'm sure I've seen that before in this context - the outline box around an option instead of actually selecting it)
** Tried **
Me.ListBox1.ListIndex = 2
doesn't do anything either.
With Me.ListBox1
saveVal = .List(0)
.Value = ""
.Value = saveVal
End With
Gives me an error saying "Invalid Property Value"
Background:
Why do I need to click twice on some items/boxes?
I have a userform with several ListBox which are populated by adding items one by one, which works fine.
The ListBox settings have been changed to MultiSelect = 1 - fmMultiSelectMulti and ListStyle = 1 - fmListStyleOption
The issue is when trying to select an option on some boxes for the first time, it just highlights it without selecting it, while on other boxes and other tries it may or may not select an option straight away. It doesn't seem to be the same culprits and is a bit random - does it have something to do with where I'm clicking on the option? On the item text instead of the item box? Why does it work on some and not others?
After I've selected one option in a box, it then allows me to select any other with a single click which is the desired behaviour.
I found a link where someone had suggested this behaviour was because of a corrupted workbook, but I don't think it's that. I just created a new book with 1 listbox in a userform, changed to desired settings, copied the listbox 6 times, put the listsource as rand() in columns A:G and I'm still getting the same issue.
Edit: My plan is to "highlight" the top option on each box so that the first click on a box has no option other than to select (because something is already highlighted)...
The trick to tackling my INITIAL problem seems to have been after populating each list to set .ListIndex = 0 but this only worked after using .SetFocus
Solved! (For now, I think)
Even though this doesn't highlight anything it allows me to select something first time without fail.

Can't add items to a combobox

I have tried these sites for help:
excel-easy.com
sitestory.dk
ozgrid.com
stackoverflow.com
contextures.com
microsoft.com
Would appreciate the help!
Here is my code:
Private Sub FusegearPerformanceUserForm1()
With FailureComboBox
.AddItem "japp"
End With
End Sub
Manipulation of controls in Excel confused me for a while until I realized that there are two kinds of them, and this might be part of your confusion. For example, there is:
a Form Control Combo Box, and,
an ActiveX Control Combo Box.
The two look, behave, and are controlled similarly, but not identically.
Click image to enlarge:
I realize that wasn't your question, but I figured I should make sure you can identify which control you are using, and therefore make sure that you're using (and Googling) the correct information - especially since the terms "Combo Box" and "Drop Down Box" are often used interchangeably. A Google Search for Vcode related to BA Combo Box Control will be wrong 50% of the time, so you need to be more specific.
AS for the code difference:
FORM CONTROL Combo Box
'add item
ActiveWorkbook.Sheets("Sheet1").Shapes("Drop Down 1").ControlFormat.AddItem "abcd"
'remove all items
ActiveWorkbook.Sheets("Sheet1").Shapes("Drop Down 1").ControlFormat.RemoveAllItems
'https://analysistabs.com/vba-code/activex-controls/combobox/
ACTIVEX CONTROL Combo Box
'add item
ActiveWorkbook.Sheets("Sheet1").ComboBox1.AddItem "abcd"
'remove all items
ActiveWorkbook.Sheets("Sheet1").ComboBox1.Clear
More Information:
Different Types of Combo Boxes Explained
VBA ComboBox
MSDN : VBA Shape Members
So, just for completion:
The solution to this question was, that the file was saved in the XLSX format which cannot contain VBA code. After saving the file in the XLSM format everything worked as expected.

Order of Events for the SheetFollowHyperlink Event

I have a workbook that lists people's names and overall performance for the past few weeks. I was asked to make it so that when their names are clicked, the details for that person would show. The solution I came up with at the time was to point all of the hyperlinks to a sheet that reminded them to turn on their macros.
In the WorkSheet_Activate event, I redirected them to another sheet that populated with the details for the person they had selected. This works fine. If the user doesn't have their macros turned on, they get a friendly reminder, but if they do, they immediately get redirected. There's just one problem. Because the hyperlink takes them somewhere else first, it causes the infamous "screen flicker".
On researching, I found the FollowHyperlink Events (I think the workbook level event would be most suitable for my purposes, though). However, before I get started rebuilding it, I wanted to make sure that this would solve the "screen flicker".
On MSDN, it states that the Event occurs when the user clicks the hyperlink. I can't seem to find anywhere that directly states whether this Event is triggered before or after the user is directed to the other sheet, though. If it gets triggered right after, that wouldn't really help me, but if it gets triggered before, I could put an Application.ScreenUpdates = False in the event, and it would solve my problem.
TL;DR (Get to the point already):
Does the Workbook_SheetFollowHyperlink Event happen before or after the user is directed to where ever the hyperlink is pointed?
To answer your question, the event is triggered after the hyperlink is followed. You can demonstrate this using the code below:
Private Sub Workbook_SheetFollowHyperlink(ByVal Sh As Object, ByVal Target As Hyperlink)
Debug.Print "Workbook level: " & ActiveSheet.Name
End Sub
When the event is triggered, the ActiveSheet is the sheet directed to by the hyperlink.
I'm not sure of a way to solve your problem directly, even the Click() event won't be raised when you click a hyperlink. However, the Worksheet level hyperlink event handler will be called before the Workbook level handler and this may speed the process up enough to not see the flicker.
You can prove this if you leave the Workbook level event as is and add the following code to the Worksheet containing the hyperlinks:
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
Debug.Print "Worksheet level: " & ActiveSheet.Name
Sleep 1000
Debug.Print "Leaving worksheet level event"
End Sub
After a few experiments (see below) I concluded that:
Allow the user to use the hyperlink columns when macros are disabled.
When macros are enabled, hide the current hyperlink column and show another column that gives the user a different "hyperlink" that takes them directly to where you want them to go.
The 2nd hyperlink can easily be "simulated" such that it picks up the other columns hyperlink. (See below)
I hope his helps
Interesting, here's a few things I tried
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' This does not fire if the user clicks directly on the hyperlink text
' it only fires if when click on the cell space that is not text
With ActiveCell
If Hyperlinks.Count Then
MsgBox "hi" & .Hyperlinks(1).Range
.Hyperlinks(1).Follow
End If
End With
End Sub
However you could make the text in the cells look like a hyperlink but actually just be blue underlined text. You could then use the Worksheet_SelectionChange to go to a related cell.
The question then become how to store the related cell.
You want to store it so that if row and column are inserted on the destination sheet, the reference will adjust. (eg NOT in comments, or the description of named ranges etc..)
Depending on how much data you have there's a variety of ways you could choose from.
I think I would favour this:
Having a hidden column next to the cell on display that has a hyperlink. The cell on display has a formula that is set to pick up the value from the hidden column (I quite like the sound of this as you have the hyperlink column already - so just modify the above code to get the hyperlink from the column next to the clicked cell using offset perhaps)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' This does not fire if the user clicks directly on the hyperlink text
With ActiveCell.offset(0,1)
If Hyperlinks.Count Then
.Hyperlinks(1).Follow
End If
End With
End Sub
You could mess around with named ranges, but it will be a pain.
I've just realised that what I tried won't help much as you need the hyperlink to work when macros have not been enabled!
So to get the above to work you could change the columns displayed when the user enables macros. ie the hyperlink column is shown when macros are disabled (and the column to the left of it is not).
When macros are enabled hide the hyperlink column and show the one to the left of it that will cause the SelectionChange event to run.
(You need to beware how other hyperlinks are used as any cell with a hyperlink next to it will respond to the event. You may need to use intersection to check the cell clicked is in a namedrange that contains "all the cells that need to respond to a user clicking them in the manner".
All the above sounds a bit mad, but it would appear the event model does not facilitate stopping the screen flickering.
I hope there is a better way of doing what you want, but for what it's worth, the above might help.
Harvey

Excel ActiveX ListBox Shrinks with each update

I have a set of linked subs which work like this:
A user types into an ActiveX TextBox
A Change Event in that TextBox calls a sub in a Module
That Module sub drives updating a named range in a sheet
The range value drives updating a table of Excel cells that uses lookup functions based on the range value
The table values are copied and pasted to a another range (to eliminate links to formulas)
That pasted range is put into a ListBox using this (props to Rory for his patience):
ActiveSheet.ListBox1.List = Sheets("Search Criteria Control").Range("G1:G21").Value
The result is that for every character the user types in the TextBox the ListBox is updated.
The problem I have is that the ListBox shrinks a bit with every keystroke in the TextBox referred to in #1 above. Is this normal behavior and I'm misusing ListBoxes, am I doing something wrong or do I need to respecify the dimensions of the ListBox every time it is updated with something like this?
ActiveSheet.OLEObjects("ListBox1").Top = 35
ActiveSheet.OLEObjects("ListBox1").Left = 650
ActiveSheet.OLEObjects("ListBox1").Width = 550
ActiveSheet.OLEObjects("ListBox1").Height = 610
Thanks in advance for any thoughts on this.
I was having trouble with the same thing. My ActiveX listbox would move around on the sheet and change size for no reason that I could see.
While I did go ahead and develop some code to reset size and coordinates, that wasn't satisfactory since there had to be a mechanism to trigger that code - something I didn't want to burden end-users with.
I found a better answer in another user forum. There's a Listbox Property called IntegralHeight whose default property is True - something to do with screen resolution and optimal display of listbox contents. Simply set that to False. I did that with some ActiveX boxes that were giving me fits, and I was able to disable the "adjustment" code and, so far, so good!

Modeless MsgBox, Error trapping, .Find

I have a subroutine that searches for an occurrence of a string in another workbook. I'm trying to get an error message to pop up if the string can't be found (it's most likely due to spelling mistakes), as vbModeless, and allows to user to click on the cell in the searched sheet with the correct value. Then I'd like to resume the search with the new value.
I'm at the moment stuck on making my simple MsgBox to be modeless.
Can anyone help? So far I have (simplified):
With ...
On Error GoTo UserSelect
celladdress = .Range("a1:bb100").Find("searchstring").Address
And my error label:
UserSelect:
MsgBox("Select the cell with the correct spelling") vbModeless
newstring = ActiveCell.Value
searchstring = newstring
Resume
I think it's the Modeless MsgBox giving me grief.
I don't believe that you can use vbModeless with msgbox. That is for use with the Show method of a user form.
What you probably need to do is create a user form that has a refedit control and a button on it. They can then pick a cell with the refedit control. When the user clicks on the button set a public variable on the form with the cell reference the selected.
Then you you need to use ".Show vbModal" on the user form and read off the cell they selected from the form public variable.
Edit:
Actually, you shouldn't need the public variable as the refedit control should be a public property of the form anyway.
I'm not 100% sure on the requirements here. Given a search string of dgo and a worksheet with cells containing bird, cat and dog. Do you want the user to:
(a) edit the cell containing dog and change it to say dgo instead
This would use the modal form and RefEdit control outlined by andynormancx. Like a MsgBox, the modal form pauses the macro until the form is closed
(b) allow the user to click on the cell containg dog and then re-run the search with dog as the search term
This is more complicated. I think that you would need to look at events here. This is fine if your subroutine is pretty much standalone but if it is part of a larger program then this could require substantial rewriting