How to Loop Through ActiveX Checkboxes on VBA - excel

I'm actually trying to make a userform that controls every checkbox in the Workbook Sheets (it's mostly graphs that shows the data from a specific period for the Company), since every graph has the same checkboxes (ActiveX ones) with the same names on them I though about making a Userform that is always active and in this way the client can just select which ones he will use and it would just loop through the other sheets without a problem.
But here is the problem first of all my code:
Dim ws As Worksheet
If Me.CheckBox1.Value = True Then
For Each ws In ThisWorkbook.Worksheets
ws.OLEObjects("chkAno1").Object.Value = 1
Next ws
ElseIf Me.CheckBox1.Value = False Then
For Each ws In ThisWorkbook.Worksheets
ws.OLEObjects("chkAno1").Object.Value = 0
Next ws
End If
I did it with only one checkbox to test it out (There is a "chkAno1" in every sheet that I want to affect) but everytime I run the code and click the checkbox I get " Error 1004: The Method "OLEObjects" from object "_Worksheet" Failed", and what's weird is that If I change "ws" with "ActiveSheet" the code works fine, but only updates the currently open sheet.
So I'm at a loss right now.

thanks for your help. I found out the problem, there was some sheets without any Checkboxes on them, so the Code kept giving me the error.
The solution I found for it was to put On Error Resume Next at the beggining and it worked like a charm! (I actually needed to put it on the graphs as well)
But in the end I ended up reworking the code to affect directly the Graph using ws.ChartObjects("grafico").Chart.FullSeriesCollection(1).IsFiltered = True instead of ws.OLEObjects("chkAno1").Object.Value = 1 Because at the end the process of updating every checkbox and after that all the charts would be actually really slow on some older computers and updating directly the Graph showed a great increase in speed.
Thanks to everyone that Commented and I hope the solution I found can help someone else!

Related

Why Is My Spreadsheet Showing Ghost Images From Another Worksheet After Running My Script

(07/08/21 - I edited my text to update and sharpen the problem).
I have made an Excel VBA program that provides the conditional formatting of a large number of cells (which are formatted using the formulas option which refer to cell values in the target spreadsheet). The script and spreadsheet works fine, but I have a problem as immediately after I have run my script (or to be precise a particular input box script has been run) then ghost images appears. (I can easily replicate the issue including on different Windows machines.) The ghost images no longer happen if the user saves the sheet and then re-opens it. However, to me this is not a good solution and makes the program look poor in quality and trustworthiness!
I have a "first" routine that when run (via a button press) uses an Application.Inputbox - this allows the user to select a range of cells. These selection of cells are located in the target worksheet which is a different workbook to where the code is run from. Also, the selection of cells are located in a sheet that is not the front sheet of the workbook concerned.
I then have another second button which when pressed uses collected data and conditionally formats the target spreadsheet. However, after doing this button press I get ghost images appearing (which shows cells from selection made earlier from the first button press).
The screenshot below illustrates the occurrence - you can see that there is a table being shown from the second sheet on the top left-hand side of the sheet (despite not fitting the cells of screen 1!). I hope that makes sense.
Someone kindly below said that I needed to use:
Application.ScreenUpdating=False
and then return it to true at the end.
However, I still have the same ghost images occur and I note these happen after the script has been run.
From researching the topic, I found that this is a common issue from using the property Application.InputBox. If I run my second program without using the first one immediately before it (which has the Application.InputBox) then no ghost images appear. Therefore, I think it is pretty safe to assume the problem has come from this Application.InputBox! However, I have not been able to find a solution! I list below the code used for the first Application.InputBoxs routine.
Sub UserSelectsCells()
Dim rng As Range
Dim wks As Worksheet
Dim wkb As Workbook
If Range("C9") <> False Then
Workbooks.Open Filename:=Range("C9")
End If
On Error Resume Next
Set rng = Application.InputBox( _
Title:="Select Test Cells", _
Prompt:="Please Find The Cells In Your Workbook That Test Whether The User Has Answered The Questions Correctly" & vbCrLf & "Remember this may be in a different sheet in your workbook" & vbCrLf & "These cells must be in a single column", _
Type:=8)
On Error GoTo 0
'Test to ensure User Did not cancel
If rng Is Nothing Then
Workbooks("Version060821.xlsm").Activate
Exit Sub
End If
Workbooks("Version060821.xlsm").Activate
Range("C32").Value = rng.Parent.Parent.Name
Range("C33").Value = rng.Parent.Name
Range("C34").Value = rng.Address
Range("D35").HorizontalAlignment = xlLeft
Range("D35").Value = rng.Count
End sub
Can anyone please find a solution? As an idea, is it possible to somehow clean the memory before my second program is run?
I note that if there is a ghost images problem and I delete all of the conditional formating then the ghost images still appear. I think this is significant because the conditional formatting is linked to the ghost image cells that appear. So, to me this suggests there is some kind of microsoft bug?
I'm not exactly sure why these ghost screens pop up sometimes but I've found that preventing the screen from flashing during your code normally fixes the issue. You can do this by setting Application.ScreenUpdating to False and the beginning of your code. Just be sure to set it back to True at the end! Something like this:
Application.ScreenUpdating = False
[Your code]
Application.ScreenUpdating = True
edit:
After further research, it would appear this is an issue that has been already identified. The workaround below originally comes from here.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim wSheet As Worksheet
On Error Resume Next
Application.ScreenUpdating = False
For Each wSheet In Worksheets
wSheet.Select
Range("A1").Select
Next
Application.ScreenUpdating = True
End Sub
This is definitely a dirty fix but if it works it works. An alternative solution was to scroll up and down using:
Private Sub worksheet_change(ByVal target As Range)
Application.ScreenUpdating = False
ActiveWindow.SmallScroll Down:=-100
ActiveWindow.SmallScroll Up:=100
Application.ScreenUpdating = True
End Sub
Please let me know what works best!
Not enough rep for a comment!
Alec, Workbook_BeforeClose is a workbook event, you don't call it like procedures.
Workbook_BeforeClose Event
From that documentation, "False when the event occurs. If the event procedure sets this argument to True, the close operation stops and the workbook is left open.". So if you add Cancel=True inside it, say, after an if statement check, you can stop the close operation.
Edit: In order to answer the question in comments.
The event is fired when you close the workbook, either from the X in the corner or from the menu, or if you have something like ActiveWorkbook.Close in your code.
You don't have to have a Cancel=True/False inside BeforeClose event's code, depends on if you want to control a premature closure of the workbook. It is required, say, if you were writing the event yourself instead of selecting it in VBA editor. Editor already inserts that parameter.

