Excel VBA forcing selection of objects after run - excel

I've researched this to death and feel like I'm the only person it's ever happened to.
I have some VBA that:
Creates a copy of 3 sheets to a new wb
In the new wb converts to values, deletes objects (shapes and controls) and all but 3 ranges
Opens an existing third file and sets the contents of three ranges in that to match the new wb
Closes the existing file (saved)
Closes the new wb (saved)
Gives a message box saying complete
At the end of all this, something weird happens with the state of the windows. The selected cell does not appear selected. If I try and click a control afterwards, it selects the object (hence users could drag them). It shouldn't and this is the big problem.
I've tried selecting a cell through code, it throws an error. I had limited success by forcing drawing mode off using Call CommandBars("Drawing").Controls("Select Objects").Execute and activating a specific sheet & selecting a cell. However, even then if I even click on a few cells afterwards, the next time I select a control it will select it as an object rather than click the thing.
I have no idea why and can't find anyone who's seen this before.
Any ideas on what I can do?
Thanks,
Basil

I didn't figure it out entirely, but I did find a fix. Hopefully it works for anyone else who finds this problem.
At the end of the code I added this:
ActiveSheet.Shapes.Range("ctrlExportPrices").Select
ActiveSheet.Range("B8").Select
So it forced a control on the sheet to be selected, and then a cell.
The next time I select the control manually, it clicks it rather than selecting the drawing object.

Related

ComboBox values disappears

I have a sheet in excel with some comoboxes (I have three). The purpose of these are just for someone to be able to choose three different values (i.e. one value in every comobox) and then I have made some VBA code which retrieves some data and plots some graphs.
However, the problem is that I want the comoboxes to have a specific value every time someone either open the sheets or runs the daily update (the sheet is in a big excel file with multiple sheets which is updated on a daily basis). I have made the VBA in such a way that it remembers whatever you just pressed before, i.e. if you choose X in combobox1, Y in combobox2 and so on it remembers this. This is done by I first make a variable which I set to be equal to the value of ComboBox1, i.e. X = ComboBox1.Value and then just before the sub ends I set ComboBox1.Value = X. This works perfectly.
However, for some reason, I am not able to set some standard value for every combobox when opening the excel file for an example, i.e. by making a Workbooks_Open Sub in ThisWorkbook and manually setting the combobox values, i.e. ComboBox1.Value = "something". This is since if I go to the sheet where the the ComboBoxes are, and then afterwards go to another sheet, and then back to the combobox sheet, then the ComboBox values have disappeared.
This do not happen when I run the sub where the data is retrieved. Therefore, I thought I could just run some sub (when the excel file is updated) which manually sets the values of these combobox to something specific I choose. But again, when I go to another sheet and then back to the combobox sheet the combobox values have disappeared again. I don't understand why.
Any help to solve this is very much appreciated. Thanks.

VBA Button Application.Caller returning wrong row

I try to use the following command on several buttons in different worksheets of myexcel workbook.
MsgBox (ActiveSheet.Shapes(Application.Caller).TopLeftCell.row)
When copying those buttons to another area of my workbook, I sometimes have the problem that still the row number of the original button location is displayed. As example in the screenshot below, I click the button at the bottom, but it return row 705 instead of 739. Can anyone explain this behaviour?
Make sure all your buttons have unique names. Somtimes it can happen that copied buttons have the same name (due to a bug in Excel). Then VBA cannot distinguish them and uses the first one that it finds. Check all your button names and make sure they are unique.
This issue can be reproduced easily:
Open a new workbook
Add a button (FormControl)
Name it MyButton
Copy that button
Paste it somewhere else in the same sheet
Use the code from the question for both buttons
The button will now always show the row of the first button, because both have the exact same name.
Image 1: Illustration how this issue can occur. In the end both buttons show the same row value. Because they have the same name VBA only can find the first one.
The soulution is, when ever you copy a button immediately make sure you rename it to a unique name.
It never happened to me to copy a shape with the same name. Only its Caption remained... But, since people says it is possible, try assigning this code to all the shapes in discussion, please. If the shape double name would be the reason, the code will return twice:
Sub callButName()
Dim sh As Shape
For Each sh In ActiveSheet.Shapes
If sh.Name = Application.Caller Then MsgBox sh.TopLeftCell.Address
Next
End Sub

How to fix run time error 400 which occurs only in shared mode of excel via VBA code

