How to Retrieve hidden sheets in an Excel add-in? - vba

I have built an Excel add-in using VBA. I have used 2 sheets containing some data while creating this add-in. When i saved it as an add-in, both sheets became hidden while add-in still works. Now i want to make few changes in the data of those sheets and code as well. How can i see those sheets hidden in add-in? Here is an screenshot attached. Here it is clear that there are two sheets ( Sheet1,Sheet9) are present but not visible. how can i retrieve these sheets?

Select ThisWorkbook. In the Properties pane, set the IsAddIn value to False. This will make the add-in's workbook (including all its sheets) visible and you can make changes to the data.
Caveat: You won't be able to save the workbook normally; doing so will give you an error and then a prompt to save it with a new name.
What you need to do instead is this: Once you have made the changes to your data, set the IsAddIn property of the workbook back to True. That will make the sheets hidden again. You can then save your add-in project from within the VBA editor.

The file would not let the user save a xla/xlam file if ".IsAddin" is false (worksheets add-in must be hidden to be saved)
If you want to use the add-in but let the user see the hidden sheets by code instead of manually you can use the following:
Sub Showbutton()
If ThisWorkbook.IsAddin Then
ThisWorkbook.IsAddin = False
End If
End Sub
Sub Hidebutton()
If not ThisWorkbook.IsAddin Then
ThisWorkbook.IsAddin = True
End If
End Sub
An Excel Error Measage will be shown but it will work after the user presses 'oK'
UNSOLVED-Suppress an Excel Error message caused by save button before going into Workbook_BeforeSave event
Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Not ThisWorkbook.IsAddin Then
ThisWorkbook.IsAddin = True
End If
End Sub

Related

Cannot close workbook after running sub with userform

I have a macro that opens a userform to capture a start and end date. After clicking OK on the userform, a file dialog box opens to select an Excel Workbook to open.
Immediately after I run the below sub, I can't close the workbook that is opened by using the 'X' in the top-right corner. I also can't save the workbook by clicking the save icon.
However, if I click on another workbook or switch to a different sheet in the workbook that was opened, and then click back to the one opened by the sub everything works as it's supposed to.
Also, I replace the userform with two input boxes, to capture each of the two dates, I am able to close the workbook that is opened with no issue.
Maybe there's something funny with the userform code?
This is all that is in the userform.
Private Sub Ok_button_Click()
call module1.forecast
unload userform1
end Sub
And this is the main sub.
Sub forecast()
dim start_SFY as long
dim end_SFY as long
dim filesToOpen as object
dim wb as workbook
Application.ScreenUpdating= False
start_SFY = userform1.textbox1.value
end_SFY = userform1.textbox2.value
set filesToOpen = application.fileDialog(msoFileDialogOpen)
filesToOpen.show
set wb = application.workbooks.open(filesToOpen.selecteditems(1),false)
Application.ScreenUpdating= True
End Sub
Here's the sub showing userform1
Sub run_userform()
userform1.show
End Sub
Also, here is the Excel version:
Excel 2013 64-bit (15.04753.1003) Part of Microsoft Office 365 ProPlus
Can someone maybe try to replicate the issue that I'm having? I'm wondering if this is an issue related to my employer's version of Excel or something?
This sort of thing has never happened to me before.
Also, I can close the program with VBA. It's just when trying to click the 'X' that it won't close.
Update:
I was able to get the code, with no changes, to work fine at home on Excel 2016. I'm going to get a coworker to test on their system today.
When I was home, I didn't put a button to call the sub on a worksheet. I called it from the VBA editor. After some testing this morning, it seems that the button is the issue. If I call the sub from the VBA editor, I can close the opened workbook. However, if I use a command button (form control, not ActiveX as I get an error saying, "Cannot draw object" whenever I try to add any kind of ActiveX object to a worksheet) the opened workbook will not close.
I think I have found the problem
This issue seems to be with the 'form control command button'. ActiveX was disabled in the Trust Center. When I enabled it and created a command button, I was able to close the opened workbook. I then tried the command form button again, and could not close the opened workbook. I was also successfully able to close the opened workbook when I ran the sub from the sub listbox in the developer tab, and when I place the sub in the Excel Ribbon and ran it from there.
Any idea as to why the control form command button would cause this issue?
The root of the problem is the change to using multiple excel interfaces in 2013. Microsoft addresses the issue in the Solutions for SDI Issues section of this page.
A workbook cannot be closed by clicking the red "X" Close button when
that workbook is programmatically opened via a modal user form. To
work around this issue, it is suggested that you add the following
code to the user form Layout event procedure and then open the user
form as modeless
Private Sub UserForm_Layout()
Static fSetModal As Boolean
If fSetModal = False Then
fSetModal = True
Me.Hide
Me.Show 1
End If
End Sub
Another option is to open the workbook window, activate any other
window, and then reactivate the workbook window. You should now be
able to close the workbook using the Close button.
So these are the two options they present and one I came up with.
Option 1) You can switch your dialog to modeless using their code, or by setting the ShowModel property to false in your userform.
Option 2) As you discovered, manually switching between workbooks after opening via modal userform resyncs everything. Not a good solution for the users of my code, and I don't recommend relying on it.
Option 3) It's worth mentioning, if you don't open the file via the userform then there's no issue. So if last thing the userform needs to do is open the file, you can easily save the file path in a string, unload the troublesome userform and move the workbooks.open call after closing. Here's an example of what I mean
Public EDIT_FILE_DIRECTORY As String
Public Sub Main()
fileOpenerForm.Show
If EDIT_FILE_DIRECTORY <> "" Then
Call Workbooks.Open(EDIT_FILE_DIRECTORY)
End If
End Sub
And in the userform something along these lines, where the filename is created based on userform parameters and a listbox selection:
Private Sub OpenSelectedWorkbooks_Button_Click()
Dim workbookName As String
workbookName = selectionList.Item(Me.FileSelection_ListBox.ListIndex + 1)
EDIT_FILE_DIRECTORY = ROOT_DIR & GetSelectedSubfolder & "\" & workbookName
Unload Me
End Sub
Try fileOpenerForm Show 0 to open open it with Modal = False (Makes the macro run while the Userform is visible)
Do not forget to add fileOpenerForm.Hide later on.
Also Load fileOpenerForm and Unload fileOpenerForm may be useful