Excel crash after Copy and paste Chart image

I Need to Copy an picture/image of a chart which is in another workbook (WbO), and paste the picture in a worksheet in this workbook (TWb), using Excel vba.
I figured out a simple code to do this.
The good thing is that the code works. Stepping line by line throught the code everything completes perfectly.
However, if I run the code (no Stepping) it also runs until the end without any error and completes the job. BUT, by the end Excel Crashes without any error message, restarts and reopens the workbook. (all work lost).
The weirdiest thing is that it crashes 3 to 5 seconds after ending the run. 3 to 5 seconds is an enormous lenght of time for computing. What is it doing during this time??
For testing, I added a 'Msgbox "Completed", vbokonly' as last code line. This made vba stop and show the message, and no crash while the message is on screen. Clicking ok, the macro runs to the end and then, after some seconds ... Crash.
Searched for similar problems in the web and found some old posts refering errors related to copy/paste, but no complete crash like this.
Tried this same file/code in different PCs, both with up-to-date office 365 but different update channels (not same build). The result was exactly the same.
Tried changing the .CopyPicture statement to a normal Copy, and then using PasteSpecial as Picture. Same Result.
Even tried moving the copy/Paste instructions to different subs (suggestion from a 2018 post), and inserting DoEvents in between .. without any luck.
Does someone have a clue why this is hapenning?
How to overcome this issue?
Help welcomed
Sample code below:
Application.EnableEvents= False
Set WbO = /Workbooks.Open("WbOFileName",0)
Set ChrtObj= Worksheets("MyCharts").ChartObjects(1) 'Set handle to the Chart obj
TWb.Activate ' Activate destination Workbook = The Wb which contains the macro
ChrtObj.CopyPicture
RangeToPasteOn(1,1).Select ' Select Top-Left cell to paste the Chart on
ActiveSheet.paste ' Paste the Chart
' ... here Code to ajust Size and position to fit destination range
Application.CutCopyMode = False
Set ChartObj = Nothing 'Release handle
WbO.Close
Set WbO = Nothing
Application.EnableEvents= True

Why additional excel window appears

