Excel VBA ActiveX ListBox not allowing click - vba

I've created a bit of code that populates an Excel sheet with Lables, TextBoxes and a ListBox. After populating the ListBox with .List=Sheets().Range().Value I am unable to click to select an item. If I save the sheet, close and reopen it works fine.
I've checked
http://blogs.technet.com/b/the_microsoft_excel_support_team_blog/archive/2014/12/11/forms-controls-stop-working-after-december-2014-updates-.aspx
But I'm not getting an error so this seems the wrong fix.
When I search KB for the following
http://support.microsoft.com/kb/3025036/EN-US
The symptoms are different from what I'm experiencing.
I also tried using Sheets().Activate as posted here:
Excel ActiveX Listbox not enabled on file open
But that didn't help or I'm implementing it incorrectly.
This is the code that creates the ListBox
Private Sub Create_ListBox_ActiveXControlProperties()
Dim oLISTBOX As OLEObject
Set oLISTBOX = ActiveSheet.OLEObjects.Add(classtype:="Forms.ListBox.1", Top:=35, Width:=500, Left:=650, Height:=600)
ActiveSheet.OLEObjects("ListBox1").Object.Font.Size = 14
ActiveSheet.OLEObjects("ListBox1").Object.ListStyle = 0
ActiveSheet.OLEObjects("ListBox1").Object.List = Sheets("Search Criteria Control").Range("g1:g21").Value
End Sub
Can anyone suggest where I can look for a solution to this?

Can't give you an explanation but if you add Activesheet.Select to the end of your Sub then you can select your items.

Another way of writing:
Sub M_snb()
With ActiveSheet.OLEObjects.Add("Forms.ListBox.1", , , , , , , 35, 50, 65, 60)
.Object.Font.Size = 14
.Object.List = ActiveSheet.Range("g1:g21").Value
.Object.ListIndex = 0
.Parent.select
End With
End Sub

For the purposes of documenting all possible solutions, here is what worked for me.
None of the workarounds provided in all forums helped me.
I added a bunch of ListBoxes dynamically including location, height, width, ListRange etc. When my code would create the controls in the Worksheet, I wasn't able to select the items in the ListBox.
This is what solved my problem: .OLEObjects().Activate
You need to activate the control soon after creating it.

Same issue there. As a workaround(app.activate don't works for me and the bahavior isn't wished), you can just add 1 to the height, it will sligthly redraw each object and réactivate it.
ListBox_Options1.Height = ListBox_Options1.Height + 1
It's a workaround, not the source of the bug.

Related

Saving Custom Document Properties in a Loop

I'm trying to save the values of data that have been input into my form. There are a total of about 50 different fields to save across 5 different agents, so I loaded the data into arrays.
I've tried saving the fields in a loop, but it doesn't seem to work in a loop, only if each field has a separate line, which is a lot of code and messy. The Ag1Name, Ag2Name and Ag3Name are the names of my textboxes that the user enters to populate the form.
Sub LoadAndSaveData()
NumberofAgents = 3
Dim AgentName(3) as String
AgentName(1) = Ag1Name.Value
AgentName(2) = Ag2Name.Value
AgentName(3) = Ag3Name.Value
For Count = 1 To NumberOfAgents
With ActiveDocument.CustomDocumentProperties
.Add Name:="AgentName" & Count, LinkToContent:=False, Value:=AgentName(Count), Type:=msoPropertyTypeString
End With
Next Count
End Sub
The data doesn't get saved to the Custom Document Properties when the code is set up in a loop like the above. Since there are so many values to save and all the data is already in arrays, I would much prefer to use a loop rather than write out a separate line of code for all ~50 of the values. It does seem to work when each field is saved in a separate line of code.
I think this would probably get what you want. You don't really need to count the document properties first, only increment with the ones you want to update. Hopefully the only document properties you want contain the name AgentName in it.
ReDim AgentName(0) As String
Dim P As Long
For Each c In ThisDocument.CustomDocumentProperties
If InStr(1, c.Name, "AgentName", vbTextCompare) > 0 Then
ReDim Preserve AgentName(P)
AgentName(P) = c.Value
P = P + 1
End If
Next c
As a guest I cannot post a comment here, but the code you gave works OK here.
However, there is a problem with creating legacy custom document properties programmatically, because doing that does not mark the document as "changed". When you close the document, Word does not necessarily save it and you lose the Properties and their values.
However, if you actually open up the Custom Document Property dialog, Word does then mark the document as "changed" and the Properties are saved.
So it is possible that the difference between your two scenarios is not the code, but that in one scenario you have actually opened the dialog box to check the values before closing the document and in the other you have not.
If that is the case, here, I was able to change this behaviour by adding the line
ActiveDocument.Saved = False
after setting the property values.
If you do not actually need the values to be Document Properties, it might be better either to use Document Variables, which are slightly easier to use since you can add them and modify them with exactly the same code, or perhaps by storing them in A Custom XML Part, which is harder work but can be useful if you need to extract the values somewhere where Word is not available.
You can make this even easier by looping the controls on the UserForm, testing whether the control name contains "Ag" and, if it does, create the Custom Document Property with the control's value - all in one step.
For example, the following code sample loops the controls in the UserForm. It tests whether the controls Name starts with "Ag". If it does, the CustomDocumentProperty is added with that control's value.
Sub LoadAndSaveData()
Dim ctl As MSForms.control
Dim controlName As String
For Each ctl In Me.Controls
controlName = ctl.Name
If Left(controlName, 2) = "Ag" Then
With ActiveDocument.CustomDocumentProperties
.Add Name:=controlName, LinkToContent:=False, value:=ctl.value, Type:=msoPropertyTypeString
End With
End If
Next
End Sub
I feel a little stupid... I just realized that the reason that the code wasn't working was that the variable NumberofAgents was not being calculated correctly elsewhere in my code. I've got it working now. Thanks for your thoughts!