I really don't know what causes error 400.
Below code runs perfectly fine in normal mode but as soon as i enable my excel in sharing mode and tries to user form, it gives me VBA 400.
What i am trying to do here is to change shape's text and disable its OnAction event, once user form is shown to user. so that another user accessing same file will come to know that someone is using "User Form" to enter data.
Dim shp As Shape
For Each shp In ActiveSheet.Shapes
If shp.TextEffect.Text = "Sort Customer" Then
shp.OnAction = ""
shp.TextEffect.Text = "Wait!!!"
End If
Next
Q. Is there any way to publish changes made by any user in shared excel automatically.
I suspect that your code falls in one of the numerous limitations of Excel shared mode, described here (see unsupported features), including
Using a data form to add new data
Using drawing tools
Inserting or changing pictures or other objects
(Please note that, due to its format, I could not easily copy that list of unsupported features in my answer.)
As far as I know, in order to keep the changes you should choose if the first one who introduces the data rules or you will choose in case of conflict. As you are looking for an "automatic" way, you should chose the first one.
You can find a good explanation described here
At Review > Share Workbook , Advanced Tab. At "Conflicting changes between users", you should chose "The changes being saved win". So as the data are introduced and saved, they are reflected.
Hope it helps.
Create a vba function in the sheet (NOT A MODULE) where users can activate the user form:
insert the following function there:
Function HyperlinkClick()
'source: https://stackoverflow.com/a/33114213/11971785
Set HyperlinkClick = Range("B2")
If HyperlinkClick.Value = "Sort Customer" Then
'sets info on WAIT
HyperlinkClick.Value = "WAIT!!!"
'shows userform
UserForm1.Show
Else
'sets info back to normal value
HyperlinkClick.Value = "Sort Customer"
End If
End Function
In the user form you can add an userform_terminate Event, which automatically changes the value in B2 back (I guess you could also do that for an workbook Close Event be on the safe side).
Private Sub userform_terminate()
'Code goes here
Range("B2").Value = "Sort Customer"
End Sub
In Excel now create a "Frontend" such as this:
and add the formula:
=HYPERLINK("#HyperlinkClick()";"Click")
to the cell where a user needs to click to open the UserForm (in this case to D2).
If you now share the workbook and click on "Click" in D2 an Event is triggered and the VBA Function "HyperlinkClick()" is called. In this function you can essentially do anything now.
Explaination:
Instead of using a graphic, button etc. which will not work correctly in shared mode, we can simply use links (which work) to trigger an Event.
Instead of "creating" and "deleting" Hyperlinks (which also does not work in shared mode) we simply build dynamic links which Point to userform.show or to nothing, depending of the situation.
Error 400 Problem: Should be solved by skipping the modify object part of the code.
Multiple User Problem: Should be solved, since only one user can activate the userform.
Is there any way to publish changes made by any user in shared excel automatically.: I guess so, please provide more information on what exactly you want to achive (incl. example).
Tip:
In General you might want to check out MS Access since it has as default feature multi-user Access and users there can use the same form at the same time, since the users only get exclusive Access for specific datapoints not the whole table/workbook or file.

Error: Can't move focus because it is invisible

I have the following code that works in all other circumstances except in a single where it returns the error Can't move focus because it is invisible, not enable, or type that does not accept focus. The data in sheet consists only basic numbers and words. My objective is to select a range from one work book and paste it to another. It appear that excel does not recognise anything to be in the cells, although there in fact is. Does anyone know why this may be happening?
Set Users = Application.Workbooks.Open(PathA)
With Prices
.Sheets("Sheet").Range("A:AJ").Select
Selection.Copy
End With
'Set Risk = Application.Workbooks.Open(PathX)
With Risk
.Sheets("Sheet").Range("A1:AJ1048576").PasteSpecial Paste:=xlPasteAll
.Save
' .Close
End With
Users.Close
it looks like someone else had the same issue and was able to resolve it on an MSDN forum
http://social.msdn.microsoft.com/Forums/office/en-US/3263b079-7e4f-452c-8dcc-92c682b8370b/excel-form-cant-move-focus-to-the-control-because-it-is-invisible-not-enabled-or-of-a-type-that?forum=exceldev
maybe this fix will apply to your situation too.
... OK so on that page, one guy has a kludge that seemed to work for him:
Error was:
Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus.
How to Fix
1. Select the object with the problem, e.g. the Form or Control.
2. In the properties windows, select the name of the object and rename adding an "x" to the end, e.g. Rename CPanel to CPanelx.
3. Save the Form.
4.Now rename the CPanelx back to CPanel.
5. Run your form.
6. Problem solved.
Something screwy with Excel VBA, not sure what !, but this will get you working again.
Steve D.
and then someone else described the underlying problem, but his solution involved using design mode, which seems like it is maybe defeating the purpose of automating in vba, but the moderator seemed to like his answer better, so here that is as well
In normal use activeX controls are intended only to be activated, not selected, there's a difference. If you partifcularly want to Select the control (manually or with code), try putting Excel into Design mode first.
See also the topic "Why can't I select form and ActiveX controls?" in Excel's help (not VBA's help)
Peter Thornton
"Run-time error '-2147352565 (8002000b)': Can't move focus to the control because it is invisible, not enabled or of a type that does not accept the focus" Can be overcome but sequentially defining the area you wish to select. Obviously some may do this in any case, but it this specific instance it is needed to overcome the issue. This is an example for copying from one workbook to another and pasting where U is the sheet excel finds to be "invisible".
Dim U As Workbook
Dim Us As Worksheet
Set U = Application.Workbooks.Open(Path)
Set Us = U.Worksheets("sheet")
With Us
.Range("A:AJ").Select
Selection.Copy
End With
U.Close SaveChanges = True
With DestinationWorkbook
.Sheets("sheet").Range("A:AJ").PasteSpecial Paste:=xlPasteAll
.Save
End With
Just to help in case you didn't find the answer till now :
In my case this message came out when I redimensioned the application window while it was maximized :
e.g. Application.width = 100 (on Excel 2003 or 2007)
The solution in this case, is to first bring the application window to NORMAL.
e.g. ActiveWindow.WindowState = xlNormal