Scenario
I am using a macro whereby I use Application.Visible = False to hide the workbooks. Also I use Application.Visible = True to unhide the workbook. At certain situation, I use Windows(ThisWorkbook.Name).Visible = False and Windows(ThisWorkbook.Name).Visible = True to hide and unhide only the workbook which contains macro.
Problem
I noticed during these operations, some additional excel windows(without any workbook) appear other than the workbook. Please see the picture below. You can see a grey window behind with a name Excel. That is the window I am talking about
If I closed that window, the whole excel will close. Does anyone know why this extra window appearing and how to prevent it from appearing?
I am not sure if this will meet the needs of your specific situation. But, what if you kept Application.Visible = False at the beginning of your code and changed Application.Visible = True to
Application.Windows(ThisWorkbook.Name).Visible = True at the end. This worked for me.
Hiding Excel
With the following code
Sub AppVisibleTrue
Application.Visible = True
End Sub
Sub AppVisibleFalse
Application.Visible = False
End Sub
you are showing or 'hiding' the 'whole' excel application, so you have to 'unhide' it in the same code, otherwise you won't be able to use the open files after you hide it, e.g. open a new workbook, in VBE add a new module and paste the above code into the module. Now, stay in VBE!!! Run the 'False' Sub. You will notice Excel has 'vanished', but you can still find it in the Task Manager's processes. Now run the 'True' Sub. Excel has 'reappeared'.
The following process will make Excel 'vanish'. The only way to close it will be via the Task Manager. If you not too familiar with doing this, just take my word for it.
Close the VBE. Now run the 'False' Sub. Excel has 'vanished'.
To conclude, this is obviously an error in your code, so I would suggest if you want to show a window (worksheet) that isn't 'ThisWorkbook' and you're dancing from one to the other, you should declare a variable
Const strSheet as String = "Sheet2"
Dim oSheet as Worksheet
'...
Set oSheet = ActiveWorkbook.Worksheets(strSheet)
Now you do with oSheet whatever you want.
Try to lose Active, Select and similar methods in the code.
If you would provide the actual scenario with the codes, a better assessment of the problem could be done.
The additional Excel window(s) could be related to your Windows Explorer. If you are previewing a document (in this case an Excel document) then the application to view that document is running in the background.
In this case, forcing the application to be visible will also make the background "preview" windows visible.

Unexpected results from a Worksheet.Activate event

I’m running excel 2010 on windows 7.
The following macro does what you would expect, ie (1) inserts a new worksheet, (2) adds a rectangle, and (3) activates cell A1.
Sub addSheetAndButton()
Dim buttonSheet As Worksheet
Set buttonSheet = ThisWorkbook.Sheets.Add
buttonSheet.Shapes.AddShape(msoShapeRectangle, 100, 100, 100, 50).Select
buttonSheet.Range("A1").Activate
End Sub
My problem is when I try to run it with a Worksheet.Activate event, for example:
Private Sub Worksheet_Activate()
Call addSheetAndButton
End Sub
This time (1) a new worksheet is not inserted, (2) the rectangle is added to the worksheet associated with the activate event, (3) cell A1 is not activated and (4) the rectangle remains activated.
What am I doing wrong? Any help would be greatly appreciated.
Thanks very much for trying this. I’m sorry it has taken me a while to get back, but I’ve been experimenting with this. I have discovered that when I exit and restart Excel, the addSheetAndButton macro works as expected under the Worksheet.Activate event. However, I have a different macro that uses another Worksheet.Activate event to update some charts. On what seemed to be a random basis, this would create a “run time error 6” - an overflow that resulted from trying to assign an out of bounds value to a variable.
I never got this error if I bypassed the Worksheet.Activate event/macro and ran the chart update macro by hand. After resetting VBA/Excel from the “run time error 6”, the addSheetAndButton macro behaved exactly as I described in my original post. The only way to cure it was to exit and restart Excel.
I think (hope) that I have traced the source of the run time error back to a line in my chart update macro where I had selected rather than activated a worksheet before reading data from it – though I am surprised at the result. It is worth pointing out that once Excel entered the “not as expected” state, the on-screen message from the following two lines was the name of the previous active sheet and not “Sheet1”.
Worksheets(“Sheet1”).Activate
Msgbox ActiveSheet.Name
Again, the only apparent way to cure this was to exit and restart Excel.
Thanks again for your help.

Problem with adding event code to newly created sheet

I have a problem with adding an event code to a newly created sheet.
The problem seems to only occur right after I open the Excel workbook.
I use
Dim codemod As Object
codemod = ActiveWorkbook.VBProject.VBComponents(Worksheets("Sheet4").CodeName).CodeModule
to add the code to the created sheet module but when I try to run this code right after opening the Excel workbook it gives me an error: run-time error '9' Subscript out of range. The debug points to the codemod line.
The weird part is that this error does not come up again when I change the code just a tiny bit and then change it back to the original state. After I do this the code runs as it should i.e. inserts code to the newly created sheet.
Anyone got any idea what may be the problem?
There is not much else to the code except inserting the lines but that does not seem to be the problem.
Thanks in advance
(This is my first action on S.O. so please don't shout at me when I'm doing things wrong.)
Did you concider preparing a workbook + sheet with the desired event code (Test1.xls-Sheet1). Then, in the target workbook (Test2.xls), copy that prepared sheet. The code in the target workbook would look like
Sub Demo1()
Workbooks.Open "Test1.xls"
Sheets("Sheet1").Copy After:=Workbooks("Test2.xls"). _
Sheets(Workbooks("Test2.xls").Worksheets.Count)
Workbooks("Test2.xls").Activate
End Sub
This obviously is a workaround but it works instantly.
A second option could be to prepare the 'workbook-with-one-sheet' and save it as a (sheet) template in D:\Documents and Settings\User\Application Data\Microsoft\Excel\XLSTART. In that case the code can be
Sub Demo2()
Sheets.Add Type:="Test1"
End Sub

Resources