unable to close opened excel workbook

I am building a excel file with commandbuttons, userforms etc. that contain links to other workbooks.
For the commandbuttons on my sheet I use the same code as for the commandbuttons in my userforms:
workbooks.open "path"
with the userform commandbuttons ater this the following is added
unload me
When I open a workbook via a userform I am unable to close it afterwards. I must activate my workbook first, then activate the opened one and then can I close it
I have tried putting "unload me" befor and after the "workbooks.open" but this doesn't change anything.
I also tried the followin, also didn't work:
unload me
dim wb as workbook
set wb = workbooks.open"pathname"
wb.activate
anyone any ideas?
Example of how it is now:
Someone needs to make a price calculation. they open the prices userform in my file. they click on the button "calculationfile". The calculationfile opens. they make there calculation and now they are finished in the calculationfile. So they want to close it by clicking on the cross. But they can't click the cross. then they switch to my file on the taskbar and then switch back to the calculation file. now they are able of clicking the cross
I dont understand why they can't click it the first time but they can click it after switching between mine and the openend workbook.
I suspect this is due to improper form handling and the "default instance" recreating itself after you unload it. If you don't create your own instance of the form before you show it, VBA will do all kinds of squirrelly things when you use it after it's unloaded.
If all you need to do is open a workbook and unload the form, *don't increment the workbook's reference count before you unload the form. Also, don't attempt to run any other code after you call Unload Me from the form. The code you posted should simply be:
Workbooks.Open "pathname"
Unload Me
Of course the calling code for the form isn't in the question, but it can likely be solved there as well.
Unload only affects a UserForm.
Try adding a reference to the open workbook and then closing it like so:
dim wb as Workbook
set wb = Workbooks.Open "pathname"
wb.activate
' do whatever with it while it's open
wb.Close
If whatever you are doing is not automated, you will need a button on your form that will set the reference to the workbook and close it once the user has completed editing.
If you define the workbooks that you open as a variable - you will be able to close them easily. Keep in mind this does not save the workbook.
Dim DataBook As Workbook
Set DataBook = Workbooks.open ("pathname")
' Do something useful with the file
DataBook.Close
It is not completely clear what you are trying to ask here, but I'll give it my best in providing you a full answer. If you are having no success with the Unload Me statement when it comes to closing a user form, try specifying the full form name in VBA. That is:
Unload UserFormName
If you are trying to close the workbook you have opened (via the user form), you can use the Workbooks.Close method:
Dim wb as Workbook
Set wb = Workbooks.Open(Filename:="C:\example.xls")
wb.Activate
'Close workbook
wb.Close
'Unload form
Unload ExampleForm
More on the use of the Unload statement can be found here:- https://msdn.microsoft.com/en-us/library/aa445829(v=vs.60).aspx
And more on the use of the Workbooks.Close statement can be found here:- https://msdn.microsoft.com/en-us/library/office/ff838613.aspx
I'm not sure what's causing the behavior you describe (inability to click the "Close" X button in the active Excel window). However your current workflow is:
User interacts with form to review/access a file
User clicks a button on the form which unloads the form
User is then expected to manually close out of the file opened in (1)
A better solution would be to remove the third step, and close the workbook from one of the form's event-handlers (UserForm_QueryClose or UserForm_Terminate). Alternatively you could add this to a CommandButton's Click event, but that's not very different than requiring the user to manually close the file.
This could be as simple as:
Private Sub UserForm_Terminate()
' should be called when form Unloads
On Error Resume Next
Workbooks.Close "filename.xlsx"
End Sub
In this manner, the file will be closed any time the user closes or otherwise unloads the userform.
OK I think I found a way around it.
Let's say I have a workbook1 which has a form called ControlPage with command button that opens up workbook2.
Private Sub CommandButton1_Click()
Dim workbook2 As Workbook
Dim workbook1name As String
workbook1name = ThisWorkbook.name
Set workbook2 = Workbooks.Open("workbook2.xlsx")
ControlPage.Hide
Workbooks(workbook1name).Activate
Workbooks("workbook2.xlsx").Activate
End Sub
So basically because 'activate' bit doesn't seem to work properly when I try to activate workbook 2 straight away, I just activate the first, and then the second one ane after another. Twisted but did the trick for me.