Excel combobox listfillrange property pointing at a formula-based named range has issues

ActiveX combobox objects in Excel do not behave well when their ListFillRange refers to a formula-based Named Range (Defined Name).
I think I have encountered other errors and possibly even Excel crashes thanks to this, but right now all that happens is the combobox_change() event is triggered anytime ANY cell in the workbook is changed.
I am not sure if this is really a bug, or if there is a fix, or a workaround. If it is a bug, how do I report it to the Excel people?
And finally, the real meat of my question is "How do I work around this issue best?" I would like to have some formula-based named ranges, but it seems like this won't be possible.
To reproduce this bug, do the following:
Create a new workbook. On Sheet3, create a small table 3 columns across, and several rows high.
Create a named range with this formula (or an equivalent): =OFFSET(Sheet3!$A$2:$C$36,0,0,COUNTA(Sheet3!$A:$A),COUNTA(Sheet3!$4:$4)) To do this use Input>Name>Define. Name the range something like "demoRange"
Go to Sheet1 and create a combobox, (it must be on a separate sheet). (Use the Control Toolbox menu, not the Forms menu).
Click on the Design Mode button (the blue triangle with pencil), then right click on the combo box and go to Properties.
In the properties window for the combobox, change the ListFillRange property so that it points at the named range you created in step 2 ("demoRange").
You may want to change the ColumnCount property to 3, and the ColumnWidths property to "50,50,50"
Set the linkedCell property to cell "A1" by typing A1 in the linkedCell property.
Close the properties window, and double click on the combobox to define its change() event.
Put a Debug.Assert(false) or Msgbox("demo") line in the subroutine for the new combobox's change event.
Exit design mode
important - Now select an item in the combobox. The event should trigger normally the first time. (The bug will not show if you don't do this step--something must be selected in the combobox)
Edit cells anywhere in the workbook [Edit] or any other open workbook [/edit], on any sheet and any location. Each time you edit any cell, (at least for me), the onchange event for the combo box is run.
Again, is this normal, and what is the best alternative for what I am doing? This combo box gets linked to various cells, and is supposed to be a replacement for the tiny font in the data validation dropdowns excel provides by default.
My advice is to never use ListFillRange and LinkedCell. They are just trouble. Fill your listbox with List and use the Change event to write to the cell. Somewhere, maybe the Workbook_Open event, fill the listbox
Private Sub Workbook_Open()
Sheet2.ListBox1.Clear
Sheet2.ListBox1.List = Sheet1.Range("demoRange").Value
End Sub
Then in the change event in the Sheet2 module, check that something was clicked and write it to the cell
Private Sub ListBox1_Change()
If Me.ListBox1.ListIndex >= 0 Then
Sheet2.Range("A1").Value = Me.ListBox1.Value
End If
End Sub
I have a few options available that I am aware of thus far. The best I can come up with is this:
Avoid directly using formula-based named ranges. Instead, define a subroutine that will check whether the defined range "demoRange" should be changed from what its current value is. Run this subroutine on the workbook_open and sheet3_deactivate events. If needed, prompt the user to ask if it's all right to update the named range. [edit] The macro that updates "demoRange" could probably just copy from a "demoRange_FormulaBased" named range into "demoRange" which would be static. [/edit]
This solution works well because you can keep using the linkedcell property, you don't have to use VBA to populate the comboboxes, and the named range can still be used for whatever other purposes it already had. Avoid using the onchange event to run this new subroutine, since it might end up being triggered thousands of times if a user opens the Find/Replace dialog and chooses "Replace All".

Resources