Excel VBA: Updating userform position/size leaves trail

I am fairly familiar with userforms, so I decided to try and get a little fancy and attempted to make a userform grow/shrink and reposition to align center based on a checkbox change event.
The code is working as intended, but there is one issue. When shrinking the userform, the userform leaves a trail of all size increments set during the loop. This makes the program look less "smooth". I've included a screenshot of the issue as well as the relevant code.
I've tried including variations of DoEvents and Application.ScreenUpdating. ScreenUpdating seemed to do nothing, while DoEvents halved the number of trails, but also made the text inside the userform go a bit crazy during execution.
Note: The checkbox is named "MyCheckBox" and the userform is named "ColumnSelect"
Perhaps I'm trying to do too much with excels memory or w/e.. Any help is appreciated though. Thank you!
Private Sub MyCheckBox_Change()
Dim w As Integer
Application.ScreenUpdating = False
If MyCheckBox.Value = True Then
For w = 425 To 838 Step 7
ColumnSelect.Width = ColumnSelect.Width + 7
ColumnSelect.Left = ColumnSelect.Left - 3.5
Next w
Else
'DoEvents
For w = 838 To 425 Step -7
ColumnSelect.Width = ColumnSelect.Width - 7
ColumnSelect.Left = ColumnSelect.Left + 3.5
Next w
End If
Application.ScreenUpdating = True
End Sub
I have tested the file on my home (gaming) of, which is much more powerful than the laptop/monitor setup I used when posing the question. There was no visible trail when resizing the user form, so it seems user A.S.H was correct in his assumption that the issue involved the PC/monitor rather than the code.
If you want credit for the answer I will be happy to give it to you, just submit your own. Otherwise I'll mark this as answerws. Thanks for your help

VB.Net equivalent for (CustomizationContext) in VBA

I'm busy with some word automation and have run into an issue whereby a context menu within a document has items in, that I wish to remove.
Once the document is open, through vba I can remove these items by running the following code;
[VBA]
Dim oContextMenu As CommandBar
Dim oContextMenuItem As CommandBarControl
'Make changes to the ActiceDocument only (this is needed to make any changes to this document).
CustomizationContext = ActiveDocument
For Each oContextMenu In ActiveDocument.CommandBars
If oContextMenu.Type = MsoBarType.msoBarTypePopup Then 'Loop through all the context menus of type (msoBarTypePopup)
For Each oContextMenuItem In oContextMenu.Controls
If (InStr(oContextMenuItem.Caption, "Smokeball")) Then
oContextMenuItem.Delete
End If
Next
End If
Next
If I execute this code and check the document, all contextMenu sub items that contain the text "smokeball" are removed.
When I try move this code to my VB.NET solution (I have no choice of language, so VB it is), I get errors on the CustomizationContext = ActiveDocument line (this line has to be there for it to affect the current document).
The error I get is CustomizationContext' is not a by reference property.
Does anyone know how to get just that ONE line equivalent for vb.net?
Thanks in advance.
EDIT: In case you need to see the vb.net sub:
Private Sub RemoveUnwantedContextMenuItems()
Dim oContextMenu As CommandBar
Dim oContextMenuItem As CommandBarControl
'Make changes to the ActiceDocument only (this is needed to make any changes to this document).
WordApplication.CustomizationContext = WordApplication.ActiveDocument 'This is the error.
For Each oContextMenu In WordApplication.CommandBars
If oContextMenu.Type = MsoBarType.msoBarTypePopup Then 'Loop through all the context menus of type (msoBarTypePopup)
For Each oContextMenuItem In oContextMenu.Controls
If (InStr(oContextMenuItem.Caption, "Smokeball")) Then
oContextMenuItem.Delete()
End If
Next
End If
Next
End Sub
PS - I have also already tried using the .AttachedTemplate as well as .Normal / .NormalTemplate
Jules pointed me in the right direction with his sample code.
After lots of playing around I noticed that somewhere in the solution, the [TYPE] of WordApplication was getting changed to a dynamic type of sorts, hence, it couldn't use CustomizationContext.
My solution was this:
I changed this line;
WordApplication.CustomizationContext = WordApplication.ActiveDocument
To this:
CType(WordApplication, Microsoft.Office.Interop.Word.Application).CustomizationContext = WordApplication.ActiveDocument
Forcing the types to be correct.
Simple solution but took some time.
Thanks to Jules for pointing me in the right direction.
(Points should go to you).