Allow user to write in a programmatically created Excel sheet without closing the userform

I programmatically create a new Excel sheet within my VBA application when the user clicks on a button. I would like to allow the user to write this newly created sheet and keep the userform of creation of new sheets displayed in the same time.
EDIT : Additional precision : I use a succession of userforms, the first one is an authentification form, the second one is a functionnality selection menu and the one I mentionned in my question offers one of those functionnalities. Therefore the correct solution to my problem was to show all these user-forms as non-modals.
Show the userform as non-modal:
Userform1.Show False '//<-- Allows user interaction whilst form is active.
Caveat:
Displaying a form as non-modal will allow code execution to resume after the form is displayed - this could result in unexpected behavior and should be considered at design time. For example:
Sub ModalExample()
UserForm1.Show '// Show modal, code will pause here until form is closed.
MsgBox "Userform has now been closed."
UserForm1.Show False '// Show non-modal, code will continue to execute regardless.
MsgBox "Userform is still open."
End Sub
The accepted answer is wrong. The following line of code is incorrect:
Userform1.Show False
The suggestion to display the userform modelessly is a good one for this question's scenario, but to be correct it should be done like so:
Userform1.Show vbModeless <---This is correct.
It is true that both False and vbModeless evaluate to the value zero. HOWEVER, that's just coincidence.
For example, if you were to try the inverse to display the userform modally, it would not work:
Userform1.Show True <---This does NOT work.
But this does:
Userform1.Show vbModal
Never use Boolean values as an argument to a userform's Show method. Instead use the members of the FormShowConstants enum.
I am pretty sure that if a userform is active then it will not allow you to access the worksheet until it is closed.
Couple of ways around this though. Hide the userform until it is needed again. Set it to a keyboard shortcut or something to show it again. So it would be userform.hide then have another macro or a button in the ribbon to show the userform again by using userform.show
Instead of creating a new sheet. Create a new instance of Excel with a new workbook. That would allow the userform to stay open in one Excel instance and then the user can write to the other workbook in the other instance of Excel
To create a new instance of Excel you would need to use the code
Dim objExcel As Excel.Application
Set objExcel = CreateObject("Excel.Application")
objExcel.Workbooks.Add
objExcel.Visible = True
That will create a new Excel instance and still have the userform in the other instance of Excel

Code to run AFTER right click

I want to block out some of the command bar options, but the method I am currently using is a bit too restrictive. I currently use this code:
Sub Auto_Open()
Application.CommandBars.FindControl(ID:=847).Enabled = False
End Sub
Sub Auto_Close()
Application.CommandBars.FindControl(ID:=847).Enabled = True
End Sub
The problem with this is that as long as the workbook that has this code stays open no other workbook can use voided controls. I think a solution might be to use:
Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Application.CommandBars.FindControl(ID:=847).Enabled = False
End Sub
This will stop the user from using my voided controls when they right click, say to delete a sheet.
I now need a way to remove those voids as soon as they click away, so the controls are available to use in any other workbooks they may have open. Is there an event that I can use for this which isn't so common that it will make the code run every 10 seconds? I also wondered whether you can use delays in vba to run a piece of code 5 seconds after a previous piece of code?
In the workbook module in which you want to disable the command bar options enter:
Private Sub Workbook_Activate()
Application.CommandBars.FindControl(ID:=847).Enabled = False
End Sub
Private Sub Workbook_Deactivate()
Application.CommandBars.FindControl(ID:=847).Enabled = True
End Sub
Whenever you are working in the workbook the commands should be disabled. I'm not certain it will work in Excel 2007 because Application.CommandBars.FindControl(ID:=847).Caption is &Delete and Delete is still enabled on both the cell right click and tab right click.
In Excel 2007 you can disable Ribbon commands for the active workbook but it's not easy. You have to change the workbook extension to .zip then edit the .rels file in _rels folder within the zip. Change the extension back to what it was after editing and the targeted commands or groups should be disabled. Disabling the Ribbon command also disables any associated right-click commands. The kicker is that sheet add/delete commands aren't available in the Ribbon.

How do I disable and enable macros on the fly?

I would like to test an Excel VBA app I made.
However the VBA code messes around with the visibility of cells and that's a pest when editing the sheet.
Is there an option is enable and disable macro's on the fly without having to
Close the sheet
Change the macro settings
Reopen the sheet
Close the sheet
Change the macro settings.
etc.
As far as I know, you can't enable / disable macros from an opened workbook on the fly.
Yet, you shouldn't have to because macros are only triggered thanks to a user click.
The only case I would see is for the Event Procedures (Worksheet_Change or else).
You could then create procedures to activate / deactivate events and call them from buttons in your worksbook:
Sub enableEvents()
Application.EnableEvents = True
End Sub
Sub disableEvents()
Application.EnableEvents = False
End Sub
You can also try these tips from Chris Pearson website using global vars you would change depending on your needs:
Public AbortChangeEvent As Boolean
And check if afterwards:
Private Sub Worksheet_Change(ByVal Target As Range)
If AbortChangeEvent = True Then
Exit Sub
End If
'
' rest of code here
'
End Sub
To disable macros on the fly, use "Application.EnableEvents = False" via the Immediate window in the VBA editor (and "Application.EnableEvents = True" to turn them back on).
You can also hold down SHIFT when you open a document to disable macros.
As of Excel 2010* there's actually an option on the "Developer" tab which allows you to disable macros as easy as ABC. Design Mode lets you do just that!
*Maybe even earlier versions.
I often fire Macros when opening a workbook but sometimes I don't want the Macro to fire so I can work on the code. So what I put a Macro in a separate workbook that does the following:
Disables macros
Opens the workbook in question
Enables macros
Then closes the original workbook
Leaves the second workbook open
Here's the code:
Sub OpenClose()
'Opens Workbook below with Macors disabled
'After it is open Macros are enabled
'This Workbook then closes without saving changes, leaving only the workbook below open
'************************************************************
'User only needs to change the workbook name on the next line
WorkbookToOpenNoMacros = "Gaby.xlsm"
'************************************************************
Dim wb As Workbook
Set wb = Application.ThisWorkbook
Application.EnableEvents = False
Application.Workbooks.Open (ActiveWorkbook.Path & "\" & WorkbookToOpenNoMacros)
Application.EnableEvents = True
wb.Saved = True
wb.Close SaveChanges:=False
End Sub
I have Office 2013 and I found a button on the VBA window that did this for me very easily.
There's a play, pause and stop button on the toolbar. In Excel, they are actually called, Run Macro, Break and Reset.
Click the Break button (pause) and any running macros should stop running. I only tested it on one macro but seems reasonable to presume that this will work in general.
Also, I believe those buttons were there for many versions of Excel, so it's worth checking earlier versions.