Programming VBA in an Outlook form

I created my own Outlook form to use it as standard surface to enter certain orders instead of the normal message form. The creation, editing and sending works perfectly fine and in the next step I want to insert some code via VBA.
My problem is that I can´t access the objects of my form in the VBA editor. E.g. I want to show a message box when a certain checkbox is checked. According code would be:
Sub example()
If CheckBox1.Value = True Then
MsgBox("Checkbox 1 is checked.")
End If
End Sub
When I run the code I get the error that the object could not be found. The same goes for every other object, like textboxes or labels etc.
I guess the solution is pretty simple, like putting Item. or sth. like that in front of each object. But so far I wasn't able to find the solution.
I´m using Outlook 2010.
I know this is a year too late but you'll want to do something like this example below. It's kinda a work around but you can get whatever value was selected.
Sub ComboBox1_Click()
Set objPage = Item.GetInspector.ModifiedFormPages("Message")
Set Control = objPage.Controls("ComboBox1")
MsgBox "The value in the " & Control.Name & _
"control has changed to " & Control.Value & "."
End Sub
You should be able to get the value, just get a handle on the object you want using the Inspector
The following is an excerpt from here
When you use a custom form, Outlook only supports the Click event for
controls. This is a natural choice for buttons but not optimal for
controls like the combo box. You write the code by inserting it into a
form’s VBScript editor. You need to have the Outlook form open in the
Form Designer and click the View Code button found in the Form group
of the Developer tab.
Sub CheckBox1_Click()
msgbox "Hello World"
End Sub
The code page is fairly minimal with no syntax highlighting. I just tried this now and it does work. Dont forget to Publish your form to pick up the new changes.
I know this is almost 6 years late but, in VB and VBA, simply start with the form name. (And if that doesn't work, just keep going up a parent object and you'll get there.) So, your code becomes:
Sub example()
If MYFORMNAME.CheckBox1.Value = True Then
MsgBox("Checkbox 1 is checked.")
End If
End Sub
Of course, after typing "MYFORMNAME." you'll know if it will work because typomatic will kick in when the system recognizes "MYFORMNAME" after you hit the period.

Why Won't My Macro/VB run from in my PowerPoint presentation

I'm trying to add a little interaction to a PowerPoint presentation I'm working on. I'm written a little VB that will increase the size and position a particular chart object when the script runs. I'm tested the script in design mode and everything seems to work fine. When, however, I link my code to an action button and try to run it from within the slide show the code does not run. I do most of my VB in Excel so I have not run across this before. Can anyone suggest a fix for this. My code is set forth below:
Sub MoveChart23()
Dim s
For Each s In ActiveWindow.Selection.SlideRange.Shapes
If s.Name = "Chart 23" Then
s.Top = 50
s.Width = 620
s.Left = 50
s.Height = 400
End If
Next
End Sub
Thanks for your help.
Anyway, I think your problem is in the following line:
For Each s In ActiveWindow.Selection.SlideRange.Shapes
while you have no Selection in presentation mode. Depending on the way you run and control the whole presentation you should use something like this instead:
For Each s In ActiveWindow.Slides(1).Shapes
But if you need to refer to currently viewed slide you should go this way:
For Each s In SlideShowWindows(1).View.Slide.Shapes